The Organizer tab of the style dialog now shows interactive "chips" for each property that differs from the parent style. Each chip displays the property name and value, and includes an X button to reset that property back to parent inheritance. All properties are shown full text, no ellipsis. Properties are grouped by tab page (Font, Font effects, etc.) and displayed in a scrollable area. A View/Edit toggle lets the user switch between the traditional description text and the interactive chip view. Implementation summary: - New PropertyChip and PropertyCategoryRow widgets (sfx2) with corresponding .ui files for the chip layout. - SfxStyleSheetBase::GetItemPresentation() virtual method returns per-property presentation strings, overridden in SwDocStyleSheet and ScStyleSheet for module-specific attributes. - SfxItemSet access tracker mechanism to automatically map WhichIds to their owning tab pages via BuildWhichToTabMap(). - SfxTabDialogController::InvalidateItem() propagates chip resets to the output set and affected tab pages. - SwDocStyleSheet::ResetItems() uses SwDoc::ResetAttrAtFormat() to ensure proper undo support in Writer. - SfxStyleDialogController::Ok() clears invalidated items from the style's item set on dialog confirmation. - SvxAsianTabPage now calls SetExchangeSupport() and implements DeactivatePage() so its items are properly tracked. - Access tracker ignore guards in SvxCharBasePage::SetPrevFontWidthScale and SvxTransparenceTabPage::InitPreview to avoid false positives from preview-only item access. Includes a UITest for Writer (sw/qa/uitest/ui/fmtui/tdf89826.py) that creates a child style, modifies a property, removes it via chip, and verifies inheritance is restored including undo. A Calc UITest is not included because the style edit dialog in Calc is opened asynchronously (ScTabViewShell::ExecuteStyleEdit) and the UITest framework's execute_dialog_through_command cannot capture it. The Calc functionality has been verified manually. A Calc UITest can be added once the framework supports async style dialogs. Change-Id: Ia764405798c212fe5340bba254f2ff6ac62365f6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199318 Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org> Tested-by: Jenkins
388 lines
14 KiB
C++
388 lines
14 KiB
C++
/* -*- 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 .
|
|
*/
|
|
|
|
#ifndef INCLUDED_SVL_STYLE_HXX
|
|
#define INCLUDED_SVL_STYLE_HXX
|
|
|
|
#include <config_options.h>
|
|
#include <com/sun/star/style/XStyle.hpp>
|
|
|
|
#include <cppuhelper/implbase.hxx>
|
|
#include <svl/svldllapi.h>
|
|
#include <svl/hint.hxx>
|
|
#include <svl/lstner.hxx>
|
|
#include <svl/SfxBroadcaster.hxx>
|
|
#include <svl/stylesheetuser.hxx>
|
|
#include <o3tl/typed_flags_set.hxx>
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
|
|
#include <vector>
|
|
#include <utility>
|
|
|
|
// This is used as a flags enum in sw/, but only there,
|
|
// so I don't pull in o3tl::typed_flags here
|
|
enum class SfxStyleFamily {
|
|
None = 0x00,
|
|
Char = 0x01,
|
|
Para = 0x02,
|
|
Frame = 0x04,
|
|
Page = 0x08,
|
|
Pseudo = 0x10,
|
|
Table = 0x20,
|
|
Cell = 0x40,
|
|
All = 0x7fff
|
|
};
|
|
|
|
enum class SfxStyleSearchBits {
|
|
// sc/calc styles
|
|
ScStandard = 0x0001,
|
|
|
|
// sw/writer styles
|
|
SwText = 0x0001,
|
|
SwChapter = 0x0002,
|
|
SwList = 0x0004,
|
|
SwIndex = 0x0008,
|
|
SwExtra = 0x0010,
|
|
SwHtml = 0x0020,
|
|
SwCondColl = 0x0040,
|
|
|
|
Auto = 0x0000, ///< automatic: flags from application
|
|
Favourite = 0x0100, ///< styles selected to be always visible (search mask)
|
|
Hidden = 0x0200, ///< hidden styles (search mask)
|
|
ReadOnly = 0x2000, ///< readonly styles (search mask)
|
|
Used = 0x4000, ///< used styles (search mask)
|
|
UserDefined = 0x8000, ///< user defined styles (search mask)
|
|
AllVisible = 0xe07f, ///< all visible styles
|
|
All = 0xe27f, ///< all styles
|
|
};
|
|
namespace o3tl {
|
|
template<> struct typed_flags<SfxStyleSearchBits> : is_typed_flags<SfxStyleSearchBits, 0xe37f> {};
|
|
}
|
|
|
|
|
|
class SfxItemSet;
|
|
class SfxItemPool;
|
|
class SfxStyleSheetBasePool;
|
|
|
|
namespace svl { class IndexedStyleSheets; }
|
|
typedef struct _xmlTextWriter* xmlTextWriterPtr;
|
|
namespace rtl { template <class reference_type> class Reference; }
|
|
enum class MapUnit : sal_uInt8;
|
|
|
|
/*
|
|
Everyone changing instances of SfxStyleSheetBasePool or SfxStyleSheetBase
|
|
must broadcast this using <SfxStyleSheetBasePool::GetBroadcaster()> broadcasts.
|
|
The class <SfxStyleSheetHint> is used for this, it contains an Action-Id and a
|
|
pointer to the <SfxStyleSheetBase>. The actions are:
|
|
|
|
#define SfxHintId::StyleSheetCreated // style is created
|
|
#define SfxHintId::StyleSheetModified // style is modified
|
|
#define SfxHintId::StyleSheetChanged // style is replaced
|
|
#define SfxHintId::StyleSheetErased // style is deleted
|
|
|
|
The following methods already broadcast themself
|
|
|
|
SfxSimpleHint(SfxHintId::Dying) from:
|
|
SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
|
|
|
|
SfxStyleSheetHint( SfxHintId::StyleSheetCreated, *p ) from:
|
|
SfxStyleSheetBasePool::Make( const String& rName,
|
|
SfxStyleFamily eFam, SfxStyleSearchBits mask)
|
|
|
|
SfxStyleSheetHint( SfxHintId::StyleSheetChanged, *pNew ) from:
|
|
SfxStyleSheetBasePool::Add( SfxStyleSheetBase& rSheet )
|
|
|
|
SfxStyleSheetHint( SfxHintId::StyleSheetErased, *p ) from:
|
|
SfxStyleSheetBasePool::Erase( SfxStyleSheetBase* p )
|
|
SfxStyleSheetBasePool::Clear()
|
|
*/
|
|
|
|
// avoid LNK2005 duplicate WeakImplHelper definitions with MSVC
|
|
class SAL_DLLPUBLIC_TEMPLATE SfxStyleSheetBase_Base : public cppu::WeakImplHelper<>
|
|
{
|
|
};
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheetBase : public SfxStyleSheetBase_Base
|
|
{
|
|
private:
|
|
friend class SfxStyleSheetBasePool;
|
|
|
|
protected:
|
|
SfxStyleSheetBasePool* m_pPool; // related pool
|
|
SfxStyleFamily nFamily;
|
|
|
|
OUString aName, aParent, aFollow;
|
|
OUString aHelpFile; // name of the help file
|
|
SfxItemSet* pSet; // ItemSet
|
|
SfxStyleSearchBits nMask; // Flags
|
|
|
|
sal_uInt32 nHelpId; // help ID
|
|
|
|
bool bMySet; // sal_True: delete Set in dtor
|
|
bool bHidden;
|
|
|
|
SfxStyleSheetBase( const OUString&, SfxStyleSheetBasePool*, SfxStyleFamily eFam,
|
|
SfxStyleSearchBits mask, const OUString& rParentStyleSheetName );
|
|
SfxStyleSheetBase( const SfxStyleSheetBase& );
|
|
virtual ~SfxStyleSheetBase() override;
|
|
|
|
public:
|
|
|
|
// returns the internal name of this style
|
|
const OUString& GetName() const;
|
|
|
|
// sets the internal name of this style.
|
|
//
|
|
// If the name of a style is changed, then the styles container needs to be
|
|
// reindexed (see IndexedStyleSheets). If you set bReindexNow to false to
|
|
// defer that indexing, then you must call the Reindex manually on the
|
|
// SfxStyleSheetBasePool parent.
|
|
virtual bool SetName(const OUString& rNewName, bool bReindexNow = true);
|
|
|
|
virtual const OUString& GetParent() const;
|
|
virtual bool SetParent( const OUString& );
|
|
virtual const OUString& GetFollow() const;
|
|
virtual bool SetFollow( const OUString& );
|
|
virtual bool HasFollowSupport() const; // Default true
|
|
virtual bool HasParentSupport() const; // Default true
|
|
virtual bool HasClearParentSupport() const; // Default false
|
|
virtual bool IsUsed() const; // Default true
|
|
virtual OUString GetDescription( MapUnit eMetric );
|
|
|
|
/// Returns individual property presentations for building UI chips
|
|
/// Each pair contains: WhichId and presentation string
|
|
virtual std::vector<std::pair<sal_uInt16, OUString>> GetItemPresentation(
|
|
MapUnit eMetric, const SfxItemSet* pWorkingSet = nullptr);
|
|
|
|
virtual OUString GetUsedBy() { return OUString(); }
|
|
|
|
SfxStyleSheetBasePool* GetPool() { return m_pPool; }
|
|
SfxStyleFamily GetFamily() const { return nFamily; }
|
|
SfxStyleSearchBits GetMask() const { return nMask; }
|
|
void SetMask( SfxStyleSearchBits mask) { nMask = mask; }
|
|
bool IsUserDefined() const
|
|
{ return bool( nMask & SfxStyleSearchBits::UserDefined); }
|
|
|
|
virtual bool IsHidden() const { return bHidden; }
|
|
virtual void SetHidden( bool bValue );
|
|
|
|
virtual sal_uInt32 GetHelpId( OUString& rFile );
|
|
virtual void SetHelpId( const OUString& r, sal_uInt32 nId );
|
|
|
|
// Spotlight Id, @return -1 for style not in use
|
|
virtual sal_Int32 GetSpotlightId();
|
|
|
|
virtual SfxItemSet& GetItemSet();
|
|
/// Due to writer's usual lack of sanity this is a separate function for
|
|
/// preview only; it shall not create the style in case it does not exist.
|
|
/// If the style has parents, it is _not_ required that the returned item
|
|
/// set has parents (i.e. use it for display purposes only).
|
|
virtual std::optional<SfxItemSet> GetItemSetForPreview();
|
|
|
|
/// Fix for expensive dynamic_cast
|
|
virtual bool isScStyleSheet() const { return false; }
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
};
|
|
|
|
/* Class to iterate and search on a SfxStyleSheetBasePool */
|
|
class SVL_DLLPUBLIC SfxStyleSheetIterator
|
|
{
|
|
public:
|
|
/** Constructor.
|
|
* The iterator will only iterate over style sheets which have the family \p eFam
|
|
*/
|
|
SfxStyleSheetIterator(const SfxStyleSheetBasePool *pBase,
|
|
SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All );
|
|
SfxStyleSearchBits GetSearchMask() const;
|
|
SfxStyleFamily GetSearchFamily() const { return nSearchFamily; }
|
|
|
|
virtual sal_Int32 Count();
|
|
virtual SfxStyleSheetBase *operator[](sal_Int32 nIdx);
|
|
virtual SfxStyleSheetBase* First();
|
|
virtual SfxStyleSheetBase* Next();
|
|
virtual SfxStyleSheetBase* Find(const OUString& rStr);
|
|
virtual ~SfxStyleSheetIterator();
|
|
|
|
bool SearchUsed() const { return bSearchUsed; }
|
|
|
|
protected:
|
|
|
|
const SfxStyleSheetBasePool* pBasePool;
|
|
SfxStyleFamily nSearchFamily;
|
|
SfxStyleSearchBits nMask;
|
|
|
|
|
|
private:
|
|
SVL_DLLPRIVATE bool IsTrivialSearch() const;
|
|
|
|
SfxStyleSheetBase* pCurrentStyle;
|
|
sal_Int32 mnCurrentPosition;
|
|
bool bSearchUsed;
|
|
|
|
friend class SfxStyleSheetBasePool;
|
|
};
|
|
|
|
class SfxStyleSheetBasePool_Impl;
|
|
|
|
// avoid LNK2005 duplicate WeakImplHelper definitions with MSVC
|
|
class SAL_DLLPUBLIC_TEMPLATE SfxStyleSheetBasePool_Base : public cppu::WeakImplHelper<>
|
|
{
|
|
};
|
|
|
|
typedef struct _xmlTextWriter* xmlTextWriterPtr;
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheetBasePool : public SfxBroadcaster, public SfxStyleSheetBasePool_Base
|
|
{
|
|
friend class SfxStyleSheetIterator;
|
|
friend class SfxStyleSheetBase;
|
|
|
|
std::unique_ptr<SfxStyleSheetBasePool_Impl> pImpl;
|
|
|
|
SfxStyleSheetIterator& GetIterator_Impl(SfxStyleFamily eFamily, SfxStyleSearchBits eMask);
|
|
protected:
|
|
SfxStyleSheetIterator* GetCachedIterator();
|
|
|
|
SfxItemPool& rPool;
|
|
|
|
void ChangeParent(std::u16string_view rOld, const OUString& rNew, SfxStyleFamily eFamily, bool bVirtual = true);
|
|
virtual rtl::Reference<SfxStyleSheetBase> Create( const OUString&, SfxStyleFamily, SfxStyleSearchBits, const OUString& rParentStyleSheetName );
|
|
virtual rtl::Reference<SfxStyleSheetBase> Create( const SfxStyleSheetBase& );
|
|
|
|
virtual ~SfxStyleSheetBasePool() override;
|
|
|
|
void StoreStyleSheet(const rtl::Reference< SfxStyleSheetBase >&);
|
|
|
|
/** Obtain the indexed style sheets.
|
|
*/
|
|
const svl::IndexedStyleSheets&
|
|
GetIndexedStyleSheets() const;
|
|
SfxStyleSheetBase* GetStyleSheetByPositionInIndex(unsigned pos);
|
|
|
|
public:
|
|
SfxStyleSheetBasePool( SfxItemPool& );
|
|
SfxStyleSheetBasePool( const SfxStyleSheetBasePool& );
|
|
|
|
SfxItemPool& GetPool() { return rPool;}
|
|
const SfxItemPool& GetPool() const { return rPool;}
|
|
|
|
virtual std::unique_ptr<SfxStyleSheetIterator> CreateIterator(SfxStyleFamily, SfxStyleSearchBits nMask = SfxStyleSearchBits::All);
|
|
|
|
virtual SfxStyleSheetBase& Make(const OUString&,
|
|
SfxStyleFamily eFam,
|
|
SfxStyleSearchBits nMask = SfxStyleSearchBits::All,
|
|
const OUString& rParentStyleSheetName = u""_ustr);
|
|
|
|
virtual void Remove( SfxStyleSheetBase* );
|
|
void Insert( SfxStyleSheetBase* );
|
|
|
|
void Clear();
|
|
|
|
SfxStyleSheetBasePool& operator=( const SfxStyleSheetBasePool& );
|
|
SfxStyleSheetBasePool& operator+=( const SfxStyleSheetBasePool& );
|
|
|
|
SfxStyleSheetBase* First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask = SfxStyleSearchBits::All);
|
|
SfxStyleSheetBase* Next();
|
|
virtual SfxStyleSheetBase* Find( const OUString&, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All );
|
|
|
|
void Reindex();
|
|
void ReindexOnNameChange(const SfxStyleSheetBase& style, const OUString& rOldName, const OUString& rNewName);
|
|
/** Add a style sheet.
|
|
* Not an actual public function. Do not call it from non-subclasses.
|
|
*/
|
|
void Add( const SfxStyleSheetBase& );
|
|
|
|
void dumpAsXml(xmlTextWriterPtr pWriter) const;
|
|
};
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheet: public SfxStyleSheetBase,
|
|
public SfxListener, public SfxBroadcaster, public svl::StyleSheetUser
|
|
{
|
|
public:
|
|
|
|
SfxStyleSheet( const OUString&, const SfxStyleSheetBasePool&, SfxStyleFamily,
|
|
SfxStyleSearchBits, const OUString& rParentStyleSheetName = u""_ustr );
|
|
SfxStyleSheet( const SfxStyleSheet& );
|
|
|
|
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
|
|
|
|
virtual bool isUsedByModel() const override final;
|
|
|
|
virtual bool SetParent( const OUString& ) override;
|
|
|
|
virtual bool IsSfxStyleSheet() const override final;
|
|
|
|
protected:
|
|
virtual ~SfxStyleSheet() override;
|
|
};
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheetPool: public SfxStyleSheetBasePool
|
|
{
|
|
protected:
|
|
using SfxStyleSheetBasePool::Create;
|
|
virtual rtl::Reference<SfxStyleSheetBase> Create(const OUString&, SfxStyleFamily,
|
|
SfxStyleSearchBits mask, const OUString& rParentStyleSheetName) override;
|
|
|
|
public:
|
|
SfxStyleSheetPool( SfxItemPool const& );
|
|
};
|
|
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheetPoolHint final : public SfxHint
|
|
{
|
|
public:
|
|
SfxStyleSheetPoolHint() : SfxHint(SfxHintId::SfxStyleSheetPool) {}
|
|
};
|
|
|
|
|
|
class SVL_DLLPUBLIC SfxStyleSheetHint: public SfxHint
|
|
{
|
|
SfxStyleSheetBase* pStyleSh;
|
|
public:
|
|
SfxStyleSheetHint( SfxHintId, SfxStyleSheetBase& );
|
|
SfxStyleSheetBase* GetStyleSheet() const
|
|
{ return pStyleSh; }
|
|
};
|
|
|
|
class UNLESS_MERGELIBS(SVL_DLLPUBLIC) SfxStyleSheetModifiedHint final : public SfxStyleSheetHint
|
|
{
|
|
OUString aName;
|
|
|
|
public:
|
|
SfxStyleSheetModifiedHint( OUString aOld,
|
|
SfxStyleSheetBase& );
|
|
const OUString& GetOldName() const { return aName; }
|
|
};
|
|
|
|
class SVL_DLLPUBLIC SfxUnoStyleSheet : public cppu::ImplInheritanceHelper<SfxStyleSheet, css::style::XStyle>
|
|
{
|
|
public:
|
|
SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily,
|
|
SfxStyleSearchBits _nMask,
|
|
const OUString& rParentStyleSheetName = u""_ustr );
|
|
|
|
static SfxUnoStyleSheet* getUnoStyleSheet( const css::uno::Reference< css::style::XStyle >& xStyle );
|
|
};
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|