tdf#157431 Show description for expert config items
Change-Id: I7d0257c2e06ed384f90ca3b51a6d2549044f2cf3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157148 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
This commit is contained in:
parent
560cb9c53e
commit
db3078bd8c
12 changed files with 171 additions and 27 deletions
|
@ -216,6 +216,8 @@ css::uno::Sequence< css::uno::Type > Access::getTypes()
|
|||
} else {
|
||||
types.push_back(
|
||||
cppu::UnoType< css::container::XHierarchicalNameAccess >::get());
|
||||
types.push_back(
|
||||
cppu::UnoType< css::configuration::XDocumentation >::get());
|
||||
}
|
||||
addTypes(&types);
|
||||
return comphelper::containerToSequence(types);
|
||||
|
@ -440,6 +442,19 @@ css::uno::Any Access::getByHierarchicalName(OUString const & aName)
|
|||
return child->asValue();
|
||||
}
|
||||
|
||||
OUString Access::getDescriptionByHierarchicalName(OUString const & aName)
|
||||
{
|
||||
assert(thisIs(IS_ANY));
|
||||
osl::MutexGuard g(*lock_);
|
||||
checkLocalizedPropertyAccess();
|
||||
rtl::Reference< ChildAccess > child(getSubChild(aName));
|
||||
if (!child.is()) {
|
||||
throw css::container::NoSuchElementException(
|
||||
aName, getXWeak());
|
||||
}
|
||||
return child->getNode()->getDescription();
|
||||
}
|
||||
|
||||
sal_Bool Access::hasByHierarchicalName(OUString const & aName)
|
||||
{
|
||||
assert(thisIs(IS_ANY));
|
||||
|
@ -1300,6 +1315,7 @@ css::uno::Any Access::queryInterface(css::uno::Type const & aType)
|
|||
static_cast< css::lang::XServiceInfo * >(this),
|
||||
static_cast< css::lang::XComponent * >(this),
|
||||
static_cast< css::container::XHierarchicalNameAccess * >(this),
|
||||
static_cast< css::configuration::XDocumentation * >(this),
|
||||
static_cast< css::container::XContainer * >(this),
|
||||
static_cast< css::beans::XExactName * >(this),
|
||||
static_cast< css::container::XHierarchicalName * >(this),
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <com/sun/star/beans/XPropertySetInfo.hpp>
|
||||
#include <com/sun/star/container/XContainer.hpp>
|
||||
#include <com/sun/star/container/XHierarchicalName.hpp>
|
||||
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
|
||||
#include <com/sun/star/configuration/XDocumentation.hpp>
|
||||
#include <com/sun/star/container/XHierarchicalNameReplace.hpp>
|
||||
#include <com/sun/star/container/XNameContainer.hpp>
|
||||
#include <com/sun/star/container/XNamed.hpp>
|
||||
|
@ -82,6 +84,7 @@ class Access:
|
|||
public cppu::OWeakObject, public css::lang::XTypeProvider,
|
||||
public css::lang::XServiceInfo,
|
||||
public css::lang::XComponent,
|
||||
public css::configuration::XDocumentation,
|
||||
public css::container::XHierarchicalNameReplace,
|
||||
public css::container::XContainer,
|
||||
public css::beans::XExactName,
|
||||
|
@ -159,6 +162,9 @@ public:
|
|||
virtual css::uno::Any SAL_CALL getByHierarchicalName(
|
||||
OUString const & aName) override;
|
||||
|
||||
virtual OUString SAL_CALL getDescriptionByHierarchicalName(
|
||||
OUString const & aName) override;
|
||||
|
||||
virtual sal_Bool SAL_CALL hasByHierarchicalName(OUString const & aName) override;
|
||||
|
||||
virtual void SAL_CALL replaceByHierarchicalName(
|
||||
|
|
|
@ -59,7 +59,6 @@ void Node::setFinalized(int layer) {
|
|||
finalized_ = layer;
|
||||
}
|
||||
|
||||
|
||||
rtl::Reference< Node > Node::getMember(OUString const & name) {
|
||||
NodeMap const & members = getMembers();
|
||||
NodeMap::const_iterator i(members.find(name));
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
|
||||
#include <rtl/ref.hxx>
|
||||
#include <rtl/ustring.hxx>
|
||||
#include <rtl/ustrbuf.hxx>
|
||||
#include <salhelper/simplereferenceobject.hxx>
|
||||
#include <xmlreader/span.hxx>
|
||||
|
||||
namespace configmgr {
|
||||
|
||||
|
@ -51,6 +53,9 @@ public:
|
|||
void setFinalized(int layer);
|
||||
int getFinalized() const { return finalized_;}
|
||||
|
||||
void setDescription(OUString const& description) { description_ = description; };
|
||||
OUString getDescription() { return description_; }
|
||||
|
||||
rtl::Reference< Node > getMember(OUString const & name);
|
||||
|
||||
protected:
|
||||
|
@ -61,6 +66,7 @@ protected:
|
|||
private:
|
||||
int layer_;
|
||||
int finalized_;
|
||||
OUString description_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -109,12 +109,14 @@ void merge(
|
|||
}
|
||||
|
||||
XcsParser::XcsParser(int layer, Data & data):
|
||||
valueParser_(layer), data_(data), state_(STATE_START), ignoring_()
|
||||
valueParser_(layer), data_(data), state_(STATE_START), ignoring_(), bIsParsingInfo_(false)
|
||||
{}
|
||||
|
||||
XcsParser::~XcsParser() {}
|
||||
|
||||
xmlreader::XmlReader::Text XcsParser::getTextMode() {
|
||||
if (bIsParsingInfo_)
|
||||
return xmlreader::XmlReader::Text::Raw;
|
||||
return valueParser_.getTextMode();
|
||||
}
|
||||
|
||||
|
@ -122,6 +124,20 @@ bool XcsParser::startElement(
|
|||
xmlreader::XmlReader & reader, int nsId, xmlreader::Span const & name,
|
||||
std::set< OUString > const * /*existingDependencies*/)
|
||||
{
|
||||
//TODO: ignoring component-schema import, component-schema uses, and
|
||||
// prop constraints; accepting all four at illegal places (and with
|
||||
// illegal content):
|
||||
if (ignoring_ > 0
|
||||
|| (nsId == xmlreader::XmlReader::NAMESPACE_NONE
|
||||
&& (name == "import" || name == "uses" || name == "constraints" || name == "desc")))
|
||||
{
|
||||
assert(ignoring_ < LONG_MAX);
|
||||
++ignoring_;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bIsParsingInfo_)
|
||||
return true;
|
||||
if (valueParser_.startElement(reader, nsId, name)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -135,18 +151,6 @@ bool XcsParser::startElement(
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
//TODO: ignoring component-schema import, component-schema uses, and
|
||||
// prop constraints; accepting all four at illegal places (and with
|
||||
// illegal content):
|
||||
if (ignoring_ > 0 ||
|
||||
(nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
(name == "info" || name == "import" ||
|
||||
name == "uses" || name == "constraints")))
|
||||
{
|
||||
assert(ignoring_ < LONG_MAX);
|
||||
++ignoring_;
|
||||
return true;
|
||||
}
|
||||
switch (state_) {
|
||||
case STATE_COMPONENT_SCHEMA:
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
|
@ -155,6 +159,12 @@ bool XcsParser::startElement(
|
|||
state_ = STATE_TEMPLATES;
|
||||
return true;
|
||||
}
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
[[fallthrough]];
|
||||
case STATE_TEMPLATES_DONE:
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
|
@ -170,6 +180,12 @@ bool XcsParser::startElement(
|
|||
}
|
||||
break;
|
||||
case STATE_TEMPLATES:
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
if (elements_.empty()) {
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "group")
|
||||
|
@ -183,6 +199,12 @@ bool XcsParser::startElement(
|
|||
handleSet(reader, true);
|
||||
return true;
|
||||
}
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
@ -197,6 +219,12 @@ bool XcsParser::startElement(
|
|||
handlePropValue(reader, elements_.top().node);
|
||||
return true;
|
||||
}
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case Node::KIND_GROUP:
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
|
@ -223,6 +251,12 @@ bool XcsParser::startElement(
|
|||
handleSet(reader, false);
|
||||
return true;
|
||||
}
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case Node::KIND_SET:
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
|
@ -233,6 +267,12 @@ bool XcsParser::startElement(
|
|||
static_cast< SetNode * >(elements_.top().node.get()));
|
||||
return true;
|
||||
}
|
||||
if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
|
||||
name == "info")
|
||||
{
|
||||
bIsParsingInfo_ = true;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default: // Node::KIND_LOCALIZED_VALUE
|
||||
assert(false); // this cannot happen
|
||||
|
@ -251,15 +291,28 @@ bool XcsParser::startElement(
|
|||
}
|
||||
|
||||
void XcsParser::endElement(xmlreader::XmlReader const & reader) {
|
||||
if (ignoring_ > 0) {
|
||||
--ignoring_;
|
||||
return;
|
||||
}
|
||||
if (bIsParsingInfo_)
|
||||
{
|
||||
bIsParsingInfo_ = false;
|
||||
return;
|
||||
}
|
||||
if (valueParser_.endElement()) {
|
||||
return;
|
||||
}
|
||||
if (ignoring_ > 0) {
|
||||
--ignoring_;
|
||||
} else if (!elements_.empty()) {
|
||||
if (!elements_.empty()) {
|
||||
Element top(std::move(elements_.top()));
|
||||
elements_.pop();
|
||||
if (top.node.is()) {
|
||||
// Remove whitespace from description_ resulting from line breaks/indentation in xml files
|
||||
OUString desc(description_.makeStringAndClear());
|
||||
desc = desc.trim();
|
||||
while (desc.indexOf(" ") != -1)
|
||||
desc = desc.replaceAll(" ", " ");
|
||||
top.node->setDescription(desc);
|
||||
if (elements_.empty()) {
|
||||
switch (state_) {
|
||||
case STATE_TEMPLATES:
|
||||
|
@ -316,6 +369,11 @@ void XcsParser::endElement(xmlreader::XmlReader const & reader) {
|
|||
}
|
||||
|
||||
void XcsParser::characters(xmlreader::Span const & text) {
|
||||
if (bIsParsingInfo_)
|
||||
{
|
||||
description_.append(text.convertFromUtf8());
|
||||
return;
|
||||
}
|
||||
valueParser_.characters(text);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ private:
|
|||
State state_;
|
||||
long ignoring_;
|
||||
ElementStack elements_;
|
||||
bool bIsParsingInfo_;
|
||||
OUStringBuffer description_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <com/sun/star/beans/UnknownPropertyException.hpp>
|
||||
#include <com/sun/star/beans/XPropertySetInfo.hpp>
|
||||
#include <com/sun/star/configuration/ReadWriteAccess.hpp>
|
||||
#include <com/sun/star/configuration/XDocumentation.hpp>
|
||||
#include <com/sun/star/container/XNameAccess.hpp>
|
||||
#include <com/sun/star/container/XNameReplace.hpp>
|
||||
#include <com/sun/star/container/XHierarchicalName.hpp>
|
||||
|
@ -70,13 +71,15 @@ struct UserData
|
|||
bool bIsPropertyPath;
|
||||
bool bIsReadOnly;
|
||||
OUString sPropertyPath;
|
||||
OUString sTooltip;
|
||||
int aLineage;
|
||||
Reference<XNameAccess> aXNameAccess;
|
||||
|
||||
explicit UserData( OUString aPropertyPath, bool isReadOnly )
|
||||
explicit UserData( OUString aPropertyPath, OUString aTooltip, bool isReadOnly )
|
||||
: bIsPropertyPath( true )
|
||||
, bIsReadOnly( isReadOnly )
|
||||
, sPropertyPath(std::move(aPropertyPath))
|
||||
, sTooltip(std::move(aTooltip))
|
||||
, aLineage(0)
|
||||
{}
|
||||
|
||||
|
@ -186,12 +189,19 @@ CuiAboutConfigTabPage::CuiAboutConfigTabPage(weld::Window* pParent)
|
|||
IMPL_LINK(CuiAboutConfigTabPage, QueryTooltip, const weld::TreeIter&, rIter, OUString)
|
||||
{
|
||||
UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(rIter));
|
||||
OUStringBuffer ret;
|
||||
if (pUserData && pUserData->bIsReadOnly)
|
||||
{
|
||||
return CuiResId(RID_CUISTR_OPT_READONLY);
|
||||
ret.append(CuiResId(RID_CUISTR_OPT_READONLY));
|
||||
}
|
||||
if (pUserData && !pUserData->sTooltip.isEmpty())
|
||||
{
|
||||
if (pUserData->bIsReadOnly)
|
||||
ret.append("\n\n");
|
||||
ret.append(pUserData->sTooltip);
|
||||
}
|
||||
|
||||
return OUString();
|
||||
return ret.makeStringAndClear();
|
||||
}
|
||||
|
||||
IMPL_LINK(CuiAboutConfigTabPage, HeaderBarClick, int, nColumn, void)
|
||||
|
@ -230,10 +240,11 @@ CuiAboutConfigTabPage::~CuiAboutConfigTabPage()
|
|||
}
|
||||
|
||||
void CuiAboutConfigTabPage::InsertEntry(const OUString& rPropertyPath, const OUString& rProp, const OUString& rStatus,
|
||||
const OUString& rType, const OUString& rValue, const weld::TreeIter* pParentEntry,
|
||||
const OUString& rType, const OUString& rValue, const OUString& rTooltip,
|
||||
const weld::TreeIter* pParentEntry,
|
||||
bool bInsertToPrefBox, bool bIsReadOnly)
|
||||
{
|
||||
m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath, bIsReadOnly));
|
||||
m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath, rTooltip, bIsReadOnly));
|
||||
if (bInsertToPrefBox)
|
||||
{
|
||||
OUString sId(weld::toId(m_vectorUserData.back().get()));
|
||||
|
@ -357,6 +368,16 @@ void CuiAboutConfigTabPage::FillItems(const Reference< XNameAccess >& xNameAcces
|
|||
SAL_WARN("cui.options", "unknown property: " << sPath + "/" + sPropertyName);
|
||||
}
|
||||
|
||||
OUString sTooltip;
|
||||
try
|
||||
{
|
||||
Reference<configuration::XDocumentation> xObjProp(xNameAccess, UNO_QUERY_THROW);
|
||||
sTooltip = xObjProp->getDescriptionByHierarchicalName(sPath + "/" + sPropertyName);
|
||||
}
|
||||
catch (css::container::NoSuchElementException)
|
||||
{
|
||||
}
|
||||
|
||||
OUString sType = aNode.getValueTypeName();
|
||||
OUStringBuffer sValue;
|
||||
|
||||
|
@ -518,7 +539,7 @@ void CuiAboutConfigTabPage::FillItems(const Reference< XNameAccess >& xNameAcces
|
|||
for(int j = 1; j < lineage; ++j)
|
||||
index = sPath.indexOf("/", index + 1);
|
||||
|
||||
InsertEntry(sPath, sPath.copy(index + 1), item, sType, sValue.makeStringAndClear(),
|
||||
InsertEntry(sPath, sPath.copy(index + 1), item, sType, sValue.makeStringAndClear(), sTooltip,
|
||||
pParentEntry, !bLoadAll, bReadOnly);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,8 @@ private:
|
|||
public:
|
||||
explicit CuiAboutConfigTabPage(weld::Window* pParent);
|
||||
virtual ~CuiAboutConfigTabPage() override;
|
||||
void InsertEntry(const OUString &rPropertyPath, const OUString& rProp, const OUString& rStatus, const OUString& rType, const OUString& rValue,
|
||||
void InsertEntry(const OUString &rPropertyPath, const OUString& rProp, const OUString& rStatus,
|
||||
const OUString& rType, const OUString& rValue, const OUString& rTooltip,
|
||||
const weld::TreeIter* pParentEntry, bool bInsertToPrefBox, bool bIsReadOnly);
|
||||
void Reset();
|
||||
void FillItems(const css::uno::Reference<css::container::XNameAccess>& xNameAccess,
|
||||
|
|
|
@ -2083,6 +2083,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/configuration,\
|
|||
InstallationIncompleteException \
|
||||
InvalidBootstrapFileException \
|
||||
MissingBootstrapFileException \
|
||||
XDocumentation \
|
||||
XReadWriteAccess \
|
||||
XTemplateContainer \
|
||||
XTemplateInstance \
|
||||
|
|
34
offapi/com/sun/star/configuration/XDocumentation.idl
Normal file
34
offapi/com/sun/star/configuration/XDocumentation.idl
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
module com { module sun { module star { module configuration {
|
||||
|
||||
/* Is used to deliver documentation for the configuration.
|
||||
|
||||
<p>This interface is still unpublished and unstable.</p>
|
||||
|
||||
@since LibreOffice 24.2
|
||||
*/
|
||||
interface XDocumentation {
|
||||
/** @returns
|
||||
the description for the requested object
|
||||
|
||||
@param aName
|
||||
the hierarchical name of the object.
|
||||
|
||||
@throws NoSuchElementException
|
||||
if an element under aName does not exist.
|
||||
*/
|
||||
string getDescriptionByHierarchicalName( [in] string aName )
|
||||
raises( com::sun::star::container::NoSuchElementException );
|
||||
};
|
||||
|
||||
}; }; }; };
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -54,7 +54,7 @@
|
|||
<xsl:template match = "label[../deprecated]"/>
|
||||
|
||||
<!-- copy all other documentation with content -->
|
||||
<xsl:template match="desc|label">
|
||||
<xsl:template match="info|desc|label">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*"/>
|
||||
<xsl:value-of select="."/>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
</xsl:template>
|
||||
<xsl:template
|
||||
match="oor:component-schema|oor:component-data|templates|component|group|
|
||||
set|node-ref|prop|item|value|it|unicode|node">
|
||||
set|node-ref|prop|item|value|it|unicode|node|info">
|
||||
<xsl:copy copy-namespaces="no">
|
||||
<!-- prune oor:component-data xmlns:install="..." namespaces (would only
|
||||
work in XSLT 2.0, however) -->
|
||||
|
@ -71,7 +71,7 @@
|
|||
<!-- ignore text elements (which must be whitespace only) -->
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
<xsl:template match="info|import|uses|constraints"/>
|
||||
<xsl:template match="import|uses|constraints"/>
|
||||
<!-- TODO: no longer strip elements when they are eventually read by
|
||||
configmgr implementation -->
|
||||
<xsl:template match="@*">
|
||||
|
|
Loading…
Reference in a new issue