tdf#134564 tdf#134578 Improve hierarchy viewing in Inspector
Significance of this patch -
* Added TreeView Lines in the ui file for Inspector
for better hierarchy viewing
* Properties and there respective values are divided
into separate columns.
* Grey out disabled properties
* bold PS, CS and DF
Change-Id: I825a75dd2c5bc54715fe59f3c639024a5e3ab5cb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98990
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/include/svx/sidebar/InspectorTextPanel.hxx b/include/svx/sidebar/InspectorTextPanel.hxx
index 30285a8..10ddf93 100644
--- a/include/svx/sidebar/InspectorTextPanel.hxx
+++ b/include/svx/sidebar/InspectorTextPanel.hxx
@@ -26,7 +26,20 @@ namespace svx::sidebar
struct TreeNode
{
OUString sNodeName;
css::uno::Any aValue;
bool isGrey;
enum
{
Category,
ComplexProperty,
SimpleProperty
} NodeType;
std::vector<TreeNode> children;
TreeNode()
: isGrey(false)
, NodeType(SimpleProperty)
{
}
};
class SVX_DLLPUBLIC InspectorTextPanel : public PanelLayout
{
diff --git a/svx/source/sidebar/inspector/InspectorTextPanel.cxx b/svx/source/sidebar/inspector/InspectorTextPanel.cxx
index 6ab6b10..ddbee7f5 100644
--- a/svx/source/sidebar/inspector/InspectorTextPanel.cxx
+++ b/svx/source/sidebar/inspector/InspectorTextPanel.cxx
@@ -19,6 +19,9 @@
#include <svx/sidebar/InspectorTextPanel.hxx>
#include <svl/languageoptions.hxx>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
using namespace css;
@@ -45,6 +48,56 @@ InspectorTextPanel::InspectorTextPanel(vcl::Window* pParent,
, mpListBoxStyles(m_xBuilder->weld_tree_view("listbox_fonts"))
{
mpListBoxStyles->set_size_request(-1, mpListBoxStyles->get_height_rows(25));
float fWidth = mpListBoxStyles->get_approximate_digit_width();
std::vector<int> aWidths;
aWidths.push_back(fWidth * 34);
aWidths.push_back(fWidth * 15);
mpListBoxStyles->set_column_fixed_widths(aWidths);
}
static bool GetPropertyValues(const OUString& rPropName, const uno::Any& rAny, OUString& rString)
{
// Hide Asian and Complex properties
if (SvtLanguageOptions().IsCJKFontEnabled() && rPropName.indexOf("Asian") != -1)
return false;
if (SvtLanguageOptions().IsCTLFontEnabled() && rPropName.indexOf("Complex") != -1)
return false;
if (bool bValue; rAny >>= bValue)
{
rString = OUString::boolean(bValue);
}
else if (OUString aValue; (rAny >>= aValue) && !(aValue.isEmpty()))
{
rString = aValue;
}
else if (awt::FontSlant eValue; rAny >>= eValue)
{
rString = (eValue == awt::FontSlant_ITALIC) ? OUStringLiteral("italic")
: OUStringLiteral("normal");
}
else if (long nValueLong; rAny >>= nValueLong)
{
if (rPropName.indexOf("Color") != -1)
rString = "0x" + OUString::number(nValueLong, 16);
else
rString = OUString::number(nValueLong);
}
else if (double fValue; rAny >>= fValue)
{
if (rPropName.indexOf("Weight") != -1)
rString = (fValue > 100) ? OUStringLiteral("bold") : OUStringLiteral("normal");
else
rString = OUString::number((round(fValue * 100)) / 100.00);
}
else if (short nValueShort; rAny >>= nValueShort)
{
rString = OUString::number(nValueShort);
}
else
return false;
return true;
}
static void FillBox_Impl(weld::TreeView& rListBoxStyles, const TreeNode& rCurrent,
@@ -52,10 +105,25 @@ static void FillBox_Impl(weld::TreeView& rListBoxStyles, const TreeNode& rCurren
{
std::unique_ptr<weld::TreeIter> pResult = rListBoxStyles.make_iterator();
const OUString& rName = rCurrent.sNodeName;
rListBoxStyles.insert(pParent, -1, &rName, nullptr, nullptr, nullptr, false, pResult.get());
OUString sPairValue;
for (const TreeNode& rChildNode : rCurrent.children)
FillBox_Impl(rListBoxStyles, rChildNode, pResult.get());
if (rCurrent.NodeType != TreeNode::SimpleProperty
|| GetPropertyValues(rName, rCurrent.aValue, sPairValue))
{
rListBoxStyles.insert(pParent, -1, &rName, nullptr, nullptr, nullptr, false, pResult.get());
rListBoxStyles.set_sensitive(*pResult, !rCurrent.isGrey, 0);
rListBoxStyles.set_text_emphasis(*pResult, rCurrent.NodeType == TreeNode::Category, 0);
if (rCurrent.NodeType == TreeNode::SimpleProperty)
{
rListBoxStyles.set_text(*pResult, sPairValue, 1);
rListBoxStyles.set_sensitive(*pResult, !rCurrent.isGrey, 1);
rListBoxStyles.set_text_emphasis(*pResult, false, 1);
}
for (const TreeNode& rChildNode : rCurrent.children)
FillBox_Impl(rListBoxStyles, rChildNode, pResult.get());
}
}
void InspectorTextPanel::updateEntries(const std::vector<TreeNode>& rStore)
diff --git a/svx/uiconfig/ui/inspectortextpanel.ui b/svx/uiconfig/ui/inspectortextpanel.ui
index af7c5cb..71199a8 100644
--- a/svx/uiconfig/ui/inspectortextpanel.ui
+++ b/svx/uiconfig/ui/inspectortextpanel.ui
@@ -4,10 +4,20 @@
<requires lib="gtk+" version="3.18"/>
<object class="GtkTreeStore" id="liststore">
<columns>
<!-- column-name text -->
<!-- column-name text1 -->
<column type="gchararray"/>
<!-- column-name text2 -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name weight1 -->
<column type="gint"/>
<!-- column-name weight2 -->
<column type="gint"/>
<!-- column-name sensitive1 -->
<column type="gboolean"/>
<!-- column-name sensitive2 -->
<column type="gboolean"/>
</columns>
</object>
<object class="GtkGrid" id="InspectorTextPanel">
@@ -40,12 +50,14 @@
<object class="GtkTreeView" id="listbox_fonts">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="search_column">0</property>
<property name="enable_tree_lines">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
@@ -54,7 +66,21 @@
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="sensitive">5</attribute>
<attribute name="text">0</attribute>
<attribute name="weight">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="sensitive">6</attribute>
<attribute name="text">1</attribute>
<attribute name="weight">4</attribute>
</attributes>
</child>
</object>
diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
index 3082492..a6faa29 100644
--- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
+++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx
@@ -25,14 +25,12 @@
#include <wrtsh.hxx>
#include <com/sun/star/text/XTextRange.hpp>
#include <com/sun/star/text/XTextCursor.hpp>
#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <unotextrange.hxx>
#include <svl/languageoptions.hxx>
namespace sw::sidebar
{
@@ -59,54 +57,6 @@ WriterInspectorTextPanel::WriterInspectorTextPanel(vcl::Window* pParent,
pShell->SetChgLnk(LINK(this, WriterInspectorTextPanel, AttrChangedNotify));
}
static bool GetPropertyValues(const beans::Property rProperty, const uno::Any& rAny,
OUString& rString)
{
// Hide Asian and Complex properties
if (SvtLanguageOptions().IsCJKFontEnabled() && rProperty.Name.indexOf("Asian") != -1)
return false;
if (SvtLanguageOptions().IsCTLFontEnabled() && rProperty.Name.indexOf("Complex") != -1)
return false;
rString = rProperty.Name + " ";
if (bool bValue; rAny >>= bValue)
{
rString += OUString::boolean(bValue);
}
else if (OUString aValue; (rAny >>= aValue) && !(aValue.isEmpty()))
{
rString += aValue;
}
else if (awt::FontSlant eValue; rAny >>= eValue)
{
rString += (eValue == awt::FontSlant_ITALIC) ? OUStringLiteral("italic")
: OUStringLiteral("normal");
}
else if (long nValueLong; rAny >>= nValueLong)
{
if (rString.indexOf("Color") != -1)
rString += "0x" + OUString::number(nValueLong, 16);
else
rString += OUString::number(nValueLong);
}
else if (double fValue; rAny >>= fValue)
{
if (rString.indexOf("Weight") != -1)
rString += (fValue > 100) ? OUStringLiteral("bold") : OUStringLiteral("normal");
else
rString += OUString::number((round(fValue * 100)) / 100.00);
}
else if (short nValueShort; rAny >>= nValueShort)
{
rString += OUString::number(nValueShort);
}
else
return false;
return true;
}
static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>& aStore)
{
SwDoc* pDoc = pDocSh->GetDoc();
@@ -118,6 +68,9 @@ static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>&
aDFNode.sNodeName = "Direct Formatting";
aCharNode.sNodeName = "Character Styles";
aParaNode.sNodeName = "Paragraph Styles";
aDFNode.NodeType = svx::sidebar::TreeNode::Category;
aCharNode.NodeType = svx::sidebar::TreeNode::Category;
aParaNode.NodeType = svx::sidebar::TreeNode::Category;
uno::Reference<text::XTextRange> xRange(
SwXTextRange::CreateXTextRange(*pDoc, *pCursor->GetPoint(), nullptr));
@@ -133,15 +86,12 @@ static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>&
{
if (xPropertiesState->getPropertyState(rProperty.Name) == beans::PropertyState_DIRECT_VALUE)
{
OUString aPropertyValuePair;
const uno::Any aAny = xPropertiesSet->getPropertyValue(rProperty.Name);
if (GetPropertyValues(rProperty, aAny, aPropertyValuePair))
{
aIsDefined[rProperty.Name] = true;
svx::sidebar::TreeNode aTemp;
aTemp.sNodeName = aPropertyValuePair;
aDFNode.children.push_back(aTemp);
}
aIsDefined[rProperty.Name] = true;
svx::sidebar::TreeNode aTemp;
aTemp.sNodeName = rProperty.Name;
aTemp.aValue = aAny;
aDFNode.children.push_back(aTemp);
}
}
@@ -164,24 +114,21 @@ static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>&
aProperties = xPropertiesSet->getPropertySetInfo()->getProperties();
svx::sidebar::TreeNode aCurrentChild;
aCurrentChild.sNodeName = sDisplayName;
aCurrentChild.NodeType = svx::sidebar::TreeNode::ComplexProperty;
for (const beans::Property& rProperty : std::as_const(aProperties))
{
OUString sPropName = rProperty.Name;
if (xPropertiesState->getPropertyState(sPropName) == beans::PropertyState_DIRECT_VALUE)
{
OUString aPropertyValuePair;
const uno::Any aAny = xPropertiesSet->getPropertyValue(sPropName);
if (GetPropertyValues(rProperty, aAny, aPropertyValuePair))
{
if (aIsDefined[sPropName]) // Already defined in "Direct Formatting" ?
aPropertyValuePair = aPropertyValuePair + " !!<GREY>!!";
else
aIsDefined[sPropName] = true;
svx::sidebar::TreeNode aTemp;
aTemp.sNodeName = aPropertyValuePair;
aCurrentChild.children.push_back(aTemp);
}
svx::sidebar::TreeNode aTemp;
if (aIsDefined[sPropName]) // Already defined in "Direct Formatting" ?
aTemp.isGrey = true;
aIsDefined[sPropName] = true;
aTemp.sNodeName = sPropName;
aTemp.aValue = aAny;
aCurrentChild.children.push_back(aTemp);
}
}
@@ -201,6 +148,7 @@ static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>&
OUString aParentParaStyle = xPropertiesStyle->getParentStyle();
svx::sidebar::TreeNode aCurrentChild;
aCurrentChild.sNodeName = sDisplayName;
aCurrentChild.NodeType = svx::sidebar::TreeNode::ComplexProperty;
for (const beans::Property& rProperty : std::as_const(aProperties))
{
@@ -209,19 +157,15 @@ static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>&
|| xPropertiesState->getPropertyState(sPropName)
== beans::PropertyState_DIRECT_VALUE)
{
OUString aPropertyValuePair;
const uno::Any aAny = xPropertiesSet->getPropertyValue(sPropName);
if (GetPropertyValues(rProperty, aAny, aPropertyValuePair))
{
// Already defined in "Default Formatting" or "Character Styles" or any child Paragraph Style ?
if (aIsDefined[sPropName])
aPropertyValuePair = aPropertyValuePair + " !!<GREY>!! ";
else
aIsDefined[sPropName] = true;
svx::sidebar::TreeNode aTemp;
aTemp.sNodeName = aPropertyValuePair;
aCurrentChild.children.push_back(aTemp);
}
svx::sidebar::TreeNode aTemp;
// Already defined in "Default Formatting" or "Character Styles" or any child Paragraph Style ?
if (aIsDefined[sPropName])
aTemp.isGrey = true;
aIsDefined[sPropName] = true;
aTemp.sNodeName = sPropName;
aTemp.aValue = aAny;
aCurrentChild.children.push_back(aTemp);
}
}