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