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/XBookmarksSupplier.hpp>
29#include <com/sun/star/text/XTextSectionsSupplier.hpp>
30#include <com/sun/star/text/XTextRange.hpp>
31#include <com/sun/star/text/XTextRangeCompare.hpp>
32#include <com/sun/star/beans/XPropertySet.hpp>
33#include <com/sun/star/beans/XPropertyState.hpp>
34#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
35#include <com/sun/star/table/BorderLine2.hpp>
36#include <com/sun/star/lang/IllegalArgumentException.hpp>
37#include <com/sun/star/rdf/XMetadatable.hpp>
38#include <com/sun/star/rdf/XDocumentMetadataAccess.hpp>
39#include <com/sun/star/container/XChild.hpp>
40
41#include <unotextrange.hxx>
42#include <comphelper/string.hxx>
45#include <vcl/settings.hxx>
46#include <inspectorproperties.hrc>
47#include <strings.hrc>
48#include <rdfhelper.hxx>
49
50namespace sw::sidebar
51{
52static void UpdateTree(SwDocShell& rDocSh, SwEditShell& rEditSh,
53 std::vector<svx::sidebar::TreeNode>& aStore, sal_Int32& rParIdx);
54
55std::unique_ptr<PanelLayout> WriterInspectorTextPanel::Create(weld::Widget* pParent)
56{
57 if (pParent == nullptr)
58 throw lang::IllegalArgumentException(
59 "no parent Window given to WriterInspectorTextPanel::Create", nullptr, 0);
60 return std::make_unique<WriterInspectorTextPanel>(pParent);
61}
62
64 : InspectorTextPanel(pParent)
65 , m_nParIdx(0)
66{
67 SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
68 m_pShell = pDocSh ? pDocSh->GetWrtShell() : nullptr;
69 if (m_pShell)
70 {
72 m_pShell->SetChgLnk(LINK(this, WriterInspectorTextPanel, AttrChangedNotify));
73 }
74
75 // Update panel on start
76 std::vector<svx::sidebar::TreeNode> aStore;
77 SwEditShell* pEditSh = pDocSh ? pDocSh->GetDoc()->GetEditShell() : nullptr;
78 if (pEditSh && pEditSh->GetCursor()->GetPointNode().GetTextNode())
79 UpdateTree(*pDocSh, *pEditSh, aStore, m_nParIdx);
80 updateEntries(aStore, m_nParIdx);
81}
82
84{
85 if (m_pShell)
87}
88
89static OUString PropertyNametoRID(const OUString& rName)
90{
91 static const std::map<OUString, TranslateId> aNameToRID = {
92 { "BorderDistance", RID_BORDER_DISTANCE },
93 { "BottomBorder", RID_BOTTOM_BORDER },
94 { "BottomBorderDistance", RID_BOTTOM_BORDER_DISTANCE },
95 { "BreakType", RID_BREAK_TYPE },
96 { "Category", RID_CATEGORY },
97 { "Cell", RID_CELL },
98 { "CharAutoEscapement", RID_CHAR_AUTO_ESCAPEMENT },
99 { "CharAutoKerning", RID_CHAR_AUTO_KERNING },
100 { "CharAutoStyleName", RID_CHAR_AUTO_STYLE_NAME },
101 { "CharBackColor", RID_CHAR_BACK_COLOR },
102 { "CharBackTransparent", RID_CHAR_BACK_TRANSPARENT },
103 { "CharBorderDistance", RID_CHAR_BORDER_DISTANCE },
104 { "CharBottomBorder", RID_CHAR_BOTTOM_BORDER },
105 { "CharBottomBorderDistance", RID_CHAR_BOTTOM_BORDER_DISTANCE },
106 { "CharCaseMap", RID_CHAR_CASE_MAP },
107 { "CharColor", RID_CHAR_COLOR },
108 { "CharCombineIsOn", RID_CHAR_COMBINE_IS_ON },
109 { "CharCombinePrefix", RID_CHAR_COMBINE_PREFIX },
110 { "CharCombineSuffix", RID_CHAR_COMBINE_SUFFIX },
111 { "CharContoured", RID_CHAR_CONTOURED },
112 { "CharCrossedOut", RID_CHAR_CROSSED_OUT },
113 { "CharDiffHeight", RID_CHAR_DIFF_HEIGHT },
114 { "CharDiffHeightAsian", RID_CHAR_DIFF_HEIGHT_ASIAN },
115 { "CharDiffHeightComplex", RID_CHAR_DIFF_HEIGHT_COMPLEX },
116 { "CharEmphasis", RID_CHAR_EMPHASIS },
117 { "CharEscapement", RID_CHAR_ESCAPEMENT },
118 { "CharEscapementHeight", RID_CHAR_ESCAPEMENT_HEIGHT },
119 { "CharFlash", RID_CHAR_FLASH },
120 { "CharFontCharSet", RID_CHAR_FONT_CHAR_SET },
121 { "CharFontCharSetAsian", RID_CHAR_FONT_CHAR_SET_ASIAN },
122 { "CharFontCharSetComplex", RID_CHAR_FONT_CHAR_SET_COMPLEX },
123 { "CharFontFamily", RID_CHAR_FONT_FAMILY },
124 { "CharFontFamilyAsian", RID_CHAR_FONT_FAMILY_ASIAN },
125 { "CharFontFamilyComplex", RID_CHAR_FONT_FAMILY_COMPLEX },
126 { "CharFontName", RID_CHAR_FONT_NAME },
127 { "CharFontNameAsian", RID_CHAR_FONT_NAME_ASIAN },
128 { "CharFontNameComplex", RID_CHAR_FONT_NAME_COMPLEX },
129 { "CharFontPitch", RID_CHAR_FONT_PITCH },
130 { "CharFontPitchAsian", RID_CHAR_FONT_PITCH_ASIAN },
131 { "CharFontPitchComplex", RID_CHAR_FONT_PITCH_COMPLEX },
132 { "CharFontStyleName", RID_CHAR_FONT_STYLE_NAME },
133 { "CharFontStyleNameAsian", RID_CHAR_FONT_STYLE_NAME_ASIAN },
134 { "CharFontStyleNameComplex", RID_CHAR_FONT_STYLE_NAME_COMPLEX },
135 { "CharHeight", RID_CHAR_HEIGHT },
136 { "CharHeightAsian", RID_CHAR_HEIGHT_ASIAN },
137 { "CharHeightComplex", RID_CHAR_HEIGHT_COMPLEX },
138 { "CharHidden", RID_CHAR_HIDDEN },
139 { "CharHighlight", RID_CHAR_HIGHLIGHT },
140 { "CharInteropGrabBag", RID_CHAR_INTEROP_GRAB_BAG },
141 { "CharKerning", RID_CHAR_KERNING },
142 { "CharLeftBorder", RID_CHAR_LEFT_BORDER },
143 { "CharLeftBorderDistance", RID_CHAR_LEFT_BORDER_DISTANCE },
144 { "CharLocale", RID_CHAR_LOCALE },
145 { "CharLocaleAsian", RID_CHAR_LOCALE_ASIAN },
146 { "CharLocaleComplex", RID_CHAR_LOCALE_COMPLEX },
147 { "CharNoHyphenation", RID_CHAR_NO_HYPHENATION },
148 { "CharOverline", RID_CHAR_OVERLINE },
149 { "CharOverlineColor", RID_CHAR_OVERLINE_COLOR },
150 { "CharOverlineHasColor", RID_CHAR_OVERLINE_HAS_COLOR },
151 { "CharPosture", RID_CHAR_POSTURE },
152 { "CharPostureAsian", RID_CHAR_POSTURE_ASIAN },
153 { "CharPostureComplex", RID_CHAR_POSTURE_COMPLEX },
154 { "CharPropHeight", RID_CHAR_PROP_HEIGHT },
155 { "CharPropHeightAsian", RID_CHAR_PROP_HEIGHT_ASIAN },
156 { "CharPropHeightComplex", RID_CHAR_PROP_HEIGHT_COMPLEX },
157 { "CharRelief", RID_CHAR_RELIEF },
158 { "CharRightBorder", RID_CHAR_RIGHT_BORDER },
159 { "CharRightBorderDistance", RID_CHAR_RIGHT_BORDER_DISTANCE },
160 { "CharRotation", RID_CHAR_ROTATION },
161 { "CharRotationIsFitToLine", RID_CHAR_ROTATION_IS_FIT_TO_LINE },
162 { "CharScaleWidth", RID_CHAR_SCALE_WIDTH },
163 { "CharShadingValue", RID_CHAR_SHADING_VALUE },
164 { "CharShadowFormat", RID_CHAR_SHADOW_FORMAT },
165 { "CharShadowed", RID_CHAR_SHADOWED },
166 { "CharStrikeout", RID_CHAR_STRIKEOUT },
167 { "CharStyleName", RID_CHAR_STYLE_NAME },
168 { "CharStyleNames", RID_CHAR_STYLE_NAMES },
169 { "CharTopBorder", RID_CHAR_TOP_BORDER },
170 { "CharTopBorderDistance", RID_CHAR_TOP_BORDER_DISTANCE },
171 { "CharTransparence", RID_CHAR_TRANSPARENCE },
172 { "CharUnderline", RID_CHAR_UNDERLINE },
173 { "CharUnderlineColor", RID_CHAR_UNDERLINE_COLOR },
174 { "CharUnderlineHasColor", RID_CHAR_UNDERLINE_HAS_COLOR },
175 { "CharWeight", RID_CHAR_WEIGHT },
176 { "CharWeightAsian", RID_CHAR_WEIGHT_ASIAN },
177 { "CharWeightComplex", RID_CHAR_WEIGHT_COMPLEX },
178 { "CharWordMode", RID_CHAR_WORD_MODE },
179 { "ContinueingPreviousSubTree", RID_CONTINUING_PREVIOUS_SUB_TREE },
180 { "DisplayName", RID_DISPLAY_NAME },
181 { "DocumentIndex", RID_DOCUMENT_INDEX },
182 { "DocumentIndexMark", RID_DOCUMENT_INDEX_MARK },
183 { "DropCapCharStyleName", RID_DROP_CAP_CHAR_STYLE_NAME },
184 { "DropCapFormat", RID_DROP_CAP_FORMAT },
185 { "DropCapWholeWord", RID_DROP_CAP_WHOLE_WORD },
186 { "Endnote", RID_ENDNOTE },
187 { "FillBackground", RID_FILL_BACKGROUND },
188 { "FillBitmap", RID_FILL_BITMAP },
189 { "FillBitmapLogicalSize", RID_FILL_BITMAP_LOGICAL_SIZE },
190 { "FillBitmapMode", RID_FILL_BITMAP_MODE },
191 { "FillBitmapName", RID_FILL_BITMAP_NAME },
192 { "FillBitmapOffsetX", RID_FILL_BITMAP_OFFSET_X },
193 { "FillBitmapOffsetY", RID_FILL_BITMAP_OFFSET_Y },
194 { "FillBitmapPositionOffsetX", RID_FILL_BITMAP_POSITION_OFFSET_X },
195 { "FillBitmapPositionOffsetY", RID_FILL_BITMAP_POSITION_OFFSET_Y },
196 { "FillBitmapRectanglePoint", RID_FILL_BITMAP_RECTANGLE_POINT },
197 { "FillBitmapSizeX", RID_FILL_BITMAP_SIZE_X },
198 { "FillBitmapSizeY", RID_FILL_BITMAP_SIZE_Y },
199 { "FillBitmapStretch", RID_FILL_BITMAP_STRETCH },
200 { "FillBitmapTile", RID_FILL_BITMAP_TILE },
201 { "FillBitmapURL", RID_FILL_BITMAP_URL },
202 { "FillColor", RID_FILL_COLOR },
203 { "FillColor2", RID_FILL_COLOR2 },
204 { "FillGradient", RID_FILL_GRADIENT },
205 { "FillGradientName", RID_FILL_GRADIENT_NAME },
206 { "FillGradientStepCount", RID_FILL_GRADIENT_STEP_COUNT },
207 { "FillHatch", RID_FILL_HATCH },
208 { "FillHatchName", RID_FILL_HATCH_NAME },
209 { "FillStyle", RID_FILL_STYLE },
210 { "FillTransparence", RID_FILL_TRANSPARENCE },
211 { "FillTransparenceGradient", RID_FILL_TRANSPARENCE_GRADIENT },
212 { "FillTransparenceGradientName", RID_FILL_TRANSPARENCE_GRADIENT_NAME },
213 { "FollowStyle", RID_FOLLOW_STYLE },
214 { "Footnote", RID_FOOTNOTE },
215 { "Hidden", RID_HIDDEN },
216 { "HyperLinkEvents", RID_HYPERLINK_EVENTS },
217 { "HyperLinkName", RID_HYPERLINK_NAME },
218 { "HyperLinkTarget", RID_HYPERLINK_TARGET },
219 { "HyperLinkURL", RID_HYPERLINK_URL },
220 { "IsAutoUpdate", RID_IS_AUTO_UPDATE },
221 { "IsPhysical", RID_IS_PHYSICAL },
222 { "LeftBorder", RID_LEFT_BORDER },
223 { "LeftBorderDistance", RID_LEFT_BORDER_DISTANCE },
224 { "ListAutoFormat", RID_LIST_AUTO_FORMAT },
225 { "ListId", RID_LIST_ID },
226 { "ListLabelString", RID_LIST_LABEL_STRING },
227 { "MetadataReference", RID_METADATA_REFERENCE },
228 { "NestedTextContent", RID_NESTED_TEXT_CONTENT },
229 { "NumberingIsNumber", RID_NUMBERING_IS_NUMBER },
230 { "NumberingLevel", RID_NUMBERING_LEVEL },
231 { "NumberingRules", RID_NUMBERING_RULES },
232 { "NumberingStartValue", RID_NUMBERING_START_VALUE },
233 { "NumberingStyleName", RID_NUMBERING_STYLE_NAME },
234 { "OutlineContentVisible", RID_OUTLINE_CONTENT_VISIBLE },
235 { "OutlineLevel", RID_OUTLINE_LEVEL },
236 { "PageDescName", RID_PAGE_DESC_NAME },
237 { "PageNumberOffset", RID_PAGE_NUMBER_OFFSET },
238 { "PageStyleName", RID_PAGE_STYLE_NAME },
239 { "ParRsid", RID_PAR_RSID },
240 { "ParaAdjust", RID_PARA_ADJUST },
241 { "ParaAutoStyleName", RID_PARA_AUTO_STYLE_NAME },
242 { "ParaBackColor", RID_PARA_BACK_COLOR },
243 { "ParaBackGraphic", RID_PARA_BACK_GRAPHIC },
244 { "ParaBackGraphicFilter", RID_PARA_BACK_GRAPHIC_FILTER },
245 { "ParaBackGraphicLocation", RID_PARA_BACK_GRAPHIC_LOCATION },
246 { "ParaBackGraphicURL", RID_PARA_BACK_GRAPHIC_URL },
247 { "ParaBackTransparent", RID_PARA_BACK_TRANSPARENT },
248 { "ParaBottomMargin", RID_PARA_BOTTOM_MARGIN },
249 { "ParaBottomMarginRelative", RID_PARA_BOTTOM_MARGIN_RELATIVE },
250 { "ParaChapterNumberingLevel", RID_PARA_CHAPTER_NUMBERING_LEVEL },
251 { "ParaConditionalStyleName", RID_PARA_CONDITIONAL_STYLE_NAME },
252 { "ParaContextMargin", RID_PARA_CONTEXT_MARGIN },
253 { "ParaExpandSingleWord", RID_PARA_EXPAND_SINGLE_WORD },
254 { "ParaFirstLineIndent", RID_PARA_FIRST_LINE_INDENT },
255 { "ParaFirstLineIndentRelative", RID_PARA_FIRST_LINE_INDENT_RELATIVE },
256 { "ParaHyphenationMaxHyphens", RID_PARA_HYPHENATION_MAX_HYPHENS },
257 { "ParaHyphenationMaxLeadingChars", RID_PARA_HYPHENATION_MAX_LEADING_CHARS },
258 { "ParaHyphenationMaxTrailingChars", RID_PARA_HYPHENATION_MAX_TRAILING_CHARS },
259 { "ParaHyphenationNoCaps", RID_PARA_HYPHENATION_NO_CAPS },
260 { "ParaHyphenationNoLastWord", RID_PARA_HYPHENATION_NO_LAST_WORD },
261 { "ParaHyphenationMinWordLength", RID_PARA_HYPHENATION_MIN_WORD_LENGTH },
262 { "ParaHyphenationZone", RID_PARA_HYPHENATION_ZONE },
263 { "ParaInteropGrabBag", RID_PARA_INTEROP_GRAB_BAG },
264 { "ParaIsAutoFirstLineIndent", RID_PARA_IS_AUTO_FIRST_LINE_INDENT },
265 { "ParaIsCharacterDistance", RID_PARA_IS_CHARACTER_DISTANCE },
266 { "ParaIsConnectBorder", RID_PARA_IS_CONNECT_BORDER },
267 { "ParaIsForbiddenRules", RID_PARA_IS_FORBIDDEN_RULES },
268 { "ParaIsHangingPunctuation", RID_PARA_IS_HANGING_PUNCTUATION },
269 { "ParaIsHyphenation", RID_PARA_IS_HYPHENATION },
270 { "ParaIsNumberingRestart", RID_PARA_IS_NUMBERING_RESTART },
271 { "ParaKeepTogether", RID_PARA_KEEP_TOGETHER },
272 { "ParaLastLineAdjust", RID_PARA_LAST_LINE_ADJUST },
273 { "ParaLeftMargin", RID_PARA_LEFT_MARGIN },
274 { "ParaLeftMarginRelative", RID_PARA_LEFT_MARGIN_RELATIVE },
275 { "ParaLineNumberCount", RID_PARA_LINE_NUMBER_COUNT },
276 { "ParaLineNumberStartValue", RID_PARA_LINE_NUMBER_START_VALUE },
277 { "ParaLineSpacing", RID_PARA_LINE_SPACING },
278 { "ParaOrphans", RID_PARA_ORPHANS },
279 { "ParaRegisterModeActive", RID_PARA_REGISTER_MODE_ACTIVE },
280 { "ParaRightMargin", RID_PARA_RIGHT_MARGIN },
281 { "ParaRightMarginRelative", RID_PARA_RIGHT_MARGIN_RELATIVE },
282 { "ParaShadowFormat", RID_PARA_SHADOW_FORMAT },
283 { "ParaSplit", RID_PARA_SPLIT },
284 { "ParaStyleName", RID_PARA_STYLE_NAME },
285 { "ParaTabStops", RID_PARA_TAB_STOPS },
286 { "ParaTopMargin", RID_PARA_TOP_MARGIN },
287 { "ParaTopMarginRelative", RID_PARA_TOP_MARGIN_RELATIVE },
288 { "ParaUserDefinedAttributes", RID_PARA_USER_DEFINED_ATTRIBUTES },
289 { "ParaVertAlignment", RID_PARA_VERT_ALIGNMENT },
290 { "ParaWidows", RID_PARA_WIDOWS },
291 { "ReferenceMark", RID_REFERENCE_MARK },
292 { "RightBorder", RID_RIGHT_BORDER },
293 { "RightBorderDistance", RID_RIGHT_BORDER_DISTANCE },
294 { "Rsid", RID_RSID },
295 { "RubyAdjust", RID_RUBY_ADJUST },
296 { "RubyCharStyleName", RID_RUBY_CHAR_STYLE_NAME },
297 { "RubyIsAbove", RID_RUBY_IS_ABOVE },
298 { "RubyPosition", RID_RUBY_POSITION },
299 { "RubyText", RID_RUBY_TEXT },
300 { "SnapToGrid", RID_SNAP_TO_GRID },
301 { "StyleInteropGrabBag", RID_STYLE_INTEROP_GRAB_BAG },
302 { "TextField", RID_TEXT_FIELD },
303 { "TextFrame", RID_TEXT_FRAME },
304 { "TextParagraph", RID_TEXT_PARAGRAPH },
305 { "TextSection", RID_TEXT_SECTION },
306 { "TextTable", RID_TEXT_TABLE },
307 { "TextUserDefinedAttributes", RID_TEXT_USER_DEFINED_ATTRIBUTES },
308 { "TopBorder", RID_TOP_BORDER },
309 { "TopBorderDistance", RID_TOP_BORDER_DISTANCE },
310 { "UnvisitedCharStyleName", RID_UNVISITED_CHAR_STYLE_NAME },
311 { "VisitedCharStyleName", RID_VISITED_CHAR_STYLE_NAME },
312 { "WritingMode", RID_WRITING_MODE },
313 { "BorderColor", RID_BORDER_COLOR },
314 { "BorderInnerLineWidth", RID_BORDER_INNER_LINE_WIDTH },
315 { "BorderLineDistance", RID_BORDER_LINE_DISTANCE },
316 { "BorderLineStyle", RID_BORDER_LINE_STYLE },
317 { "BorderLineWidth", RID_BORDER_LINE_WIDTH },
318 { "BorderOuterLineWidth", RID_BORDER_OUTER_LINE_WIDTH },
319 };
320
321 auto itr = aNameToRID.find(rName);
322 if (itr != aNameToRID.end())
323 return SwResId(itr->second);
324 return rName;
325}
326
327static svx::sidebar::TreeNode SimplePropToTreeNode(const OUString& rName, const css::uno::Any& rVal)
328{
329 svx::sidebar::TreeNode aCurNode;
330 aCurNode.sNodeName = PropertyNametoRID(rName);
331 aCurNode.aValue = rVal;
332
333 return aCurNode;
334}
335
336static svx::sidebar::TreeNode BorderToTreeNode(const OUString& rName, const css::uno::Any& rVal)
337{
338 table::BorderLine2 aBorder;
339 rVal >>= aBorder;
340 svx::sidebar::TreeNode aCurNode;
341 aCurNode.sNodeName = PropertyNametoRID(rName);
343
344 aCurNode.children.push_back(SimplePropToTreeNode("BorderColor", css::uno::Any(aBorder.Color)));
345 aCurNode.children.push_back(
346 SimplePropToTreeNode("BorderLineWidth", css::uno::Any(aBorder.LineWidth)));
347 aCurNode.children.push_back(
348 SimplePropToTreeNode("BorderLineStyle", css::uno::Any(aBorder.LineStyle)));
349 aCurNode.children.push_back(
350 SimplePropToTreeNode("BorderLineDistance", css::uno::Any(aBorder.LineDistance)));
351 aCurNode.children.push_back(
352 SimplePropToTreeNode("BorderInnerLineWidth", css::uno::Any(aBorder.InnerLineWidth)));
353 aCurNode.children.push_back(
354 SimplePropToTreeNode("BorderOuterLineWidth", css::uno::Any(aBorder.OuterLineWidth)));
355
356 return aCurNode;
357}
358
359static svx::sidebar::TreeNode LocaleToTreeNode(const OUString& rName, const css::uno::Any& rVal)
360{
361 svx::sidebar::TreeNode aCurNode;
362 aCurNode.sNodeName = PropertyNametoRID(rName);
363 lang::Locale aLocale;
364 rVal >>= aLocale;
365 OUString aLocaleText(aLocale.Language + "-" + aLocale.Country);
366 if (!aLocale.Variant.isEmpty())
367 aLocaleText += " (" + aLocale.Variant + ")";
368 aCurNode.aValue <<= aLocaleText;
369
370 return aCurNode;
371}
372
373// Collect text of the current level of the annotated text
374// ranges (InContentMetadata) and metadata fields (MetadataField)
375static OUString NestedTextContentToText(const css::uno::Any& rVal)
376{
377 uno::Reference<container::XEnumerationAccess> xMeta;
378 if (rVal >>= xMeta)
379 {
380 uno::Reference<container::XEnumeration> xMetaPortions = xMeta->createEnumeration();
381
382 OUStringBuffer aBuf;
383 while (xMetaPortions->hasMoreElements())
384 {
385 uno::Reference<css::text::XTextRange> xRng(xMetaPortions->nextElement(),
386 uno::UNO_QUERY);
387 aBuf.append(xRng->getString());
388 }
389 return aBuf.makeStringAndClear();
390 }
391
392 return OUString();
393}
394
395// List metadata associated to the paragraph or character range
396static void MetadataToTreeNode(const css::uno::Reference<css::uno::XInterface>& rSource,
398{
399 uno::Reference<rdf::XMetadatable> xMeta(rSource, uno::UNO_QUERY_THROW);
400 // don't add tree node "Metadata Reference", if there is no xml:id
401 if (!xMeta.is() || xMeta->getMetadataReference().Second.isEmpty())
402 return;
403
404 // add metadata of parents for nested annotated text ranges
405 uno::Reference<container::XChild> xChild(rSource, uno::UNO_QUERY);
406 if (xChild.is())
407 {
408 uno::Reference<container::XEnumerationAccess> xParentMeta(xChild->getParent(),
409 uno::UNO_QUERY);
410 if (xParentMeta.is())
411 MetadataToTreeNode(xParentMeta, rNode);
412 }
413
414 svx::sidebar::TreeNode aCurNode;
415 aCurNode.sNodeName = PropertyNametoRID("MetadataReference");
417
418 aCurNode.children.push_back(
419 SimplePropToTreeNode("xml:id", uno::Any(xMeta->getMetadataReference().Second)));
420
421 // list associated (predicate, object) pairs of the actual subject
422 // under the tree node "Metadata Reference"
423 if (SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current()))
424 {
425 uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(pDocSh->GetBaseModel(),
426 uno::UNO_QUERY);
427 const uno::Reference<rdf::XRepository>& xRepo = xDocumentMetadataAccess->getRDFRepository();
428 const css::uno::Reference<css::rdf::XResource> xSubject(rSource, uno::UNO_QUERY);
429 std::map<OUString, OUString> xStatements
430 = SwRDFHelper::getStatements(pDocSh->GetBaseModel(), xRepo->getGraphNames(), xSubject);
431 for (const auto& pair : xStatements)
432 aCurNode.children.push_back(SimplePropToTreeNode(pair.first, uno::Any(pair.second)));
433 }
434
435 rNode.children.push_back(aCurNode);
436}
437
439PropertyToTreeNode(const css::beans::Property& rProperty,
440 const uno::Reference<beans::XPropertySet>& xPropertiesSet, const bool rIsGrey)
441{
442 const OUString& rPropName = rProperty.Name;
443 svx::sidebar::TreeNode aCurNode;
444 const uno::Any aAny = xPropertiesSet->getPropertyValue(rPropName);
445 aCurNode.sNodeName = PropertyNametoRID(rPropName);
446
447 // These properties are handled separately as they are stored in STRUCT and not in single data members
448 if (rPropName == "CharTopBorder" || rPropName == "CharBottomBorder"
449 || rPropName == "CharLeftBorder" || rPropName == "CharRightBorder"
450 || rPropName == "TopBorder" || rPropName == "BottomBorder" || rPropName == "LeftBorder"
451 || rPropName == "RightBorder")
452 {
453 aCurNode = BorderToTreeNode(rPropName, aAny);
454 }
455 else if (rPropName == "CharLocale")
456 {
457 aCurNode = LocaleToTreeNode(rPropName, aAny);
458 }
459 else
460 aCurNode = SimplePropToTreeNode(rPropName, aAny);
461
462 if (rIsGrey)
463 {
464 aCurNode.isGrey = true;
465 for (svx::sidebar::TreeNode& rChildNode : aCurNode.children)
466 rChildNode.isGrey = true; // grey out all the children nodes
467 }
468
469 return aCurNode;
470}
471
472static void InsertValues(const css::uno::Reference<css::uno::XInterface>& rSource,
473 std::unordered_map<OUString, bool>& rIsDefined,
474 svx::sidebar::TreeNode& rNode, const bool isRoot,
475 const std::vector<OUString>& rHiddenProperty,
476 svx::sidebar::TreeNode& rFieldsNode)
477{
478 uno::Reference<beans::XPropertySet> xPropertiesSet(rSource, uno::UNO_QUERY_THROW);
479 uno::Reference<beans::XPropertyState> xPropertiesState(rSource, uno::UNO_QUERY_THROW);
480 const uno::Sequence<beans::Property> aProperties
481 = xPropertiesSet->getPropertySetInfo()->getProperties();
482
483 for (const beans::Property& rProperty : aProperties)
484 {
485 const OUString& rPropName = rProperty.Name;
486 if (std::find(rHiddenProperty.begin(), rHiddenProperty.end(), rPropName)
487 != rHiddenProperty.end())
488 continue;
489
490 if (isRoot
491 || xPropertiesState->getPropertyState(rPropName) == beans::PropertyState_DIRECT_VALUE)
492 {
494 = PropertyToTreeNode(rProperty, xPropertiesSet, rIsDefined[rPropName]);
495 rIsDefined[rPropName] = true;
496
497 // process NestedTextContent and show associated metadata
498 // under the tree node "Metadata Reference", if they exist
499 if (rPropName == "NestedTextContent")
500 {
501 uno::Reference<container::XEnumerationAccess> xMeta;
502 if (aCurNode.aValue >>= xMeta)
503 MetadataToTreeNode(xMeta, rFieldsNode);
504 aCurNode.aValue <<= NestedTextContentToText(aCurNode.aValue);
505 }
506
507 rNode.children.push_back(aCurNode);
508 }
509 }
510
513 Application::GetSettings().GetUILanguageTag().getLocale());
514
515 std::sort(
516 rNode.children.begin(), rNode.children.end(),
517 [&aSorter](svx::sidebar::TreeNode const& rEntry1, svx::sidebar::TreeNode const& rEntry2) {
518 return aSorter.compare(rEntry1.sNodeName, rEntry2.sNodeName) < 0;
519 });
520}
521
522static void UpdateTree(SwDocShell& rDocSh, SwEditShell& rEditSh,
523 std::vector<svx::sidebar::TreeNode>& aStore, sal_Int32& rParIdx)
524{
525 SwDoc* pDoc = rDocSh.GetDoc();
526 SwPaM* pCursor = rEditSh.GetCursor();
527 svx::sidebar::TreeNode aCharDFNode;
528 svx::sidebar::TreeNode aCharNode;
529 svx::sidebar::TreeNode aParaNode;
530 svx::sidebar::TreeNode aParaDFNode;
531 svx::sidebar::TreeNode aBookmarksNode;
532 svx::sidebar::TreeNode aFieldsNode;
533 svx::sidebar::TreeNode aTextSectionsNode;
534
535 aCharNode.sNodeName = SwResId(STR_CHARACTERSTYLEFAMILY);
536 aParaNode.sNodeName = SwResId(STR_PARAGRAPHSTYLEFAMILY);
537 aCharDFNode.sNodeName = SwResId(RID_CHAR_DIRECTFORMAT);
538 aParaDFNode.sNodeName = SwResId(RID_PARA_DIRECTFORMAT);
539 aBookmarksNode.sNodeName = SwResId(STR_CONTENT_TYPE_BOOKMARK);
540 aFieldsNode.sNodeName = SwResId(STR_CONTENT_TYPE_TEXTFIELD);
541 aTextSectionsNode.sNodeName = SwResId(STR_CONTENT_TYPE_REGION);
548 aTextSectionsNode.NodeType = svx::sidebar::TreeNode::Category;
549
550 uno::Reference<text::XTextRange> xRange(
551 SwXTextRange::CreateXTextRange(*pDoc, *pCursor->GetPoint(), nullptr));
552 uno::Reference<beans::XPropertySet> xPropertiesSet(xRange, uno::UNO_QUERY_THROW);
553 std::unordered_map<OUString, bool> aIsDefined;
554
555 const std::vector<OUString> aHiddenProperties{ UNO_NAME_RSID,
569
570 const std::vector<OUString> aHiddenCharacterProperties{ UNO_NAME_CHAR_COLOR_THEME,
572
573 InsertValues(xRange, aIsDefined, aCharDFNode, false, aHiddenProperties, aFieldsNode);
574
575 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(rDocSh.GetBaseModel(),
576 uno::UNO_QUERY);
577 uno::Reference<container::XNameAccess> xStyleFamilies
578 = xStyleFamiliesSupplier->getStyleFamilies();
579 OUString sCurrentCharStyle, sCurrentParaStyle, sDisplayName;
580
581 uno::Reference<container::XNameAccess> xStyleFamily(
582 xStyleFamilies->getByName("CharacterStyles"), uno::UNO_QUERY_THROW);
583 xPropertiesSet->getPropertyValue("CharStyleName") >>= sCurrentCharStyle;
584 xPropertiesSet->getPropertyValue("ParaStyleName") >>= sCurrentParaStyle;
585
586 if (!sCurrentCharStyle.isEmpty())
587 {
588 xPropertiesSet.set(xStyleFamily->getByName(sCurrentCharStyle), css::uno::UNO_QUERY_THROW);
589 xPropertiesSet->getPropertyValue("DisplayName") >>= sDisplayName;
590 svx::sidebar::TreeNode aCurrentChild;
591 aCurrentChild.sNodeName = sDisplayName;
593
594 InsertValues(xPropertiesSet, aIsDefined, aCurrentChild, false, aHiddenCharacterProperties,
595 aFieldsNode);
596
597 aCharNode.children.push_back(aCurrentChild);
598 }
599
600 // Collect paragraph direct formatting
601 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xRange, uno::UNO_QUERY_THROW);
602 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
603 uno::Reference<text::XTextRange> xThisParagraphRange(xParaEnum->nextElement(), uno::UNO_QUERY);
604 if (xThisParagraphRange.is())
605 {
606 // Collect metadata of the current paragraph
607 MetadataToTreeNode(xThisParagraphRange, aParaDFNode);
608 InsertValues(xThisParagraphRange, aIsDefined, aParaDFNode, false, aHiddenProperties,
609 aFieldsNode);
610 }
611
612 xStyleFamily.set(xStyleFamilies->getByName("ParagraphStyles"), uno::UNO_QUERY_THROW);
613
614 while (!sCurrentParaStyle.isEmpty())
615 {
616 uno::Reference<style::XStyle> xPropertiesStyle(xStyleFamily->getByName(sCurrentParaStyle),
617 uno::UNO_QUERY_THROW);
618 xPropertiesSet.set(xPropertiesStyle, css::uno::UNO_QUERY_THROW);
619 xPropertiesSet->getPropertyValue("DisplayName") >>= sDisplayName;
620 OUString aParentParaStyle = xPropertiesStyle->getParentStyle();
621 svx::sidebar::TreeNode aCurrentChild;
622 aCurrentChild.sNodeName = sDisplayName;
624
625 InsertValues(xPropertiesSet, aIsDefined, aCurrentChild, aParentParaStyle.isEmpty(),
626 aHiddenCharacterProperties, aFieldsNode);
627
628 aParaNode.children.push_back(aCurrentChild);
629 sCurrentParaStyle = aParentParaStyle;
630 }
631
632 std::reverse(aParaNode.children.begin(),
633 aParaNode.children.end()); // Parent style should be first then children
634
635 // Collect bookmarks at character position
636 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(rDocSh.GetBaseModel(),
637 uno::UNO_QUERY);
638
639 uno::Reference<container::XIndexAccess> xBookmarks(xBookmarksSupplier->getBookmarks(),
640 uno::UNO_QUERY);
641 for (sal_Int32 i = 0; i < xBookmarks->getCount(); ++i)
642 {
643 svx::sidebar::TreeNode aCurNode;
644 uno::Reference<text::XTextContent> bookmark;
645 xBookmarks->getByIndex(i) >>= bookmark;
646 uno::Reference<container::XNamed> xBookmark(bookmark, uno::UNO_QUERY);
647
648 try
649 {
650 uno::Reference<text::XTextRange> bookmarkRange = bookmark->getAnchor();
651 uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xRange->getText(),
652 uno::UNO_QUERY);
653 if (xTextRangeCompare.is()
654 && xTextRangeCompare->compareRegionStarts(bookmarkRange, xRange) != -1
655 && xTextRangeCompare->compareRegionEnds(xRange, bookmarkRange) != -1)
656 {
657 aCurNode.sNodeName = xBookmark->getName();
659
660 MetadataToTreeNode(xBookmark, aCurNode);
661 // show bookmark only if it has RDF metadata
662 if (aCurNode.children.size() > 0)
663 aBookmarksNode.children.push_back(aCurNode);
664 }
665 }
666 catch (const lang::IllegalArgumentException&)
667 {
668 }
669 }
670
671 // Collect sections at character position
672 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(rDocSh.GetBaseModel(),
673 uno::UNO_QUERY);
674
675 uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(),
676 uno::UNO_QUERY);
677 for (sal_Int32 i = 0; i < xTextSections->getCount(); ++i)
678 {
679 svx::sidebar::TreeNode aCurNode;
680 uno::Reference<text::XTextContent> section;
681 xTextSections->getByIndex(i) >>= section;
682 uno::Reference<container::XNamed> xTextSection(section, uno::UNO_QUERY);
683
684 try
685 {
686 uno::Reference<text::XTextRange> sectionRange = section->getAnchor();
687 uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xRange->getText(),
688 uno::UNO_QUERY);
689 if (xTextRangeCompare.is()
690 && xTextRangeCompare->compareRegionStarts(sectionRange, xRange) != -1
691 && xTextRangeCompare->compareRegionEnds(xRange, sectionRange) != -1)
692 {
693 aCurNode.sNodeName = xTextSection->getName();
695
696 MetadataToTreeNode(xTextSection, aCurNode);
697 // show section only if it has RDF metadata
698 if (aCurNode.children.size() > 0)
699 aTextSectionsNode.children.push_back(aCurNode);
700 }
701 }
702 catch (const lang::IllegalArgumentException&)
703 {
704 }
705 }
706
707 /*
708 Display Order :-
709 SECTIONS with RDF metadata (optional)
710 BOOKMARKS with RDF metadata (optional)
711 FIELDS with RDF metadata (optional)
712 PARAGRAPH STYLE
713 PARAGRAPH DIRECT FORMATTING
714 CHARACTER STYLE
715 DIRECT FORMATTING
716 */
717 rParIdx = 0;
718 // show sections, bookmarks and fields only if they have RDF metadata
719 if (aTextSectionsNode.children.size() > 0)
720 {
721 aStore.push_back(aTextSectionsNode);
722 rParIdx++;
723 }
724 if (aBookmarksNode.children.size() > 0)
725 {
726 aStore.push_back(aBookmarksNode);
727 rParIdx++;
728 }
729 if (aFieldsNode.children.size() > 0)
730 {
731 aStore.push_back(aFieldsNode);
732 rParIdx++;
733 }
734 aStore.push_back(aParaNode);
735 aStore.push_back(aParaDFNode);
736 aStore.push_back(aCharNode);
737 aStore.push_back(aCharDFNode);
738}
739
740IMPL_LINK(WriterInspectorTextPanel, AttrChangedNotify, LinkParamNone*, pLink, void)
741{
742 if (m_oldLink.IsSet())
743 m_oldLink.Call(pLink);
744
745 SwDocShell* pDocSh = m_pShell->GetDoc()->GetDocShell();
746 std::vector<svx::sidebar::TreeNode> aStore;
747
748 SwEditShell* pEditSh = pDocSh ? pDocSh->GetDoc()->GetEditShell() : nullptr;
749 if (pEditSh && pEditSh->GetCursor()->GetPointNode().GetTextNode())
750 UpdateTree(*pDocSh, *pEditSh, aStore, m_nParIdx);
751
752 updateEntries(aStore, m_nParIdx);
753}
754
755} // end of namespace svx::sidebar
756
757/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
static const AllSettings & GetSettings()
css::uno::Reference< css::frame::XModel3 > GetBaseModel() const
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
const Link< LinkParamNone *, void > & GetChgLnk() const
Definition: crsrsh.hxx:501
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:194
void SetChgLnk(const Link< LinkParamNone *, void > &rLnk)
Definition: crsrsh.hxx:500
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:225
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
Definition: doc.hxx:195
SwEditShell const * GetEditShell() const
Definition: doccorr.cxx:330
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:897
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
SwNode & GetPointNode() const
Definition: pam.hxx:283
const SwPosition * GetPoint() const
Definition: pam.hxx:261
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 rtl::Reference< SwXTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1199
void updateEntries(const std::vector< TreeNode > &rStore, const sal_Int32 nParIdx)
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent)
OUString sDisplayName
Shell * m_pShell
SvBaseLink * pLink
aBuf
const LanguageTag & getLocale()
Reference< XComponentContext > getProcessComponentContext()
int i
static void MetadataToTreeNode(const css::uno::Reference< css::uno::XInterface > &rSource, svx::sidebar::TreeNode &rNode)
static OUString PropertyNametoRID(const OUString &rName)
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, svx::sidebar::TreeNode &rFieldsNode)
IMPL_LINK(PageColumnControl, ColumnButtonClickHdl_Impl, weld::Button &, rButton, void)
static svx::sidebar::TreeNode SimplePropToTreeNode(const OUString &rName, const css::uno::Any &rVal)
static void UpdateTree(SwDocShell &rDocSh, SwEditShell &rEditSh, std::vector< svx::sidebar::TreeNode > &aStore, sal_Int32 &rParIdx)
static OUString NestedTextContentToText(const css::uno::Any &rVal)
static svx::sidebar::TreeNode BorderToTreeNode(const OUString &rName, const css::uno::Any &rVal)
static svx::sidebar::TreeNode PropertyToTreeNode(const css::beans::Property &rProperty, const uno::Reference< beans::XPropertySet > &xPropertiesSet, const bool rIsGrey)
static svx::sidebar::TreeNode LocaleToTreeNode(const OUString &rName, const css::uno::Any &rVal)
std::vector< TreeNode > children
css::uno::Any aValue
enum svx::sidebar::TreeNode::@4 NodeType
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
constexpr OUStringLiteral UNO_NAME_SORTED_TEXT_ID
Definition: unoprnms.hxx:415
constexpr OUStringLiteral UNO_NAME_PARA_IS_NUMBERING_RESTART
Definition: unoprnms.hxx:518
constexpr OUStringLiteral UNO_NAME_CHAR_COLOR_THEME
constexpr OUStringLiteral UNO_NAME_NUMBERING_IS_NUMBER
Definition: unoprnms.hxx:165
constexpr OUStringLiteral UNO_NAME_PARA_CONDITIONAL_STYLE_NAME
Definition: unoprnms.hxx:489
constexpr OUStringLiteral UNO_NAME_PARA_STYLE_NAME
Definition: unoprnms.hxx:189
constexpr OUStringLiteral UNO_NAME_CHAR_COLOR_TINT_OR_SHADE
constexpr OUStringLiteral UNO_NAME_RSID
Definition: unoprnms.hxx:849
constexpr OUStringLiteral UNO_NAME_NUMBERING_LEVEL
constexpr OUStringLiteral UNO_NAME_PAGE_STYLE_NAME
Definition: unoprnms.hxx:185
constexpr OUStringLiteral UNO_NAME_NUMBERING_START_VALUE
Definition: unoprnms.hxx:164
constexpr OUStringLiteral UNO_NAME_PARA_CONTINUEING_PREVIOUS_SUB_TREE
Definition: unoprnms.hxx:833
constexpr OUStringLiteral UNO_NAME_PARRSID
Definition: unoprnms.hxx:850
constexpr OUStringLiteral UNO_NAME_CHAR_STYLE_NAME