LibreOffice Module sw (master)  1
WriterInspectorTextPanel.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
21 
22 #include <doc.hxx>
23 #include <ndtxt.hxx>
24 #include <docsh.hxx>
25 #include <wrtsh.hxx>
26 #include <unoprnms.hxx>
27 #include <editeng/unoprnms.hxx>
28 #include <com/sun/star/text/XTextRange.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/beans/XPropertyState.hpp>
31 #include <com/sun/star/frame/XFrame.hpp>
32 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
33 #include <com/sun/star/table/BorderLine2.hpp>
34 #include <com/sun/star/lang/IllegalArgumentException.hpp>
35 #include <com/sun/star/rdf/XMetadatable.hpp>
36 #include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
37 
38 #include <unotextrange.hxx>
39 #include <comphelper/string.hxx>
42 #include <vcl/settings.hxx>
43 #include <inspectorproperties.hrc>
44 #include <strings.hrc>
45 #include <rdfhelper.hxx>
46 
47 namespace sw::sidebar
48 {
49 static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>& aStore);
50 
51 std::unique_ptr<PanelLayout> WriterInspectorTextPanel::Create(weld::Widget* pParent)
52 {
53  if (pParent == nullptr)
54  throw lang::IllegalArgumentException(
55  "no parent Window given to WriterInspectorTextPanel::Create", nullptr, 0);
56  return std::make_unique<WriterInspectorTextPanel>(pParent);
57 }
58 
60  : InspectorTextPanel(pParent)
61 {
62  SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
63  m_pShell = pDocSh->GetWrtShell();
64  if (m_pShell)
65  {
67  m_pShell->SetChgLnk(LINK(this, WriterInspectorTextPanel, AttrChangedNotify));
68  }
69 
70  // Update panel on start
71  std::vector<svx::sidebar::TreeNode> aStore;
72  if (pDocSh->GetDoc()->GetEditShell()->GetCursor()->GetNode().GetTextNode())
73  UpdateTree(pDocSh, aStore);
74  updateEntries(aStore);
75 }
76 
78 
79 static OUString PropertyNametoRID(const OUString& rName)
80 {
81  static const std::map<OUString, const char*> aNameToRID = {
82  { "BorderDistance", RID_BORDER_DISTANCE },
83  { "BottomBorder", RID_BOTTOM_BORDER },
84  { "BottomBorderDistance", RID_BOTTOM_BORDER_DISTANCE },
85  { "BreakType", RID_BREAK_TYPE },
86  { "Category", RID_CATEGORY },
87  { "Cell", RID_CELL },
88  { "CharAutoEscapement", RID_CHAR_AUTO_ESCAPEMENT },
89  { "CharAutoKerning", RID_CHAR_AUTO_KERNING },
90  { "CharAutoStyleName", RID_CHAR_AUTO_STYLE_NAME },
91  { "CharBackColor", RID_CHAR_BACK_COLOR },
92  { "CharBackTransparent", RID_CHAR_BACK_TRANSPARENT },
93  { "CharBorderDistance", RID_CHAR_BORDER_DISTANCE },
94  { "CharBottomBorder", RID_CHAR_BOTTOM_BORDER },
95  { "CharBottomBorderDistance", RID_CHAR_BOTTOM_BORDER_DISTANCE },
96  { "CharCaseMap", RID_CHAR_CASE_MAP },
97  { "CharColor", RID_CHAR_COLOR },
98  { "CharCombineIsOn", RID_CHAR_COMBINE_IS_ON },
99  { "CharCombinePrefix", RID_CHAR_COMBINE_PREFIX },
100  { "CharCombineSuffix", RID_CHAR_COMBINE_SUFFIX },
101  { "CharContoured", RID_CHAR_CONTOURED },
102  { "CharCrossedOut", RID_CHAR_CROSSED_OUT },
103  { "CharDiffHeight", RID_CHAR_DIFF_HEIGHT },
104  { "CharDiffHeightAsian", RID_CHAR_DIFF_HEIGHT_ASIAN },
105  { "CharDiffHeightComplex", RID_CHAR_DIFF_HEIGHT_COMPLEX },
106  { "CharEmphasis", RID_CHAR_EMPHASIS },
107  { "CharEscapement", RID_CHAR_ESCAPEMENT },
108  { "CharEscapementHeight", RID_CHAR_ESCAPEMENT_HEIGHT },
109  { "CharFlash", RID_CHAR_FLASH },
110  { "CharFontCharSet", RID_CHAR_FONT_CHAR_SET },
111  { "CharFontCharSetAsian", RID_CHAR_FONT_CHAR_SET_ASIAN },
112  { "CharFontCharSetComplex", RID_CHAR_FONT_CHAR_SET_COMPLEX },
113  { "CharFontFamily", RID_CHAR_FONT_FAMILY },
114  { "CharFontFamilyAsian", RID_CHAR_FONT_FAMILY_ASIAN },
115  { "CharFontFamilyComplex", RID_CHAR_FONT_FAMILY_COMPLEX },
116  { "CharFontName", RID_CHAR_FONT_NAME },
117  { "CharFontNameAsian", RID_CHAR_FONT_NAME_ASIAN },
118  { "CharFontNameComplex", RID_CHAR_FONT_NAME_COMPLEX },
119  { "CharFontPitch", RID_CHAR_FONT_PITCH },
120  { "CharFontPitchAsian", RID_CHAR_FONT_PITCH_ASIAN },
121  { "CharFontPitchComplex", RID_CHAR_FONT_PITCH_COMPLEX },
122  { "CharFontStyleName", RID_CHAR_FONT_STYLE_NAME },
123  { "CharFontStyleNameAsian", RID_CHAR_FONT_STYLE_NAME_ASIAN },
124  { "CharFontStyleNameComplex", RID_CHAR_FONT_STYLE_NAME_COMPLEX },
125  { "CharHeight", RID_CHAR_HEIGHT },
126  { "CharHeightAsian", RID_CHAR_HEIGHT_ASIAN },
127  { "CharHeightComplex", RID_CHAR_HEIGHT_COMPLEX },
128  { "CharHidden", RID_CHAR_HIDDEN },
129  { "CharHighlight", RID_CHAR_HIGHLIGHT },
130  { "CharInteropGrabBag", RID_CHAR_INTEROP_GRAB_BAG },
131  { "CharKerning", RID_CHAR_KERNING },
132  { "CharLeftBorder", RID_CHAR_LEFT_BORDER },
133  { "CharLeftBorderDistance", RID_CHAR_LEFT_BORDER_DISTANCE },
134  { "CharLocale", RID_CHAR_LOCALE },
135  { "CharLocaleAsian", RID_CHAR_LOCALE_ASIAN },
136  { "CharLocaleComplex", RID_CHAR_LOCALE_COMPLEX },
137  { "CharNoHyphenation", RID_CHAR_NO_HYPHENATION },
138  { "CharOverline", RID_CHAR_OVERLINE },
139  { "CharOverlineColor", RID_CHAR_OVERLINE_COLOR },
140  { "CharOverlineHasColor", RID_CHAR_OVERLINE_HAS_COLOR },
141  { "CharPosture", RID_CHAR_POSTURE },
142  { "CharPostureAsian", RID_CHAR_POSTURE_ASIAN },
143  { "CharPostureComplex", RID_CHAR_POSTURE_COMPLEX },
144  { "CharPropHeight", RID_CHAR_PROP_HEIGHT },
145  { "CharPropHeightAsian", RID_CHAR_PROP_HEIGHT_ASIAN },
146  { "CharPropHeightComplex", RID_CHAR_PROP_HEIGHT_COMPLEX },
147  { "CharRelief", RID_CHAR_RELIEF },
148  { "CharRightBorder", RID_CHAR_RIGHT_BORDER },
149  { "CharRightBorderDistance", RID_CHAR_RIGHT_BORDER_DISTANCE },
150  { "CharRotation", RID_CHAR_ROTATION },
151  { "CharRotationIsFitToLine", RID_CHAR_ROTATION_IS_FIT_TO_LINE },
152  { "CharScaleWidth", RID_CHAR_SCALE_WIDTH },
153  { "CharShadingValue", RID_CHAR_SHADING_VALUE },
154  { "CharShadowFormat", RID_CHAR_SHADOW_FORMAT },
155  { "CharShadowed", RID_CHAR_SHADOWED },
156  { "CharStrikeout", RID_CHAR_STRIKEOUT },
157  { "CharStyleName", RID_CHAR_STYLE_NAME },
158  { "CharStyleNames", RID_CHAR_STYLE_NAMES },
159  { "CharTopBorder", RID_CHAR_TOP_BORDER },
160  { "CharTopBorderDistance", RID_CHAR_TOP_BORDER_DISTANCE },
161  { "CharTransparence", RID_CHAR_TRANSPARENCE },
162  { "CharUnderline", RID_CHAR_UNDERLINE },
163  { "CharUnderlineColor", RID_CHAR_UNDERLINE_COLOR },
164  { "CharUnderlineHasColor", RID_CHAR_UNDERLINE_HAS_COLOR },
165  { "CharWeight", RID_CHAR_WEIGHT },
166  { "CharWeightAsian", RID_CHAR_WEIGHT_ASIAN },
167  { "CharWeightComplex", RID_CHAR_WEIGHT_COMPLEX },
168  { "CharWordMode", RID_CHAR_WORD_MODE },
169  { "ContinueingPreviousSubTree", RID_CONTINUING_PREVIOUS_SUB_TREE },
170  { "DisplayName", RID_DISPLAY_NAME },
171  { "DocumentIndex", RID_DOCUMENT_INDEX },
172  { "DocumentIndexMark", RID_DOCUMENT_INDEX_MARK },
173  { "DropCapCharStyleName", RID_DROP_CAP_CHAR_STYLE_NAME },
174  { "DropCapFormat", RID_DROP_CAP_FORMAT },
175  { "DropCapWholeWord", RID_DROP_CAP_WHOLE_WORD },
176  { "Endnote", RID_ENDNOTE },
177  { "FillBackground", RID_FILL_BACKGROUND },
178  { "FillBitmap", RID_FILL_BITMAP },
179  { "FillBitmapLogicalSize", RID_FILL_BITMAP_LOGICAL_SIZE },
180  { "FillBitmapMode", RID_FILL_BITMAP_MODE },
181  { "FillBitmapName", RID_FILL_BITMAP_NAME },
182  { "FillBitmapOffsetX", RID_FILL_BITMAP_OFFSET_X },
183  { "FillBitmapOffsetY", RID_FILL_BITMAP_OFFSET_Y },
184  { "FillBitmapPositionOffsetX", RID_FILL_BITMAP_POSITION_OFFSET_X },
185  { "FillBitmapPositionOffsetY", RID_FILL_BITMAP_POSITION_OFFSET_Y },
186  { "FillBitmapRectanglePoint", RID_FILL_BITMAP_RECTANGLE_POINT },
187  { "FillBitmapSizeX", RID_FILL_BITMAP_SIZE_X },
188  { "FillBitmapSizeY", RID_FILL_BITMAP_SIZE_Y },
189  { "FillBitmapStretch", RID_FILL_BITMAP_STRETCH },
190  { "FillBitmapTile", RID_FILL_BITMAP_TILE },
191  { "FillBitmapURL", RID_FILL_BITMAP_URL },
192  { "FillColor", RID_FILL_COLOR },
193  { "FillColor2", RID_FILL_COLOR2 },
194  { "FillGradient", RID_FILL_GRADIENT },
195  { "FillGradientName", RID_FILL_GRADIENT_NAME },
196  { "FillGradientStepCount", RID_FILL_GRADIENT_STEP_COUNT },
197  { "FillHatch", RID_FILL_HATCH },
198  { "FillHatchName", RID_FILL_HATCH_NAME },
199  { "FillStyle", RID_FILL_STYLE },
200  { "FillTransparence", RID_FILL_TRANSPARENCE },
201  { "FillTransparenceGradient", RID_FILL_TRANSPARENCE_GRADIENT },
202  { "FillTransparenceGradientName", RID_FILL_TRANSPARENCE_GRADIENT_NAME },
203  { "FollowStyle", RID_FOLLOW_STYLE },
204  { "Footnote", RID_FOOTNOTE },
205  { "Hidden", RID_HIDDEN },
206  { "HyperLinkEvents", RID_HYPERLINK_EVENTS },
207  { "HyperLinkName", RID_HYPERLINK_NAME },
208  { "HyperLinkTarget", RID_HYPERLINK_TARGET },
209  { "HyperLinkURL", RID_HYPERLINK_URL },
210  { "IsAutoUpdate", RID_IS_AUTO_UPDATE },
211  { "IsPhysical", RID_IS_PHYSICAL },
212  { "LeftBorder", RID_LEFT_BORDER },
213  { "LeftBorderDistance", RID_LEFT_BORDER_DISTANCE },
214  { "ListAutoFormat", RID_LIST_AUTO_FORMAT },
215  { "ListId", RID_LIST_ID },
216  { "ListLabelString", RID_LIST_LABEL_STRING },
217  { "MetadataReference", RID_METADATA_REFERENCE },
218  { "NestedTextContent", RID_NESTED_TEXT_CONTENT },
219  { "NumberingIsNumber", RID_NUMBERING_IS_NUMBER },
220  { "NumberingLevel", RID_NUMBERING_LEVEL },
221  { "NumberingRules", RID_NUMBERING_RULES },
222  { "NumberingStartValue", RID_NUMBERING_START_VALUE },
223  { "NumberingStyleName", RID_NUMBERING_STYLE_NAME },
224  { "OutlineContentVisible", RID_OUTLINE_CONTENT_VISIBLE },
225  { "OutlineLevel", RID_OUTLINE_LEVEL },
226  { "PageDescName", RID_PAGE_DESC_NAME },
227  { "PageNumberOffset", RID_PAGE_NUMBER_OFFSET },
228  { "PageStyleName", RID_PAGE_STYLE_NAME },
229  { "ParRsid", RID_PAR_RSID },
230  { "ParaAdjust", RID_PARA_ADJUST },
231  { "ParaAutoStyleName", RID_PARA_AUTO_STYLE_NAME },
232  { "ParaBackColor", RID_PARA_BACK_COLOR },
233  { "ParaBackGraphic", RID_PARA_BACK_GRAPHIC },
234  { "ParaBackGraphicFilter", RID_PARA_BACK_GRAPHIC_FILTER },
235  { "ParaBackGraphicLocation", RID_PARA_BACK_GRAPHIC_LOCATION },
236  { "ParaBackGraphicURL", RID_PARA_BACK_GRAPHIC_URL },
237  { "ParaBackTransparent", RID_PARA_BACK_TRANSPARENT },
238  { "ParaBottomMargin", RID_PARA_BOTTOM_MARGIN },
239  { "ParaBottomMarginRelative", RID_PARA_BOTTOM_MARGIN_RELATIVE },
240  { "ParaChapterNumberingLevel", RID_PARA_CHAPTER_NUMBERING_LEVEL },
241  { "ParaConditionalStyleName", RID_PARA_CONDITIONAL_STYLE_NAME },
242  { "ParaContextMargin", RID_PARA_CONTEXT_MARGIN },
243  { "ParaExpandSingleWord", RID_PARA_EXPAND_SINGLE_WORD },
244  { "ParaFirstLineIndent", RID_PARA_FIRST_LINE_INDENT },
245  { "ParaFirstLineIndentRelative", RID_PARA_FIRST_LINE_INDENT_RELATIVE },
246  { "ParaHyphenationMaxHyphens", RID_PARA_HYPHENATION_MAX_HYPHENS },
247  { "ParaHyphenationMaxLeadingChars", RID_PARA_HYPHENATION_MAX_LEADING_CHARS },
248  { "ParaHyphenationMaxTrailingChars", RID_PARA_HYPHENATION_MAX_TRAILING_CHARS },
249  { "ParaHyphenationNoCaps", RID_PARA_HYPHENATION_NO_CAPS },
250  { "ParaInteropGrabBag", RID_PARA_INTEROP_GRAB_BAG },
251  { "ParaIsAutoFirstLineIndent", RID_PARA_IS_AUTO_FIRST_LINE_INDENT },
252  { "ParaIsCharacterDistance", RID_PARA_IS_CHARACTER_DISTANCE },
253  { "ParaIsConnectBorder", RID_PARA_IS_CONNECT_BORDER },
254  { "ParaIsForbiddenRules", RID_PARA_IS_FORBIDDEN_RULES },
255  { "ParaIsHangingPunctuation", RID_PARA_IS_HANGING_PUNCTUATION },
256  { "ParaIsHyphenation", RID_PARA_IS_HYPHENATION },
257  { "ParaIsNumberingRestart", RID_PARA_IS_NUMBERING_RESTART },
258  { "ParaKeepTogether", RID_PARA_KEEP_TOGETHER },
259  { "ParaLastLineAdjust", RID_PARA_LAST_LINE_ADJUST },
260  { "ParaLeftMargin", RID_PARA_LEFT_MARGIN },
261  { "ParaLeftMarginRelative", RID_PARA_LEFT_MARGIN_RELATIVE },
262  { "ParaLineNumberCount", RID_PARA_LINE_NUMBER_COUNT },
263  { "ParaLineNumberStartValue", RID_PARA_LINE_NUMBER_START_VALUE },
264  { "ParaLineSpacing", RID_PARA_LINE_SPACING },
265  { "ParaOrphans", RID_PARA_ORPHANS },
266  { "ParaRegisterModeActive", RID_PARA_REGISTER_MODE_ACTIVE },
267  { "ParaRightMargin", RID_PARA_RIGHT_MARGIN },
268  { "ParaRightMarginRelative", RID_PARA_RIGHT_MARGIN_RELATIVE },
269  { "ParaShadowFormat", RID_PARA_SHADOW_FORMAT },
270  { "ParaSplit", RID_PARA_SPLIT },
271  { "ParaStyleName", RID_PARA_STYLE_NAME },
272  { "ParaTabStops", RID_PARA_TAB_STOPS },
273  { "ParaTopMargin", RID_PARA_TOP_MARGIN },
274  { "ParaTopMarginRelative", RID_PARA_TOP_MARGIN_RELATIVE },
275  { "ParaUserDefinedAttributes", RID_PARA_USER_DEFINED_ATTRIBUTES },
276  { "ParaVertAlignment", RID_PARA_VERT_ALIGNMENT },
277  { "ParaWidows", RID_PARA_WIDOWS },
278  { "ReferenceMark", RID_REFERENCE_MARK },
279  { "RightBorder", RID_RIGHT_BORDER },
280  { "RightBorderDistance", RID_RIGHT_BORDER_DISTANCE },
281  { "Rsid", RID_RSID },
282  { "RubyAdjust", RID_RUBY_ADJUST },
283  { "RubyCharStyleName", RID_RUBY_CHAR_STYLE_NAME },
284  { "RubyIsAbove", RID_RUBY_IS_ABOVE },
285  { "RubyPosition", RID_RUBY_POSITION },
286  { "RubyText", RID_RUBY_TEXT },
287  { "SnapToGrid", RID_SNAP_TO_GRID },
288  { "StyleInteropGrabBag", RID_STYLE_INTEROP_GRAB_BAG },
289  { "TextField", RID_TEXT_FIELD },
290  { "TextFrame", RID_TEXT_FRAME },
291  { "TextParagraph", RID_TEXT_PARAGRAPH },
292  { "TextSection", RID_TEXT_SECTION },
293  { "TextTable", RID_TEXT_TABLE },
294  { "TextUserDefinedAttributes", RID_TEXT_USER_DEFINED_ATTRIBUTES },
295  { "TopBorder", RID_TOP_BORDER },
296  { "TopBorderDistance", RID_TOP_BORDER_DISTANCE },
297  { "UnvisitedCharStyleName", RID_UNVISITED_CHAR_STYLE_NAME },
298  { "VisitedCharStyleName", RID_VISITED_CHAR_STYLE_NAME },
299  { "WritingMode", RID_WRITING_MODE },
300  { "BorderColor", RID_BORDER_COLOR },
301  { "BorderInnerLineWidth", RID_BORDER_INNER_LINE_WIDTH },
302  { "BorderLineDistance", RID_BORDER_LINE_DISTANCE },
303  { "BorderLineStyle", RID_BORDER_LINE_STYLE },
304  { "BorderLineWidth", RID_BORDER_LINE_WIDTH },
305  { "BorderOuterLineWidth", RID_BORDER_OUTER_LINE_WIDTH },
306  };
307 
308  auto itr = aNameToRID.find(rName);
309  if (itr != aNameToRID.end())
310  return SwResId(itr->second);
311  return rName;
312 }
313 
314 static svx::sidebar::TreeNode SimplePropToTreeNode(const OUString& rName, const css::uno::Any& rVal)
315 {
316  svx::sidebar::TreeNode aCurNode;
317  aCurNode.sNodeName = PropertyNametoRID(rName);
318  aCurNode.aValue = rVal;
319 
320  return aCurNode;
321 }
322 
323 static svx::sidebar::TreeNode BorderToTreeNode(const OUString& rName, const css::uno::Any& rVal)
324 {
325  table::BorderLine2 aBorder;
326  rVal >>= aBorder;
327  svx::sidebar::TreeNode aCurNode;
328  aCurNode.sNodeName = PropertyNametoRID(rName);
330 
331  aCurNode.children.push_back(SimplePropToTreeNode("BorderColor", css::uno::Any(aBorder.Color)));
332  aCurNode.children.push_back(
333  SimplePropToTreeNode("BorderLineWidth", css::uno::Any(aBorder.LineWidth)));
334  aCurNode.children.push_back(
335  SimplePropToTreeNode("BorderLineStyle", css::uno::Any(aBorder.LineStyle)));
336  aCurNode.children.push_back(
337  SimplePropToTreeNode("BorderLineDistance", css::uno::Any(aBorder.LineDistance)));
338  aCurNode.children.push_back(
339  SimplePropToTreeNode("BorderInnerLineWidth", css::uno::Any(aBorder.InnerLineWidth)));
340  aCurNode.children.push_back(
341  SimplePropToTreeNode("BorderOuterLineWidth", css::uno::Any(aBorder.OuterLineWidth)));
342 
343  return aCurNode;
344 }
345 
346 static svx::sidebar::TreeNode LocaleToTreeNode(const OUString& rName, const css::uno::Any& rVal)
347 {
348  svx::sidebar::TreeNode aCurNode;
349  aCurNode.sNodeName = PropertyNametoRID(rName);
350  lang::Locale aLocale;
351  rVal >>= aLocale;
352  OUString aLocaleText(aLocale.Language + "-" + aLocale.Country);
353  if (!aLocale.Variant.isEmpty())
354  aLocaleText += " (" + aLocale.Variant + ")";
355  aCurNode.aValue <<= aLocaleText;
356 
357  return aCurNode;
358 }
359 
360 // Collect text of the current level of the annotated text
361 // ranges (InContentMetadata) and metadata fields (MetadataField)
362 static OUString NestedTextContentToText(const css::uno::Any& rVal)
363 {
364  uno::Reference<container::XEnumerationAccess> xMeta;
365  if (rVal >>= xMeta)
366  {
367  uno::Reference<container::XEnumeration> xMetaPortions = xMeta->createEnumeration();
368 
369  OUStringBuffer aBuf;
370  while (xMetaPortions->hasMoreElements())
371  {
372  uno::Reference<css::text::XTextRange> xRng(xMetaPortions->nextElement(),
373  uno::UNO_QUERY);
374  aBuf.append(xRng->getString());
375  }
376  return aBuf.makeStringAndClear();
377  }
378 
379  return OUString();
380 }
381 
382 // List metadata associated to the paragraph or character range
383 static void MetadataToTreeNode(const css::uno::Reference<css::uno::XInterface>& rSource,
384  svx::sidebar::TreeNode& rNode)
385 {
386  uno::Reference<rdf::XMetadatable> xMeta(rSource, uno::UNO_QUERY_THROW);
387  // don't add tree node "Metadata Reference", if there is no xml:id
388  if (xMeta.is() && !xMeta->getMetadataReference().Second.isEmpty())
389  {
390  svx::sidebar::TreeNode aCurNode;
391  aCurNode.sNodeName = PropertyNametoRID("MetadataReference");
393 
394  // list associated (predicate, object) pairs of the actual subject
395  // under the tree node "Metadata Reference"
396  SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
397  uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(pDocSh->GetBaseModel(),
398  uno::UNO_QUERY);
399  const uno::Reference<rdf::XRepository>& xRepo = xDocumentMetadataAccess->getRDFRepository();
400  const css::uno::Reference<css::rdf::XResource> xSubject(rSource, uno::UNO_QUERY);
401  std::map<OUString, OUString> xStatements
402  = SwRDFHelper::getStatements(pDocSh->GetBaseModel(), xRepo->getGraphNames(), xSubject);
403  for (const auto& pair : xStatements)
404  aCurNode.children.push_back(
405  SimplePropToTreeNode(pair.first, uno::makeAny(pair.second)));
406 
407  rNode.children.push_back(aCurNode);
408  }
409 }
410 
412 PropertyToTreeNode(const css::beans::Property& rProperty,
413  const uno::Reference<beans::XPropertySet>& xPropertiesSet, const bool rIsGrey)
414 {
415  const OUString& rPropName = rProperty.Name;
416  svx::sidebar::TreeNode aCurNode;
417  const uno::Any aAny = xPropertiesSet->getPropertyValue(rPropName);
418  aCurNode.sNodeName = PropertyNametoRID(rPropName);
419 
420  // These properties are handled separately as they are stored in STRUCT and not in single data members
421  if (rPropName == "CharTopBorder" || rPropName == "CharBottomBorder"
422  || rPropName == "CharLeftBorder" || rPropName == "CharRightBorder"
423  || rPropName == "TopBorder" || rPropName == "BottomBorder" || rPropName == "LeftBorder"
424  || rPropName == "RightBorder")
425  {
426  aCurNode = BorderToTreeNode(rPropName, aAny);
427  }
428  else if (rPropName == "CharLocale")
429  {
430  aCurNode = LocaleToTreeNode(rPropName, aAny);
431  }
432  else
433  aCurNode = SimplePropToTreeNode(rPropName, aAny);
434 
435  if (rIsGrey)
436  {
437  aCurNode.isGrey = true;
438  for (svx::sidebar::TreeNode& rChildNode : aCurNode.children)
439  rChildNode.isGrey = true; // grey out all the children nodes
440  }
441 
442  return aCurNode;
443 }
444 
445 static void InsertValues(const css::uno::Reference<css::uno::XInterface>& rSource,
446  std::unordered_map<OUString, bool>& rIsDefined,
447  svx::sidebar::TreeNode& rNode, const bool isRoot,
448  const std::vector<OUString>& rHiddenProperty)
449 {
450  uno::Reference<beans::XPropertySet> xPropertiesSet(rSource, uno::UNO_QUERY_THROW);
451  uno::Reference<beans::XPropertyState> xPropertiesState(rSource, uno::UNO_QUERY_THROW);
452  const uno::Sequence<beans::Property> aProperties
453  = xPropertiesSet->getPropertySetInfo()->getProperties();
454 
455  for (const beans::Property& rProperty : aProperties)
456  {
457  const OUString& rPropName = rProperty.Name;
458  if (std::find(rHiddenProperty.begin(), rHiddenProperty.end(), rPropName)
459  != rHiddenProperty.end())
460  continue;
461 
462  if (isRoot
463  || xPropertiesState->getPropertyState(rPropName) == beans::PropertyState_DIRECT_VALUE)
464  {
465  svx::sidebar::TreeNode aCurNode
466  = PropertyToTreeNode(rProperty, xPropertiesSet, rIsDefined[rPropName]);
467  rIsDefined[rPropName] = true;
468 
469  // process NestedTextContent and show associated metadata
470  // under the tree node "Metadata Reference", if they exist
471  if (rPropName == "NestedTextContent")
472  {
473  uno::Reference<container::XEnumerationAccess> xMeta;
474  if (aCurNode.aValue >>= xMeta)
475  MetadataToTreeNode(xMeta, rNode);
476  aCurNode.aValue <<= NestedTextContentToText(aCurNode.aValue);
477  }
478 
479  rNode.children.push_back(aCurNode);
480  }
481  }
482 
485  Application::GetSettings().GetUILanguageTag().getLocale());
486 
487  std::sort(
488  rNode.children.begin(), rNode.children.end(),
489  [&aSorter](svx::sidebar::TreeNode const& rEntry1, svx::sidebar::TreeNode const& rEntry2) {
490  return aSorter.compare(rEntry1.sNodeName, rEntry2.sNodeName) < 0;
491  });
492 }
493 
494 static void UpdateTree(SwDocShell* pDocSh, std::vector<svx::sidebar::TreeNode>& aStore)
495 {
496  SwDoc* pDoc = pDocSh->GetDoc();
497  SwPaM* pCursor = pDoc->GetEditShell()->GetCursor();
498  svx::sidebar::TreeNode aCharDFNode;
499  svx::sidebar::TreeNode aCharNode;
500  svx::sidebar::TreeNode aParaNode;
501  svx::sidebar::TreeNode aParaDFNode;
502 
503  aCharNode.sNodeName = SwResId(STR_CHARACTERSTYLEFAMILY);
504  aParaNode.sNodeName = SwResId(STR_PARAGRAPHSTYLEFAMILY);
505  aCharDFNode.sNodeName = SwResId(RID_CHAR_DIRECTFORMAT);
506  aParaDFNode.sNodeName = SwResId(RID_PARA_DIRECTFORMAT);
511 
512  uno::Reference<text::XTextRange> xRange(
513  SwXTextRange::CreateXTextRange(*pDoc, *pCursor->GetPoint(), nullptr));
514  uno::Reference<beans::XPropertySet> xPropertiesSet(xRange, uno::UNO_QUERY_THROW);
515  std::unordered_map<OUString, bool> aIsDefined;
516 
517  const std::vector<OUString> aHiddenProperties{ UNO_NAME_RSID,
528 
529  InsertValues(xRange, aIsDefined, aCharDFNode, false, aHiddenProperties);
530 
531  uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(pDocSh->GetBaseModel(),
532  uno::UNO_QUERY);
533  uno::Reference<container::XNameAccess> xStyleFamilies
534  = xStyleFamiliesSupplier->getStyleFamilies();
535  OUString sCurrentCharStyle, sCurrentParaStyle, sDisplayName;
536 
537  uno::Reference<container::XNameAccess> xStyleFamily(
538  xStyleFamilies->getByName("CharacterStyles"), uno::UNO_QUERY_THROW);
539  xPropertiesSet->getPropertyValue("CharStyleName") >>= sCurrentCharStyle;
540  xPropertiesSet->getPropertyValue("ParaStyleName") >>= sCurrentParaStyle;
541 
542  if (!sCurrentCharStyle.isEmpty())
543  {
544  xPropertiesSet.set(xStyleFamily->getByName(sCurrentCharStyle), css::uno::UNO_QUERY_THROW);
545  xPropertiesSet->getPropertyValue("DisplayName") >>= sDisplayName;
546  svx::sidebar::TreeNode aCurrentChild;
547  aCurrentChild.sNodeName = sDisplayName;
549 
550  InsertValues(xPropertiesSet, aIsDefined, aCurrentChild, false, {});
551 
552  aCharNode.children.push_back(aCurrentChild);
553  }
554 
555  // Collect paragraph direct formatting
556  uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xRange, uno::UNO_QUERY_THROW);
557  uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
558  uno::Reference<text::XTextRange> xThisParagraphRange(xParaEnum->nextElement(), uno::UNO_QUERY);
559  if (xThisParagraphRange.is())
560  {
561  // Collect metadata of the current paragraph
562  MetadataToTreeNode(xThisParagraphRange, aParaDFNode);
563  InsertValues(xThisParagraphRange, aIsDefined, aParaDFNode, false, aHiddenProperties);
564  }
565 
566  xStyleFamily.set(xStyleFamilies->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW);
567 
568  while (!sCurrentParaStyle.isEmpty())
569  {
570  uno::Reference<style::XStyle> xPropertiesStyle(xStyleFamily->getByName(sCurrentParaStyle),
571  uno::UNO_QUERY_THROW);
572  xPropertiesSet.set(xPropertiesStyle, css::uno::UNO_QUERY_THROW);
573  xPropertiesSet->getPropertyValue("DisplayName") >>= sDisplayName;
574  OUString aParentParaStyle = xPropertiesStyle->getParentStyle();
575  svx::sidebar::TreeNode aCurrentChild;
576  aCurrentChild.sNodeName = sDisplayName;
578 
579  InsertValues(xPropertiesSet, aIsDefined, aCurrentChild, aParentParaStyle.isEmpty(), {});
580 
581  aParaNode.children.push_back(aCurrentChild);
582  sCurrentParaStyle = aParentParaStyle;
583  }
584 
585  std::reverse(aParaNode.children.begin(),
586  aParaNode.children.end()); // Parent style should be first then children
587 
588  /*
589  Display Order :-
590  PARAGRAPH STYLE
591  PARAGRAPH DIRECT FORMATTING
592  CHARACTER STYLE
593  DIRECT FORMATTING
594  */
595  aStore.push_back(aParaNode);
596  aStore.push_back(aParaDFNode);
597  aStore.push_back(aCharNode);
598  aStore.push_back(aCharDFNode);
599 }
600 
601 IMPL_LINK(WriterInspectorTextPanel, AttrChangedNotify, LinkParamNone*, pLink, void)
602 {
603  if (m_oldLink.IsSet())
604  m_oldLink.Call(pLink);
605 
606  SwDocShell* pDocSh = m_pShell->GetDoc()->GetDocShell();
607  std::vector<svx::sidebar::TreeNode> aStore;
608 
609  if (pDocSh && pDocSh->GetDoc()->GetEditShell()->GetCursor()->GetNode().GetTextNode())
610  UpdateTree(pDocSh, aStore);
611 
612  updateEntries(aStore);
613 }
614 
615 } // end of namespace svx::sidebar
616 
617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:223
#define UNO_NAME_RSID
Definition: unoprnms.hxx:818
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
static const AllSettings & GetSettings()
#define UNO_NAME_PARA_STYLE_NAME
Definition: unoprnms.hxx:172
constexpr OUStringLiteral UNO_NAME_CHAR_STYLE_NAME
Definition: doc.hxx:187
aBuf
static svx::sidebar::TreeNode PropertyToTreeNode(const css::beans::Property &rProperty, const uno::Reference< beans::XPropertySet > &xPropertiesSet, const bool rIsGrey)
IMPL_LINK(PageColumnControl, ColumnButtonClickHdl_Impl, weld::Button &, rButton, void)
static SfxObjectShell * Current()
#define UNO_NAME_PARA_CONDITIONAL_STYLE_NAME
Definition: unoprnms.hxx:463
PropertiesInfo aProperties
static std::map< OUString, OUString > getStatements(const css::uno::Reference< css::frame::XModel > &xModel, const css::uno::Sequence< css::uno::Reference< css::rdf::XURI >> &rGraphNames, const css::uno::Reference< css::rdf::XResource > &xSubject)
Gets all (XResource, key, value) statements in RDF graphs given the graph-names.
static svx::sidebar::TreeNode BorderToTreeNode(const OUString &rName, const css::uno::Any &rVal)
css::uno::Reference< css::frame::XModel > GetBaseModel() const
enum svx::sidebar::TreeNode::@3 NodeType
static svx::sidebar::TreeNode LocaleToTreeNode(const OUString &rName, const css::uno::Any &rVal)
void SetChgLnk(const Link< LinkParamNone *, void > &rLnk)
Definition: crsrsh.hxx:483
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:203
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
static void MetadataToTreeNode(const css::uno::Reference< css::uno::XInterface > &rSource, svx::sidebar::TreeNode &rNode)
css::uno::Any aValue
static OUString NestedTextContentToText(const css::uno::Any &rVal)
const SwPosition * GetPoint() const
Definition: pam.hxx:207
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:328
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent)
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:224
static svx::sidebar::TreeNode SimplePropToTreeNode(const OUString &rName, const css::uno::Any &rVal)
OUString SwResId(const char *pId)
Definition: swmodule.cxx:166
Shell * m_pShell
void updateEntries(const std::vector< TreeNode > &rStore)
#define UNO_NAME_NUMBERING_START_VALUE
Definition: unoprnms.hxx:148
std::vector< TreeNode > children
const Link< LinkParamNone *, void > & GetChgLnk() const
Definition: crsrsh.hxx:484
#define UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE
Definition: unoprnms.hxx:802
static void InsertValues(const css::uno::Reference< css::uno::XInterface > &rSource, std::unordered_map< OUString, bool > &rIsDefined, svx::sidebar::TreeNode &rNode, const bool isRoot, const std::vector< OUString > &rHiddenProperty)
#define UNO_NAME_PARRSID
Definition: unoprnms.hxx:819
const LanguageTag & getLocale()
#define UNO_NAME_NUMBERING_IS_NUMBER
Definition: unoprnms.hxx:149
SvBaseLink * pLink
static OUString PropertyNametoRID(const OUString &rName)
#define UNO_NAME_PARA_IS_NUMBERING_RESTART
Definition: unoprnms.hxx:488
Reference< XComponentContext > getProcessComponentContext()
static void UpdateTree(SwDocShell *pDocSh, std::vector< svx::sidebar::TreeNode > &aStore)
sal_Int32 compare(const OUString &rLHS, const OUString &rRHS) const
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1203
#define UNO_NAME_NUMBERING_LEVEL
#define UNO_NAME_PAGE_STYLE_NAME
Definition: unoprnms.hxx:168
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:845
OUString sDisplayName