LibreOffice Module svx (master) 1
ClassificationDialog.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 */
10
13
14#include <editeng/flditem.hxx>
15#include <editeng/eeitem.hxx>
16#include <editeng/section.hxx>
17#include <editeng/editobj.hxx>
18#include <editeng/wghtitem.hxx>
19#include <svl/itemset.hxx>
20#include <osl/file.hxx>
21#include <rtl/bootstrap.hxx>
22#include <config_folders.h>
23#include <tools/stream.hxx>
24#include <tools/XmlWriter.hxx>
25#include <tools/XmlWalker.hxx>
26#include <utility>
27#include <vcl/customweld.hxx>
28#include <vcl/event.hxx>
29#include <vcl/svapp.hxx>
30#include <sfx2/objsh.hxx>
31
32#include <officecfg/Office/Common.hxx>
33
35
36namespace svx {
37
38IMPL_STATIC_LINK(ClassificationDialog, KeyInput, const KeyEvent&, rKeyEvent, bool)
39{
40 bool bTextIsFreeForm = officecfg::Office::Common::Classification::IntellectualPropertyTextInputIsFreeForm::get();
41
42 if (!bTextIsFreeForm)
43 {
44 // Ignore key combination with modifier keys
45 if (rKeyEvent.GetKeyCode().IsMod3()
46 || rKeyEvent.GetKeyCode().IsMod2()
47 || rKeyEvent.GetKeyCode().IsMod1())
48 {
49 return true;
50 }
51
52 switch (rKeyEvent.GetKeyCode().GetCode())
53 {
54 // Allowed characters
55 case KEY_BACKSPACE:
56 case KEY_DELETE:
57 case KEY_DIVIDE:
58 case KEY_SEMICOLON:
59 case KEY_SPACE:
60 return false;
61 // Anything else is ignored
62 default:
63 return true;
64 }
65 }
66
67 return false;
68}
69
70namespace {
71
72constexpr size_t RECENTLY_USED_LIMIT = 5;
73
74constexpr OUStringLiteral constRecentlyUsedFileName(u"recentlyUsed.xml");
75
76OUString lcl_getClassificationUserPath()
77{
78 OUString sPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/user/classification/");
79 rtl::Bootstrap::expandMacros(sPath);
80 return sPath;
81}
82
83const SvxFieldItem* findField(editeng::Section const & rSection)
84{
85 for (SfxPoolItem const * pPool : rSection.maAttributes)
86 {
87 if (pPool->Which() == EE_FEATURE_FIELD)
88 return static_cast<const SvxFieldItem*>(pPool);
89 }
90 return nullptr;
91}
92
93bool fileExists(OUString const & sFilename)
94{
95 osl::File aFile(sFilename);
96 osl::FileBase::RC eRC = aFile.open(osl_File_OpenFlag_Read);
97 return osl::FileBase::E_None == eRC;
98}
99
100bool stringToClassificationType(std::string_view rsType, svx::ClassificationType & reType)
101{
102 if (rsType == "CATEGORY")
104 else if (rsType == "INTELLECTUAL_PROPERTY_PART")
106 else if (rsType == "MARKING")
108 else if (rsType == "PARAGRAPH")
110 else if (rsType == "TEXT")
112 else
113 return false;
114 return true;
115}
116
117OUString classificationTypeToString(svx::ClassificationType const & reType)
118{
119 switch(reType)
120 {
122 return "CATEGORY"; break;
124 return "MARKING"; break;
126 return "TEXT"; break;
128 return "INTELLECTUAL_PROPERTY_PART"; break;
130 return "PARAGRAPH"; break;
131 }
132 return OUString();
133}
134
135void writeResultToXml(tools::XmlWriter & rXmlWriter,
136 std::vector<ClassificationResult> const & rResultCollection)
137{
138 for (ClassificationResult const & rResult : rResultCollection)
139 {
140 rXmlWriter.startElement("element");
141 OUString sType = classificationTypeToString(rResult.meType);
142 rXmlWriter.attribute("type", sType);
143 rXmlWriter.startElement("string");
144 rXmlWriter.content(rResult.msName);
145 rXmlWriter.endElement();
146 rXmlWriter.startElement("abbreviatedString");
147 rXmlWriter.content(rResult.msAbbreviatedName);
148 rXmlWriter.endElement();
149 rXmlWriter.startElement("identifier");
150 rXmlWriter.content(rResult.msIdentifier);
151 rXmlWriter.endElement();
152 rXmlWriter.endElement();
153 }
154}
155
156} // end anonymous namespace
157
158ClassificationDialog::ClassificationDialog(weld::Window* pParent, const css::uno::Reference<css::document::XDocumentProperties>& rDocProps,
159 const bool bPerParagraph, std::function<void()> aParagraphSignHandler)
160 : GenericDialogController(pParent, "svx/ui/classificationdialog.ui", "AdvancedDocumentClassificationDialog")
161 , maHelper(rDocProps)
162 , maInternationalHelper(rDocProps, /*bUseLocalizedPolicy*/ false)
163 , m_bPerParagraph(bPerParagraph)
164 , m_aParagraphSignHandler(std::move(aParagraphSignHandler))
165 , m_nCurrentSelectedCategory(-1)
166 , m_xOkButton(m_xBuilder->weld_button("ok"))
167 , m_xSignButton(m_xBuilder->weld_button("signButton"))
168 , m_xToolBox(m_xBuilder->weld_toggle_button("toolbox"))
169 , m_xRecentlyUsedListBox(m_xBuilder->weld_combo_box("recentlyUsedCB"))
170 , m_xClassificationListBox(m_xBuilder->weld_combo_box("classificationCB"))
171 , m_xInternationalClassificationListBox(m_xBuilder->weld_combo_box("internationalClassificationCB"))
172 , m_xMarkingLabel(m_xBuilder->weld_label("markingLabel"))
173 , m_xMarkingListBox(m_xBuilder->weld_tree_view("markingLB"))
174 , m_xIntellectualPropertyPartListBox(m_xBuilder->weld_tree_view("intellectualPropertyPartLB"))
175 , m_xIntellectualPropertyPartNumberListBox(m_xBuilder->weld_tree_view("intellectualPropertyPartNumberLB"))
176 , m_xIntellectualPropertyPartAddButton(m_xBuilder->weld_button("intellectualPropertyPartAddButton"))
177 , m_xIntellectualPropertyPartEdit(m_xBuilder->weld_entry("intellectualPropertyPartEntry"))
178 , m_xIntellectualPropertyExpander(m_xBuilder->weld_expander("intellectualPropertyExpander"))
179 , m_xEditWindow(new ClassificationEditView)
180 , m_xEditWindowWeld(new weld::CustomWeld(*m_xBuilder, "classificationEditWindow", *m_xEditWindow))
181{
182 m_xOkButton->connect_clicked(LINK(this, ClassificationDialog, OkHdl));
183 m_xSignButton->connect_clicked(LINK(this, ClassificationDialog, ButtonClicked));
184 m_xSignButton->set_visible(m_bPerParagraph);
185
187
188 // no need for BOLD if we do paragraph classification
189 if (m_bPerParagraph)
190 {
191 m_xToolBox->hide();
192 }
193 else
194 {
195 m_xToolBox->connect_toggled(LINK(this, ClassificationDialog, SelectToolboxHdl));
196 }
197
198 m_xIntellectualPropertyPartAddButton->connect_clicked(LINK(this, ClassificationDialog, ButtonClicked));
199
200 m_xClassificationListBox->set_size_request(m_xClassificationListBox->get_approximate_digit_width() * 20, -1);
201 m_xClassificationListBox->connect_changed(LINK(this, ClassificationDialog, SelectClassificationHdl));
202 for (const OUString& rName : maHelper.GetBACNames())
203 m_xClassificationListBox->append_text(rName);
204
205 m_xInternationalClassificationListBox->set_size_request(m_xInternationalClassificationListBox->get_approximate_digit_width() * 20, -1);
206 m_xInternationalClassificationListBox->connect_changed(LINK(this, ClassificationDialog, SelectClassificationHdl));
207 for (const OUString& rName : maInternationalHelper.GetBACNames())
208 m_xInternationalClassificationListBox->append_text(rName);
209
210 if (!maHelper.GetMarkings().empty())
211 {
212 m_xMarkingListBox->set_size_request(m_xMarkingListBox->get_approximate_digit_width() * 10,
213 m_xMarkingListBox->get_height_rows(4));
214 m_xMarkingListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectMarkingHdl));
215
216 for (const OUString& rName : maHelper.GetMarkings())
217 m_xMarkingListBox->append_text(rName);
218 }
219 else
220 {
221 m_xMarkingListBox->hide();
222 m_xMarkingLabel->hide();
223 }
224
225 m_xIntellectualPropertyPartNumberListBox->set_size_request(m_xIntellectualPropertyPartNumberListBox->get_approximate_digit_width() * 10,
226 m_xIntellectualPropertyPartNumberListBox->get_height_rows(5));
227 m_xIntellectualPropertyPartNumberListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectIPPartNumbersHdl));
228 for (const OUString& rName : maHelper.GetIntellectualPropertyPartNumbers())
230
231 m_xIntellectualPropertyPartNumberListBox->set_size_request(m_xIntellectualPropertyPartNumberListBox->get_approximate_digit_width() * 20,
232 m_xIntellectualPropertyPartListBox->get_height_rows(5));
233 m_xIntellectualPropertyPartListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectIPPartHdl));
234 for (const OUString& rName : maHelper.GetIntellectualPropertyParts())
235 m_xIntellectualPropertyPartListBox->append_text(rName);
236
237 m_xRecentlyUsedListBox->set_size_request(m_xRecentlyUsedListBox->get_approximate_digit_width() * 5, -1);
238 m_xRecentlyUsedListBox->connect_changed(LINK(this, ClassificationDialog, SelectRecentlyUsedHdl));
239
240 m_xIntellectualPropertyExpander->connect_expanded(LINK(this, ClassificationDialog, ExpandedHdl));
241 if (officecfg::Office::Common::Classification::IntellectualPropertySectionExpanded::get())
243 else
244 m_nAsyncExpandEvent = nullptr;
245
246 m_xEditWindow->SetModifyHdl(LINK(this, ClassificationDialog, EditWindowModifiedHdl));
247
250
251 int nNumber = 1;
253 {
254 m_xRecentlyUsedListBox->set_sensitive(false);
255 }
256 else
257 {
258 for (std::vector<ClassificationResult> const & rResults : m_aRecentlyUsedValuesCollection)
259 {
260 OUString rContentRepresentation = svx::classification::convertClassificationResultToString(rResults);
261 OUString rDescription = OUString::number(nNumber) + ": " + rContentRepresentation;
262 nNumber++;
263
264 m_xRecentlyUsedListBox->append_text(rDescription);
265 }
266 }
267}
268
269//do it async so gtk has a chance to shrink it to best size, otherwise its larger than min
270IMPL_LINK_NOARG(ClassificationDialog, OnAsyncExpandHdl, void*, void)
271{
272 m_nAsyncExpandEvent = nullptr;
273 m_xIntellectualPropertyExpander->set_expanded(true);
274}
275
277{
280}
281
283{
284 const OUString aFullString = maHelper.GetBACNames()[nID];
285 const OUString aAbbreviatedString = maHelper.GetAbbreviatedBACNames()[nID];
286 const OUString aIdentifierString = maHelper.GetBACIdentifiers()[nID];
287 insertField(ClassificationType::CATEGORY, aAbbreviatedString, aFullString, aIdentifierString);
288}
289
290void ClassificationDialog::insertField(ClassificationType eType, OUString const & rString, OUString const & rFullString, OUString const & rIdentifier)
291{
292 ClassificationField aField(eType, rString, rFullString, rIdentifier);
293 m_xEditWindow->InsertField(SvxFieldItem(aField, EE_FEATURE_FIELD));
294}
295
296void ClassificationDialog::setupValues(std::vector<ClassificationResult> && rInput)
297{
298 m_aInitialValues = std::move(rInput);
300}
301
303{
304 OUString sPath = lcl_getClassificationUserPath();
305 OUString sFilePath(sPath + constRecentlyUsedFileName);
306
307 if (!fileExists(sFilePath))
308 return;
309
310 SvFileStream aFileStream(sFilePath, StreamMode::READ);
311 tools::XmlWalker aWalker;
312 if (!aWalker.open(&aFileStream))
313 return;
314
315 if (aWalker.name() != "recentlyUsedClassifications")
316 return;
317
318 aWalker.children();
319 while (aWalker.isValid())
320 {
321 if (aWalker.name() == "elementGroup")
322 {
323 std::vector<ClassificationResult> aResults;
324
325 aWalker.children();
326
327 while (aWalker.isValid())
328 {
329 if (aWalker.name() == "element")
330 {
332 OUString sString;
333 OUString sAbbreviatedString;
334 OUString sIdentifier;
335
336 // Convert string to classification type, but continue only if
337 // conversion was successful.
338 if (stringToClassificationType(aWalker.attribute("type"), eType))
339 {
340 aWalker.children();
341
342 while (aWalker.isValid())
343 {
344 if (aWalker.name() == "string")
345 {
346 sString = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
347 }
348 else if (aWalker.name() == "abbreviatedString")
349 {
350 sAbbreviatedString = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
351 }
352 else if (aWalker.name() == "identifier")
353 {
354 sIdentifier = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
355 }
356 aWalker.next();
357 }
358 aWalker.parent();
359
360 aResults.push_back({ eType, sString, sAbbreviatedString, sIdentifier });
361 }
362 }
363 aWalker.next();
364 }
365 aWalker.parent();
366 m_aRecentlyUsedValuesCollection.push_back(aResults);
367 }
368 aWalker.next();
369 }
370 aWalker.parent();
371}
372
374{
375 OUString sPath = lcl_getClassificationUserPath();
376 osl::Directory::createPath(sPath);
377 OUString sFilePath(sPath + constRecentlyUsedFileName);
378
379 std::unique_ptr<SvStream> pStream;
380 pStream.reset(new SvFileStream(sFilePath, StreamMode::STD_READWRITE | StreamMode::TRUNC));
381
382 tools::XmlWriter aXmlWriter(pStream.get());
383
384 if (!aXmlWriter.startDocument())
385 return;
386
387 aXmlWriter.startElement("recentlyUsedClassifications");
388
389 aXmlWriter.startElement("elementGroup");
390
391 writeResultToXml(aXmlWriter, getResult());
392
393 aXmlWriter.endElement();
394
395 if (m_aRecentlyUsedValuesCollection.size() >= RECENTLY_USED_LIMIT)
397
398 for (std::vector<ClassificationResult> const & rResultCollection : m_aRecentlyUsedValuesCollection)
399 {
400 aXmlWriter.startElement("elementGroup");
401
402 writeResultToXml(aXmlWriter, rResultCollection);
403
404 aXmlWriter.endElement();
405 }
406
407 aXmlWriter.endElement();
408
409 aXmlWriter.endDocument();
410}
411
412void ClassificationDialog::readIn(std::vector<ClassificationResult> const & rInput)
413{
414 sal_Int32 nParagraph = -1;
415
416 for (ClassificationResult const & rClassificationResult : rInput)
417 {
418
419 switch (rClassificationResult.meType)
420 {
422 {
423 m_xEditWindow->getEditView().InsertText(rClassificationResult.msName);
424 }
425 break;
426
428 {
429 OUString sName;
430 if (rClassificationResult.msName.isEmpty())
431 sName = maHelper.GetBACNameForIdentifier(rClassificationResult.msIdentifier);
432 else
433 sName = rClassificationResult.msName;
434
435 OUString sAbbreviatedName = rClassificationResult.msAbbreviatedName;
436 if (sAbbreviatedName.isEmpty())
437 sAbbreviatedName = maHelper.GetAbbreviatedBACName(sName);
438
439 m_xClassificationListBox->set_active_text(sName);
442
443 insertField(rClassificationResult.meType, sAbbreviatedName, sName, rClassificationResult.msIdentifier);
444 }
445 break;
446
448 {
449 m_xMarkingListBox->select_text(rClassificationResult.msName);
450 insertField(rClassificationResult.meType, rClassificationResult.msName, rClassificationResult.msName, rClassificationResult.msIdentifier);
451 }
452 break;
453
455 {
456 insertField(rClassificationResult.meType, rClassificationResult.msName, rClassificationResult.msName, rClassificationResult.msIdentifier);
457 }
458 break;
459
461 {
462 nParagraph++;
463
464 if (nParagraph != 0)
465 m_xEditWindow->getEditView().InsertParaBreak();
466
467 // Set paragraph font weight
468 FontWeight eWeight = (rClassificationResult.msName == "BOLD") ? WEIGHT_BOLD : WEIGHT_NORMAL;
469
470 ClassificationEditEngine& rEdEngine = m_xEditWindow->getEditEngine();
471 SfxItemSet aSet(rEdEngine.GetParaAttribs(nParagraph));
472 aSet.Put(SvxWeightItem(eWeight, EE_CHAR_WEIGHT));
473 rEdEngine.SetParaAttribs(nParagraph, aSet);
474 }
475 break;
476
477 default:
478 break;
479 }
480 }
482}
483
485{
486 const EditEngine& rEditEngine = m_xEditWindow->getEditEngine();
487
488 for (sal_Int32 nParagraph = 0; nParagraph < rEditEngine.GetParagraphCount(); ++nParagraph)
489 {
490 sal_uInt16 nFieldCount = rEditEngine.GetFieldCount(nParagraph);
491 for (sal_uInt16 nField = 0; nField < nFieldCount; ++nField)
492 {
493 EFieldInfo aFieldInfo = rEditEngine.GetFieldInfo(nParagraph, nField);
494 if (aFieldInfo.pFieldItem)
495 {
496 const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(aFieldInfo.pFieldItem->GetField());
497 if (pClassificationField && pClassificationField->meType == ClassificationType::CATEGORY)
498 {
499 m_xOkButton->set_sensitive(true);
500 return;
501 }
502 }
503 }
504 }
505
506 // Category field in the text edit has been deleted, so reset the list boxes
507 m_xOkButton->set_sensitive(false);
508 m_xClassificationListBox->set_active(-1);
510}
511
512std::vector<ClassificationResult> ClassificationDialog::getResult()
513{
514 std::vector<ClassificationResult> aClassificationResults;
515
516 ClassificationEditEngine& rEdEngine = m_xEditWindow->getEditEngine();
517 std::unique_ptr<EditTextObject> pEditText(rEdEngine.CreateTextObject());
518
519 sal_Int32 nCurrentParagraph = -1;
520
521 std::vector<editeng::Section> aSections;
522 pEditText->GetAllSections(aSections);
523 for (editeng::Section const & rSection : aSections)
524 {
525 while (nCurrentParagraph < rSection.mnParagraph)
526 {
527 nCurrentParagraph++;
528
529 // Get Weight of current paragraph
530 FontWeight eFontWeight = WEIGHT_NORMAL;
531 SfxItemSet aItemSet(rEdEngine.GetParaAttribs(nCurrentParagraph));
532 if (const SfxPoolItem* pItem = aItemSet.GetItem(EE_CHAR_WEIGHT, false))
533 {
534 const SvxWeightItem* pWeightItem = dynamic_cast<const SvxWeightItem*>(pItem);
535 if (pWeightItem && pWeightItem->GetWeight() == WEIGHT_BOLD)
536 eFontWeight = WEIGHT_BOLD;
537 }
538 // Font weight to string
539 OUString sWeightProperty = "NORMAL";
540 if (eFontWeight == WEIGHT_BOLD)
541 sWeightProperty = "BOLD";
542 // Insert into collection
543 OUString sBlank;
544 aClassificationResults.push_back({ ClassificationType::PARAGRAPH, sWeightProperty, sBlank, sBlank });
545 }
546
547 const SvxFieldItem* pFieldItem = findField(rSection);
548
549 ESelection aSelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, rSection.mnEnd);
550 const OUString sDisplayString = rEdEngine.GetText(aSelection);
551 if (!sDisplayString.isEmpty())
552 {
553 const ClassificationField* pClassificationField = pFieldItem ? dynamic_cast<const ClassificationField*>(pFieldItem->GetField()) : nullptr;
554
555 if (pClassificationField)
556 {
557 aClassificationResults.push_back({ pClassificationField->meType, pClassificationField->msFullClassName,
558 pClassificationField->msDescription, pClassificationField->msIdentifier });
559 }
560 else
561 {
562 aClassificationResults.push_back({ ClassificationType::TEXT, sDisplayString, sDisplayString, OUString() });
563 }
564 }
565 }
566
567 return aClassificationResults;
568}
569
570IMPL_LINK(ClassificationDialog, SelectClassificationHdl, weld::ComboBox&, rBox, void)
571{
572 const sal_Int32 nSelected = rBox.get_active();
573 if (nSelected < 0 || m_nCurrentSelectedCategory == nSelected)
574 return;
575
576 std::unique_ptr<EditTextObject> pEditText(m_xEditWindow->getEditEngine().CreateTextObject());
577 std::vector<editeng::Section> aSections;
578 pEditText->GetAllSections(aSections);
579
580 // if we are replacing an existing field
581 bool bReplaceExisting = false;
582 // selection of the existing field, which will be replaced
583 ESelection aExistingFieldSelection;
584
585 for (editeng::Section const & rSection : aSections)
586 {
587 const SvxFieldItem* pFieldItem = findField(rSection);
588 if (pFieldItem)
589 {
590 const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(pFieldItem->GetField());
591 if (pClassificationField && pClassificationField->meType == ClassificationType::CATEGORY)
592 {
593 aExistingFieldSelection = ESelection(rSection.mnParagraph, rSection.mnStart,
594 rSection.mnParagraph, rSection.mnEnd);
595 bReplaceExisting = true;
596 }
597 }
598 }
599
600 if (bReplaceExisting)
601 m_xEditWindow->getEditView().SetSelection(aExistingFieldSelection);
602
603 insertCategoryField(nSelected);
604
605 // Change category to the new selection
606 m_xInternationalClassificationListBox->set_active(nSelected);
607 m_xClassificationListBox->set_active(nSelected);
608 m_nCurrentSelectedCategory = nSelected;
609}
610
611IMPL_LINK(ClassificationDialog, SelectMarkingHdl, weld::TreeView&, rBox, bool)
612{
613 sal_Int32 nSelected = rBox.get_selected_index();
614 if (nSelected >= 0)
615 {
616 const OUString aString = maHelper.GetMarkings()[nSelected];
617 insertField(ClassificationType::MARKING, aString, aString);
618 }
619 return true;
620}
621
622IMPL_LINK(ClassificationDialog, SelectIPPartNumbersHdl, weld::TreeView&, rBox, bool)
623{
624 sal_Int32 nSelected = rBox.get_selected_index();
625 if (nSelected >= 0)
626 {
627 OUString sString = maHelper.GetIntellectualPropertyPartNumbers()[nSelected];
628 m_xIntellectualPropertyPartEdit->replace_selection(sString);
629 m_xIntellectualPropertyPartEdit->grab_focus();
630 }
631 return true;
632}
633
634IMPL_LINK(ClassificationDialog, SelectRecentlyUsedHdl, weld::ComboBox&, rBox, void)
635{
636 sal_Int32 nSelected = rBox.get_active();
637 if (nSelected >= 0)
638 {
639 m_xEditWindow->getEditEngine().Clear();
640 readIn(m_aRecentlyUsedValuesCollection[nSelected]);
641 }
642}
643
644IMPL_LINK(ClassificationDialog, SelectIPPartHdl, weld::TreeView&, rBox, bool)
645{
646 const sal_Int32 nSelected = rBox.get_selected_index();
647 if (nSelected >= 0)
648 {
649 const OUString sString = maHelper.GetIntellectualPropertyParts()[nSelected];
650 m_xIntellectualPropertyPartEdit->replace_selection(sString);
651 m_xIntellectualPropertyPartEdit->grab_focus();
652 }
653 return true;
654}
655
656IMPL_LINK(ClassificationDialog, ButtonClicked, weld::Button&, rButton, void)
657{
658 if (&rButton == m_xSignButton.get())
659 {
660 m_aParagraphSignHandler();
661 }
662 else if (&rButton == m_xIntellectualPropertyPartAddButton.get())
663 {
664 const OUString sString = m_xIntellectualPropertyPartEdit->get_text();
665 insertField(ClassificationType::INTELLECTUAL_PROPERTY_PART, sString, sString);
666 }
667}
668
670{
671 writeRecentlyUsed();
672 m_xDialog->response(RET_OK);
673}
674
676{
677 m_xEditWindow->InvertSelectionWeight();
678}
679
681{
682 toggleWidgetsDependingOnCategory();
683}
684
686{
687 std::shared_ptr<comphelper::ConfigurationChanges> aConfigurationChanges(comphelper::ConfigurationChanges::create());
688 officecfg::Office::Common::Classification::IntellectualPropertySectionExpanded::set(rExpander.get_expanded(), aConfigurationChanges);
689 aConfigurationChanges->commit();
690}
691
692} // end svx
693
694/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
Reference< XExecutableDialog > m_xDialog
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
OUString GetText(LineEnd eEnd=LINEEND_LF) const
std::unique_ptr< EditTextObject > CreateTextObject()
sal_Int32 GetParagraphCount() const
EFieldInfo GetFieldInfo(sal_Int32 nPara, sal_uInt16 nField) const
sal_uInt16 GetFieldCount(sal_Int32 nPara) const
virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const
std::vector< OUString > const & GetIntellectualPropertyParts() const
std::vector< OUString > const & GetIntellectualPropertyPartNumbers() const
std::vector< OUString > GetBACIdentifiers()
const OUString & GetAbbreviatedBACName(const OUString &sFullName)
OUString GetBACNameForIdentifier(std::u16string_view sIdentifier)
std::vector< OUString > const & GetMarkings() const
std::vector< OUString > GetAbbreviatedBACNames()
std::vector< OUString > GetBACNames()
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_uInt16 Which() const
const SvxFieldData * GetField() const
FontWeight GetWeight() const
static std::shared_ptr< ConfigurationChanges > create()
void readIn(std::vector< ClassificationResult > const &rInput)
std::unique_ptr< weld::Label > m_xMarkingLabel
std::unique_ptr< weld::Button > m_xIntellectualPropertyPartAddButton
std::unique_ptr< weld::TreeView > m_xMarkingListBox
std::vector< ClassificationResult > getResult()
std::vector< ClassificationResult > m_aInitialValues
void insertCategoryField(sal_Int32 nID)
std::vector< std::vector< ClassificationResult > > m_aRecentlyUsedValuesCollection
std::unique_ptr< weld::TreeView > m_xIntellectualPropertyPartListBox
std::unique_ptr< weld::Button > m_xOkButton
std::unique_ptr< weld::ComboBox > m_xClassificationListBox
ClassificationDialog(weld::Window *pParent, const css::uno::Reference< css::document::XDocumentProperties > &rDocProps, bool bPerParagraph, std::function< void()> aParagraphSignHandler=[]() {})
SfxClassificationHelper maHelper
std::unique_ptr< weld::Button > m_xSignButton
SfxClassificationHelper maInternationalHelper
std::unique_ptr< weld::TreeView > m_xIntellectualPropertyPartNumberListBox
std::unique_ptr< ClassificationEditView > m_xEditWindow
void insertField(ClassificationType eType, OUString const &rString, OUString const &rFullString, OUString const &rIdentifier=OUString())
std::unique_ptr< weld::ComboBox > m_xInternationalClassificationListBox
std::unique_ptr< weld::Expander > m_xIntellectualPropertyExpander
void setupValues(std::vector< ClassificationResult > &&rInput)
std::unique_ptr< weld::Entry > m_xIntellectualPropertyPartEdit
std::unique_ptr< weld::ToggleButton > m_xToolBox
std::unique_ptr< weld::ComboBox > m_xRecentlyUsedListBox
OString content()
OString attribute(const OString &sName) const
bool isValid() const
bool open(SvStream *pStream)
void content(const OString &sValue)
bool startDocument(sal_Int32 nIndent=2, bool bWriteXmlHeader=true)
void attribute(const char *sTagName, const OString &aValue)
void startElement(const char *sName)
#define SAL_CONFIGFILE(name)
constexpr TypedWhichId< SvxFieldItem > EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
DocumentType eType
WEIGHT_BOLD
WEIGHT_NORMAL
OUString sName
bool fileExists(const OString &fileName)
constexpr sal_uInt16 KEY_SEMICOLON
constexpr sal_uInt16 KEY_DELETE
constexpr sal_uInt16 KEY_SPACE
constexpr sal_uInt16 KEY_DIVIDE
constexpr sal_uInt16 KEY_BACKSPACE
FontWeight
OUString convertClassificationResultToString(std::vector< svx::ClassificationResult > const &rResults)
IMPL_STATIC_LINK(ClassificationDialog, KeyInput, const KeyEvent &, rKeyEvent, bool)
IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::Toggleable &, rBox, void)
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
std::unique_ptr< SvxFieldItem > pFieldItem
std::vector< const SfxPoolItem * > maAttributes
sal_Int32 mnParagraph
sal_Int32 mnStart
RET_OK