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 bool bPerParagraph, std::function<void()> aParagraphSignHandler)
159 : GenericDialogController(pParent, "svx/ui/classificationdialog.ui", "AdvancedDocumentClassificationDialog")
160 , maHelper(SfxObjectShell::Current()->getDocProperties())
161 , maInternationalHelper(SfxObjectShell::Current()->getDocProperties(), /*bUseLocalizedPolicy*/ false)
162 , m_bPerParagraph(bPerParagraph)
163 , m_aParagraphSignHandler(std::move(aParagraphSignHandler))
164 , m_nCurrentSelectedCategory(-1)
165 , m_xOkButton(m_xBuilder->weld_button("ok"))
166 , m_xSignButton(m_xBuilder->weld_button("signButton"))
167 , m_xToolBox(m_xBuilder->weld_toggle_button("toolbox"))
168 , m_xRecentlyUsedListBox(m_xBuilder->weld_combo_box("recentlyUsedCB"))
169 , m_xClassificationListBox(m_xBuilder->weld_combo_box("classificationCB"))
170 , m_xInternationalClassificationListBox(m_xBuilder->weld_combo_box("internationalClassificationCB"))
171 , m_xMarkingLabel(m_xBuilder->weld_label("markingLabel"))
172 , m_xMarkingListBox(m_xBuilder->weld_tree_view("markingLB"))
173 , m_xIntellectualPropertyPartListBox(m_xBuilder->weld_tree_view("intellectualPropertyPartLB"))
174 , m_xIntellectualPropertyPartNumberListBox(m_xBuilder->weld_tree_view("intellectualPropertyPartNumberLB"))
175 , m_xIntellectualPropertyPartAddButton(m_xBuilder->weld_button("intellectualPropertyPartAddButton"))
176 , m_xIntellectualPropertyPartEdit(m_xBuilder->weld_entry("intellectualPropertyPartEntry"))
177 , m_xIntellectualPropertyExpander(m_xBuilder->weld_expander("intellectualPropertyExpander"))
178 , m_xEditWindow(new ClassificationEditView)
179 , m_xEditWindowWeld(new weld::CustomWeld(*m_xBuilder, "classificationEditWindow", *m_xEditWindow))
180{
181 m_xOkButton->connect_clicked(LINK(this, ClassificationDialog, OkHdl));
182 m_xSignButton->connect_clicked(LINK(this, ClassificationDialog, ButtonClicked));
183 m_xSignButton->set_visible(m_bPerParagraph);
184
186
187 // no need for BOLD if we do paragraph classification
188 if (m_bPerParagraph)
189 {
190 m_xToolBox->hide();
191 }
192 else
193 {
194 m_xToolBox->connect_toggled(LINK(this, ClassificationDialog, SelectToolboxHdl));
195 }
196
197 m_xIntellectualPropertyPartAddButton->connect_clicked(LINK(this, ClassificationDialog, ButtonClicked));
198
199 m_xClassificationListBox->set_size_request(m_xClassificationListBox->get_approximate_digit_width() * 20, -1);
200 m_xClassificationListBox->connect_changed(LINK(this, ClassificationDialog, SelectClassificationHdl));
201 for (const OUString& rName : maHelper.GetBACNames())
202 m_xClassificationListBox->append_text(rName);
203
204 m_xInternationalClassificationListBox->set_size_request(m_xInternationalClassificationListBox->get_approximate_digit_width() * 20, -1);
205 m_xInternationalClassificationListBox->connect_changed(LINK(this, ClassificationDialog, SelectClassificationHdl));
206 for (const OUString& rName : maInternationalHelper.GetBACNames())
207 m_xInternationalClassificationListBox->append_text(rName);
208
209 if (!maHelper.GetMarkings().empty())
210 {
211 m_xMarkingListBox->set_size_request(m_xMarkingListBox->get_approximate_digit_width() * 10,
212 m_xMarkingListBox->get_height_rows(4));
213 m_xMarkingListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectMarkingHdl));
214
215 for (const OUString& rName : maHelper.GetMarkings())
216 m_xMarkingListBox->append_text(rName);
217 }
218 else
219 {
220 m_xMarkingListBox->hide();
221 m_xMarkingLabel->hide();
222 }
223
224 m_xIntellectualPropertyPartNumberListBox->set_size_request(m_xIntellectualPropertyPartNumberListBox->get_approximate_digit_width() * 10,
225 m_xIntellectualPropertyPartNumberListBox->get_height_rows(5));
226 m_xIntellectualPropertyPartNumberListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectIPPartNumbersHdl));
227 for (const OUString& rName : maHelper.GetIntellectualPropertyPartNumbers())
229
230 m_xIntellectualPropertyPartNumberListBox->set_size_request(m_xIntellectualPropertyPartNumberListBox->get_approximate_digit_width() * 20,
231 m_xIntellectualPropertyPartListBox->get_height_rows(5));
232 m_xIntellectualPropertyPartListBox->connect_row_activated(LINK(this, ClassificationDialog, SelectIPPartHdl));
233 for (const OUString& rName : maHelper.GetIntellectualPropertyParts())
234 m_xIntellectualPropertyPartListBox->append_text(rName);
235
236 m_xRecentlyUsedListBox->set_size_request(m_xRecentlyUsedListBox->get_approximate_digit_width() * 5, -1);
237 m_xRecentlyUsedListBox->connect_changed(LINK(this, ClassificationDialog, SelectRecentlyUsedHdl));
238
239 m_xIntellectualPropertyExpander->connect_expanded(LINK(this, ClassificationDialog, ExpandedHdl));
240 if (officecfg::Office::Common::Classification::IntellectualPropertySectionExpanded::get())
242 else
243 m_nAsyncExpandEvent = nullptr;
244
245 m_xEditWindow->SetModifyHdl(LINK(this, ClassificationDialog, EditWindowModifiedHdl));
246
249
250 int nNumber = 1;
252 {
253 m_xRecentlyUsedListBox->set_sensitive(false);
254 }
255 else
256 {
257 for (std::vector<ClassificationResult> const & rResults : m_aRecentlyUsedValuesCollection)
258 {
259 OUString rContentRepresentation = svx::classification::convertClassificationResultToString(rResults);
260 OUString rDescription = OUString::number(nNumber) + ": " + rContentRepresentation;
261 nNumber++;
262
263 m_xRecentlyUsedListBox->append_text(rDescription);
264 }
265 }
266}
267
268//do it async so gtk has a chance to shrink it to best size, otherwise its larger than min
269IMPL_LINK_NOARG(ClassificationDialog, OnAsyncExpandHdl, void*, void)
270{
271 m_nAsyncExpandEvent = nullptr;
272 m_xIntellectualPropertyExpander->set_expanded(true);
273}
274
276{
279}
280
282{
283 const OUString aFullString = maHelper.GetBACNames()[nID];
284 const OUString aAbbreviatedString = maHelper.GetAbbreviatedBACNames()[nID];
285 const OUString aIdentifierString = maHelper.GetBACIdentifiers()[nID];
286 insertField(ClassificationType::CATEGORY, aAbbreviatedString, aFullString, aIdentifierString);
287}
288
289void ClassificationDialog::insertField(ClassificationType eType, OUString const & rString, OUString const & rFullString, OUString const & rIdentifier)
290{
291 ClassificationField aField(eType, rString, rFullString, rIdentifier);
292 m_xEditWindow->InsertField(SvxFieldItem(aField, EE_FEATURE_FIELD));
293}
294
295void ClassificationDialog::setupValues(std::vector<ClassificationResult> && rInput)
296{
297 m_aInitialValues = std::move(rInput);
299}
300
302{
303 OUString sPath = lcl_getClassificationUserPath();
304 OUString sFilePath(sPath + constRecentlyUsedFileName);
305
306 if (!fileExists(sFilePath))
307 return;
308
309 SvFileStream aFileStream(sFilePath, StreamMode::READ);
310 tools::XmlWalker aWalker;
311 if (!aWalker.open(&aFileStream))
312 return;
313
314 if (aWalker.name() != "recentlyUsedClassifications")
315 return;
316
317 aWalker.children();
318 while (aWalker.isValid())
319 {
320 if (aWalker.name() == "elementGroup")
321 {
322 std::vector<ClassificationResult> aResults;
323
324 aWalker.children();
325
326 while (aWalker.isValid())
327 {
328 if (aWalker.name() == "element")
329 {
331 OUString sString;
332 OUString sAbbreviatedString;
333 OUString sIdentifier;
334
335 // Convert string to classification type, but continue only if
336 // conversion was successful.
337 if (stringToClassificationType(aWalker.attribute("type"), eType))
338 {
339 aWalker.children();
340
341 while (aWalker.isValid())
342 {
343 if (aWalker.name() == "string")
344 {
345 sString = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
346 }
347 else if (aWalker.name() == "abbreviatedString")
348 {
349 sAbbreviatedString = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
350 }
351 else if (aWalker.name() == "identifier")
352 {
353 sIdentifier = OStringToOUString(aWalker.content(), RTL_TEXTENCODING_UTF8);
354 }
355 aWalker.next();
356 }
357 aWalker.parent();
358
359 aResults.push_back({ eType, sString, sAbbreviatedString, sIdentifier });
360 }
361 }
362 aWalker.next();
363 }
364 aWalker.parent();
365 m_aRecentlyUsedValuesCollection.push_back(aResults);
366 }
367 aWalker.next();
368 }
369 aWalker.parent();
370}
371
373{
374 OUString sPath = lcl_getClassificationUserPath();
375 osl::Directory::createPath(sPath);
376 OUString sFilePath(sPath + constRecentlyUsedFileName);
377
378 std::unique_ptr<SvStream> pStream;
379 pStream.reset(new SvFileStream(sFilePath, StreamMode::STD_READWRITE | StreamMode::TRUNC));
380
381 tools::XmlWriter aXmlWriter(pStream.get());
382
383 if (!aXmlWriter.startDocument())
384 return;
385
386 aXmlWriter.startElement("recentlyUsedClassifications");
387
388 aXmlWriter.startElement("elementGroup");
389
390 writeResultToXml(aXmlWriter, getResult());
391
392 aXmlWriter.endElement();
393
394 if (m_aRecentlyUsedValuesCollection.size() >= RECENTLY_USED_LIMIT)
396
397 for (std::vector<ClassificationResult> const & rResultCollection : m_aRecentlyUsedValuesCollection)
398 {
399 aXmlWriter.startElement("elementGroup");
400
401 writeResultToXml(aXmlWriter, rResultCollection);
402
403 aXmlWriter.endElement();
404 }
405
406 aXmlWriter.endElement();
407
408 aXmlWriter.endDocument();
409}
410
411void ClassificationDialog::readIn(std::vector<ClassificationResult> const & rInput)
412{
413 sal_Int32 nParagraph = -1;
414
415 for (ClassificationResult const & rClassificationResult : rInput)
416 {
417
418 switch (rClassificationResult.meType)
419 {
421 {
422 m_xEditWindow->getEditView().InsertText(rClassificationResult.msName);
423 }
424 break;
425
427 {
428 OUString sName;
429 if (rClassificationResult.msName.isEmpty())
430 sName = maHelper.GetBACNameForIdentifier(rClassificationResult.msIdentifier);
431 else
432 sName = rClassificationResult.msName;
433
434 OUString sAbbreviatedName = rClassificationResult.msAbbreviatedName;
435 if (sAbbreviatedName.isEmpty())
436 sAbbreviatedName = maHelper.GetAbbreviatedBACName(sName);
437
438 m_xClassificationListBox->set_active_text(sName);
441
442 insertField(rClassificationResult.meType, sAbbreviatedName, sName, rClassificationResult.msIdentifier);
443 }
444 break;
445
447 {
448 m_xMarkingListBox->select_text(rClassificationResult.msName);
449 insertField(rClassificationResult.meType, rClassificationResult.msName, rClassificationResult.msName, rClassificationResult.msIdentifier);
450 }
451 break;
452
454 {
455 insertField(rClassificationResult.meType, rClassificationResult.msName, rClassificationResult.msName, rClassificationResult.msIdentifier);
456 }
457 break;
458
460 {
461 nParagraph++;
462
463 if (nParagraph != 0)
464 m_xEditWindow->getEditView().InsertParaBreak();
465
466 // Set paragraph font weight
467 FontWeight eWeight = (rClassificationResult.msName == "BOLD") ? WEIGHT_BOLD : WEIGHT_NORMAL;
468
469 ClassificationEditEngine& rEdEngine = m_xEditWindow->getEditEngine();
470 SfxItemSet aSet(rEdEngine.GetParaAttribs(nParagraph));
471 aSet.Put(SvxWeightItem(eWeight, EE_CHAR_WEIGHT));
472 rEdEngine.SetParaAttribs(nParagraph, aSet);
473 }
474 break;
475
476 default:
477 break;
478 }
479 }
481}
482
484{
485 const EditEngine& rEditEngine = m_xEditWindow->getEditEngine();
486
487 for (sal_Int32 nParagraph = 0; nParagraph < rEditEngine.GetParagraphCount(); ++nParagraph)
488 {
489 sal_uInt16 nFieldCount = rEditEngine.GetFieldCount(nParagraph);
490 for (sal_uInt16 nField = 0; nField < nFieldCount; ++nField)
491 {
492 EFieldInfo aFieldInfo = rEditEngine.GetFieldInfo(nParagraph, nField);
493 if (aFieldInfo.pFieldItem)
494 {
495 const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(aFieldInfo.pFieldItem->GetField());
496 if (pClassificationField && pClassificationField->meType == ClassificationType::CATEGORY)
497 {
498 m_xOkButton->set_sensitive(true);
499 return;
500 }
501 }
502 }
503 }
504
505 // Category field in the text edit has been deleted, so reset the list boxes
506 m_xOkButton->set_sensitive(false);
507 m_xClassificationListBox->set_active(-1);
509}
510
511std::vector<ClassificationResult> ClassificationDialog::getResult()
512{
513 std::vector<ClassificationResult> aClassificationResults;
514
515 ClassificationEditEngine& rEdEngine = m_xEditWindow->getEditEngine();
516 std::unique_ptr<EditTextObject> pEditText(rEdEngine.CreateTextObject());
517
518 sal_Int32 nCurrentParagraph = -1;
519
520 std::vector<editeng::Section> aSections;
521 pEditText->GetAllSections(aSections);
522 for (editeng::Section const & rSection : aSections)
523 {
524 while (nCurrentParagraph < rSection.mnParagraph)
525 {
526 nCurrentParagraph++;
527
528 // Get Weight of current paragraph
529 FontWeight eFontWeight = WEIGHT_NORMAL;
530 SfxItemSet aItemSet(rEdEngine.GetParaAttribs(nCurrentParagraph));
531 if (const SfxPoolItem* pItem = aItemSet.GetItem(EE_CHAR_WEIGHT, false))
532 {
533 const SvxWeightItem* pWeightItem = dynamic_cast<const SvxWeightItem*>(pItem);
534 if (pWeightItem && pWeightItem->GetWeight() == WEIGHT_BOLD)
535 eFontWeight = WEIGHT_BOLD;
536 }
537 // Font weight to string
538 OUString sWeightProperty = "NORMAL";
539 if (eFontWeight == WEIGHT_BOLD)
540 sWeightProperty = "BOLD";
541 // Insert into collection
542 OUString sBlank;
543 aClassificationResults.push_back({ ClassificationType::PARAGRAPH, sWeightProperty, sBlank, sBlank });
544 }
545
546 const SvxFieldItem* pFieldItem = findField(rSection);
547
548 ESelection aSelection(rSection.mnParagraph, rSection.mnStart, rSection.mnParagraph, rSection.mnEnd);
549 const OUString sDisplayString = rEdEngine.GetText(aSelection);
550 if (!sDisplayString.isEmpty())
551 {
552 const ClassificationField* pClassificationField = pFieldItem ? dynamic_cast<const ClassificationField*>(pFieldItem->GetField()) : nullptr;
553
554 if (pClassificationField)
555 {
556 aClassificationResults.push_back({ pClassificationField->meType, pClassificationField->msFullClassName,
557 pClassificationField->msDescription, pClassificationField->msIdentifier });
558 }
559 else
560 {
561 aClassificationResults.push_back({ ClassificationType::TEXT, sDisplayString, sDisplayString, OUString() });
562 }
563 }
564 }
565
566 return aClassificationResults;
567}
568
569IMPL_LINK(ClassificationDialog, SelectClassificationHdl, weld::ComboBox&, rBox, void)
570{
571 const sal_Int32 nSelected = rBox.get_active();
572 if (nSelected < 0 || m_nCurrentSelectedCategory == nSelected)
573 return;
574
575 std::unique_ptr<EditTextObject> pEditText(m_xEditWindow->getEditEngine().CreateTextObject());
576 std::vector<editeng::Section> aSections;
577 pEditText->GetAllSections(aSections);
578
579 // if we are replacing an existing field
580 bool bReplaceExisting = false;
581 // selection of the existing field, which will be replaced
582 ESelection aExistingFieldSelection;
583
584 for (editeng::Section const & rSection : aSections)
585 {
586 const SvxFieldItem* pFieldItem = findField(rSection);
587 if (pFieldItem)
588 {
589 const ClassificationField* pClassificationField = dynamic_cast<const ClassificationField*>(pFieldItem->GetField());
590 if (pClassificationField && pClassificationField->meType == ClassificationType::CATEGORY)
591 {
592 aExistingFieldSelection = ESelection(rSection.mnParagraph, rSection.mnStart,
593 rSection.mnParagraph, rSection.mnEnd);
594 bReplaceExisting = true;
595 }
596 }
597 }
598
599 if (bReplaceExisting)
600 m_xEditWindow->getEditView().SetSelection(aExistingFieldSelection);
601
602 insertCategoryField(nSelected);
603
604 // Change category to the new selection
605 m_xInternationalClassificationListBox->set_active(nSelected);
606 m_xClassificationListBox->set_active(nSelected);
607 m_nCurrentSelectedCategory = nSelected;
608}
609
610IMPL_LINK(ClassificationDialog, SelectMarkingHdl, weld::TreeView&, rBox, bool)
611{
612 sal_Int32 nSelected = rBox.get_selected_index();
613 if (nSelected >= 0)
614 {
615 const OUString aString = maHelper.GetMarkings()[nSelected];
616 insertField(ClassificationType::MARKING, aString, aString);
617 }
618 return true;
619}
620
621IMPL_LINK(ClassificationDialog, SelectIPPartNumbersHdl, weld::TreeView&, rBox, bool)
622{
623 sal_Int32 nSelected = rBox.get_selected_index();
624 if (nSelected >= 0)
625 {
626 OUString sString = maHelper.GetIntellectualPropertyPartNumbers()[nSelected];
627 m_xIntellectualPropertyPartEdit->replace_selection(sString);
628 m_xIntellectualPropertyPartEdit->grab_focus();
629 }
630 return true;
631}
632
633IMPL_LINK(ClassificationDialog, SelectRecentlyUsedHdl, weld::ComboBox&, rBox, void)
634{
635 sal_Int32 nSelected = rBox.get_active();
636 if (nSelected >= 0)
637 {
638 m_xEditWindow->getEditEngine().Clear();
639 readIn(m_aRecentlyUsedValuesCollection[nSelected]);
640 }
641}
642
643IMPL_LINK(ClassificationDialog, SelectIPPartHdl, weld::TreeView&, rBox, bool)
644{
645 const sal_Int32 nSelected = rBox.get_selected_index();
646 if (nSelected >= 0)
647 {
648 const OUString sString = maHelper.GetIntellectualPropertyParts()[nSelected];
649 m_xIntellectualPropertyPartEdit->replace_selection(sString);
650 m_xIntellectualPropertyPartEdit->grab_focus();
651 }
652 return true;
653}
654
655IMPL_LINK(ClassificationDialog, ButtonClicked, weld::Button&, rButton, void)
656{
657 if (&rButton == m_xSignButton.get())
658 {
659 m_aParagraphSignHandler();
660 }
661 else if (&rButton == m_xIntellectualPropertyPartAddButton.get())
662 {
663 const OUString sString = m_xIntellectualPropertyPartEdit->get_text();
664 insertField(ClassificationType::INTELLECTUAL_PROPERTY_PART, sString, sString);
665 }
666}
667
669{
670 writeRecentlyUsed();
671 m_xDialog->response(RET_OK);
672}
673
675{
676 m_xEditWindow->InvertSelectionWeight();
677}
678
680{
681 toggleWidgetsDependingOnCategory();
682}
683
685{
686 std::shared_ptr<comphelper::ConfigurationChanges> aConfigurationChanges(comphelper::ConfigurationChanges::create());
687 officecfg::Office::Common::Classification::IntellectualPropertySectionExpanded::set(rExpander.get_expanded(), aConfigurationChanges);
688 aConfigurationChanges->commit();
689}
690
691} // end svx
692
693/* 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
SfxClassificationHelper maHelper
std::unique_ptr< weld::Button > m_xSignButton
SfxClassificationHelper maInternationalHelper
std::unique_ptr< weld::TreeView > m_xIntellectualPropertyPartNumberListBox
std::unique_ptr< ClassificationEditView > m_xEditWindow
ClassificationDialog(weld::Window *pParent, bool bPerParagraph, std::function< void()> aParagraphSignHandler=[]() {})
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 OString &sTagName, const OString &aValue)
void startElement(const OString &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