Version 7.1.7.1, tag libreoffice-7.1.7.1
[LibreOffice.git] / sfx2 / source / doc / autoredactdialog.cxx
blob2fea27f6975b3dfd4a5d27f2733b7579db9575e1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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 */
10 #include <autoredactdialog.hxx>
12 #include <sfx2/filedlghelper.hxx>
13 #include <sfx2/sfxresid.hxx>
14 #include <sfx2/strings.hrc>
16 #include <osl/file.hxx>
17 #include <sal/log.hxx>
18 #include <vcl/svapp.hxx>
19 #include <vcl/weld.hxx>
20 #include <unotools/viewoptions.hxx>
22 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
24 #include <boost/property_tree/json_parser.hpp>
26 #define FILEDIALOG_FILTER_JSON "*.json"
28 int TargetsTable::GetRowByTargetName(const OUString& sName)
30 for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
32 RedactionTarget* pTarget
33 = reinterpret_cast<RedactionTarget*>(m_xControl->get_id(i).toInt64());
34 if (pTarget->sName == sName)
36 return i;
39 return -1;
42 TargetsTable::TargetsTable(std::unique_ptr<weld::TreeView> xControl)
43 : m_xControl(std::move(xControl))
45 m_xControl->set_size_request(555, 250);
46 std::vector<int> aWidths;
47 aWidths.push_back(100);
48 aWidths.push_back(50);
49 aWidths.push_back(200);
50 aWidths.push_back(105);
51 aWidths.push_back(105);
52 m_xControl->set_column_fixed_widths(aWidths);
53 m_xControl->set_selection_mode(SelectionMode::Multiple);
56 namespace
58 OUString getTypeName(RedactionTargetType nType)
60 OUString sTypeName(SfxResId(STR_REDACTION_TARGET_TYPE_UNKNOWN));
62 switch (nType)
64 case RedactionTargetType::REDACTION_TARGET_TEXT:
65 sTypeName = SfxResId(STR_REDACTION_TARGET_TYPE_TEXT);
66 break;
67 case RedactionTargetType::REDACTION_TARGET_REGEX:
68 sTypeName = SfxResId(STR_REDACTION_TARGET_TYPE_REGEX);
69 break;
70 case RedactionTargetType::REDACTION_TARGET_PREDEFINED:
71 sTypeName = SfxResId(STR_REDACTION_TARGET_TYPE_PREDEF);
72 break;
73 case RedactionTargetType::REDACTION_TARGET_UNKNOWN:
74 sTypeName = SfxResId(STR_REDACTION_TARGET_TYPE_UNKNOWN);
75 break;
78 return sTypeName;
81 /// Returns TypeID to be used in the add/edit target dialog
82 OUString getTypeID(RedactionTargetType nType)
84 OUString sTypeID("unknown");
86 switch (nType)
88 case RedactionTargetType::REDACTION_TARGET_TEXT:
89 sTypeID = "text";
90 break;
91 case RedactionTargetType::REDACTION_TARGET_REGEX:
92 sTypeID = "regex";
93 break;
94 case RedactionTargetType::REDACTION_TARGET_PREDEFINED:
95 sTypeID = "predefined";
96 break;
97 case RedactionTargetType::REDACTION_TARGET_UNKNOWN:
98 sTypeID = "unknown";
99 break;
102 return sTypeID;
106 void TargetsTable::InsertTarget(RedactionTarget* pTarget)
108 if (!pTarget)
110 SAL_WARN("sfx.doc", "pTarget is null in TargetsTable::InsertTarget()");
111 return;
114 // Check if the name is empty or invalid (clashing with another entry's name)
115 if (pTarget->sName.isEmpty() || GetRowByTargetName(pTarget->sName) != -1)
117 pTarget->sName = GetNameProposal();
120 OUString sContent = pTarget->sContent;
122 if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED)
124 //selection_num;selection_name
125 sContent = sContent.getToken(1, ';');
128 // Add to the end
129 int nRow = m_xControl->n_children();
130 m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(pTarget)), pTarget->sName);
131 m_xControl->set_text(nRow, getTypeName(pTarget->sType), 1);
132 m_xControl->set_text(nRow, sContent, 2);
133 m_xControl->set_text(
134 nRow, pTarget->bCaseSensitive ? SfxResId(STR_REDACTION_YES) : SfxResId(STR_REDACTION_NO),
136 m_xControl->set_text(
137 nRow, pTarget->bWholeWords ? SfxResId(STR_REDACTION_YES) : SfxResId(STR_REDACTION_NO), 4);
140 RedactionTarget* TargetsTable::GetTargetByName(const OUString& sName)
142 int nEntry = GetRowByTargetName(sName);
143 if (nEntry == -1)
144 return nullptr;
146 return reinterpret_cast<RedactionTarget*>(m_xControl->get_id(nEntry).toInt64());
149 OUString TargetsTable::GetNameProposal() const
151 OUString sDefaultTargetName(SfxResId(STR_REDACTION_TARGET));
152 sal_Int32 nHighestTargetId = 0;
153 for (int i = 0, nCount = m_xControl->n_children(); i < nCount; ++i)
155 RedactionTarget* pTarget
156 = reinterpret_cast<RedactionTarget*>(m_xControl->get_id(i).toInt64());
157 const OUString& sName = pTarget->sName;
158 sal_Int32 nIndex = 0;
159 if (sName.getToken(0, ' ', nIndex) == sDefaultTargetName)
161 sal_Int32 nCurrTargetId = sName.getToken(0, ' ', nIndex).toInt32();
162 nHighestTargetId = std::max<sal_Int32>(nHighestTargetId, nCurrTargetId);
165 return sDefaultTargetName + " " + OUString::number(nHighestTargetId + 1);
168 void TargetsTable::setRowData(int nRowIndex, const RedactionTarget* pTarget)
170 OUString sContent = pTarget->sContent;
172 if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED)
174 //selection_num;selection_name
175 sContent = sContent.getToken(1, ';');
178 m_xControl->set_text(nRowIndex, pTarget->sName, 0);
179 m_xControl->set_text(nRowIndex, getTypeName(pTarget->sType), 1);
180 m_xControl->set_text(nRowIndex, sContent, 2);
181 m_xControl->set_text(
182 nRowIndex,
183 pTarget->bCaseSensitive ? SfxResId(STR_REDACTION_YES) : SfxResId(STR_REDACTION_NO), 3);
184 m_xControl->set_text(
185 nRowIndex, pTarget->bWholeWords ? SfxResId(STR_REDACTION_YES) : SfxResId(STR_REDACTION_NO),
189 IMPL_LINK_NOARG(SfxAutoRedactDialog, Load, weld::Button&, void)
191 //Load a targets list from a previously saved file (a json file?)
192 // ask for filename, where we should load the new config data from
193 StartFileDialog(StartFileDialogType::Open, SfxResId(STR_REDACTION_LOAD_TARGETS));
196 IMPL_LINK_NOARG(SfxAutoRedactDialog, Save, weld::Button&, void)
198 //Allow saving the targets into a file
199 StartFileDialog(StartFileDialogType::SaveAs, SfxResId(STR_REDACTION_SAVE_TARGETS));
202 IMPL_LINK_NOARG(SfxAutoRedactDialog, AddHdl, weld::Button&, void)
204 // Open the Add Target dialog, create a new target and insert into the targets vector and the listbox
205 SfxAddTargetDialog aAddTargetDialog(getDialog(), m_xTargetsBox->GetNameProposal());
207 bool bIncomplete;
210 bIncomplete = false;
212 if (aAddTargetDialog.run() != RET_OK)
213 return;
215 if (aAddTargetDialog.getName().isEmpty()
216 || aAddTargetDialog.getType() == RedactionTargetType::REDACTION_TARGET_UNKNOWN
217 || aAddTargetDialog.getContent().isEmpty())
219 bIncomplete = true;
220 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
221 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
222 SfxResId(STR_REDACTION_FIELDS_REQUIRED)));
223 xBox->run();
225 else if (m_xTargetsBox->GetTargetByName(aAddTargetDialog.getName()))
227 bIncomplete = true;
228 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
229 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
230 SfxResId(STR_REDACTION_TARGET_NAME_CLASH)));
231 xBox->run();
234 } while (bIncomplete);
236 //Alright, we now have everything we need to construct a new target
237 RedactionTarget* redactiontarget = new RedactionTarget(
238 { aAddTargetDialog.getName(), aAddTargetDialog.getType(), aAddTargetDialog.getContent(),
239 aAddTargetDialog.isCaseSensitive(), aAddTargetDialog.isWholeWords(), 0 });
241 // Only the visual/display part
242 m_xTargetsBox->InsertTarget(redactiontarget);
244 // Actually add to the targets vector
245 if (m_xTargetsBox->GetTargetByName(redactiontarget->sName))
246 m_aTableTargets.emplace_back(redactiontarget, redactiontarget->sName);
247 else
249 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
250 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
251 SfxResId(STR_REDACTION_TARGET_ADD_ERROR)));
252 xBox->run();
253 delete redactiontarget;
257 IMPL_LINK_NOARG(SfxAutoRedactDialog, EditHdl, weld::Button&, void)
259 sal_Int32 nSelectedRow = m_xTargetsBox->get_selected_index();
261 // No selection, nothing to edit
262 if (nSelectedRow < 0)
263 return;
265 // Only one entry should be selected for editing
266 if (m_xTargetsBox->get_selected_rows().size() > 1)
268 //Warn the user about multiple selections
269 std::unique_ptr<weld::MessageDialog> xBox(
270 Application::CreateMessageDialog(getDialog(), VclMessageType::Error, VclButtonsType::Ok,
271 SfxResId(STR_REDACTION_MULTI_EDIT)));
272 xBox->run();
273 return;
276 // Get the redaction target to be edited
277 RedactionTarget* pTarget
278 = reinterpret_cast<RedactionTarget*>(m_xTargetsBox->get_id(nSelectedRow).toInt64());
280 // Construct and run the edit target dialog
281 SfxAddTargetDialog aEditTargetDialog(getDialog(), pTarget->sName, pTarget->sType,
282 pTarget->sContent, pTarget->bCaseSensitive,
283 pTarget->bWholeWords);
285 bool bIncomplete;
288 bIncomplete = false;
290 if (aEditTargetDialog.run() != RET_OK)
291 return;
293 if (aEditTargetDialog.getName().isEmpty()
294 || aEditTargetDialog.getType() == RedactionTargetType::REDACTION_TARGET_UNKNOWN
295 || aEditTargetDialog.getContent().isEmpty())
297 bIncomplete = true;
298 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
299 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
300 SfxResId(STR_REDACTION_FIELDS_REQUIRED)));
301 xBox->run();
303 else if (aEditTargetDialog.getName() != pTarget->sName
304 && m_xTargetsBox->GetTargetByName(aEditTargetDialog.getName()))
306 bIncomplete = true;
307 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
308 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
309 SfxResId(STR_REDACTION_TARGET_NAME_CLASH)));
310 xBox->run();
313 } while (bIncomplete);
315 // Update the redaction target
316 pTarget->sName = aEditTargetDialog.getName();
317 pTarget->sType = aEditTargetDialog.getType();
318 pTarget->sContent = aEditTargetDialog.getContent();
319 pTarget->bCaseSensitive = aEditTargetDialog.isCaseSensitive();
320 pTarget->bWholeWords = aEditTargetDialog.isWholeWords();
322 // And sync the targets box row with the actual target data
323 m_xTargetsBox->setRowData(nSelectedRow, pTarget);
326 IMPL_LINK_NOARG(SfxAutoRedactDialog, DeleteHdl, weld::Button&, void)
328 std::vector<int> aSelectedRows = m_xTargetsBox->get_selected_rows();
330 //No selection, so nothing to delete
331 if (aSelectedRows.empty())
332 return;
334 if (aSelectedRows.size() > 1)
336 OUString sMsg(SfxResId(STR_REDACTION_MULTI_DELETE)
337 .replaceFirst("$(TARGETSCOUNT)", OUString::number(aSelectedRows.size())));
338 //Warn the user about multiple deletions
339 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
340 getDialog(), VclMessageType::Question, VclButtonsType::OkCancel, sMsg));
341 if (xBox->run() == RET_CANCEL)
342 return;
345 // After each delete, the indexes of the following items decrease by one.
346 int delta = 0;
347 for (const auto& i : aSelectedRows)
349 m_aTableTargets.erase(m_aTableTargets.begin() + (i - delta));
350 m_xTargetsBox->remove(i - delta++);
354 namespace
356 boost::property_tree::ptree redactionTargetToJSON(const RedactionTarget* pTarget)
358 boost::property_tree::ptree aNode;
359 aNode.put("sName", pTarget->sName.toUtf8().getStr());
360 aNode.put("eType", pTarget->sType);
361 aNode.put("sContent", pTarget->sContent.toUtf8().getStr());
362 aNode.put("bWholeWords", pTarget->bWholeWords);
363 aNode.put("bCaseSensitive", pTarget->bCaseSensitive);
364 aNode.put("nID", pTarget->nID);
366 return aNode;
369 RedactionTarget* JSONtoRedactionTarget(const boost::property_tree::ptree::value_type& rValue)
371 OUString sName = OUString::fromUtf8(rValue.second.get<std::string>("sName").c_str());
372 RedactionTargetType eType
373 = static_cast<RedactionTargetType>(atoi(rValue.second.get<std::string>("eType").c_str()));
374 OUString sContent = OUString::fromUtf8(rValue.second.get<std::string>("sContent").c_str());
375 bool bCaseSensitive
376 = OUString::fromUtf8(rValue.second.get<std::string>("bCaseSensitive").c_str()).toBoolean();
377 bool bWholeWords
378 = OUString::fromUtf8(rValue.second.get<std::string>("bWholeWords").c_str()).toBoolean();
379 sal_uInt32 nID = atoi(rValue.second.get<std::string>("nID").c_str());
381 RedactionTarget* pTarget
382 = new RedactionTarget({ sName, eType, sContent, bCaseSensitive, bWholeWords, nID });
384 return pTarget;
388 IMPL_LINK_NOARG(SfxAutoRedactDialog, LoadHdl, sfx2::FileDialogHelper*, void)
390 assert(m_pFileDlg);
392 OUString sTargetsFile;
393 if (ERRCODE_NONE == m_pFileDlg->GetError())
394 sTargetsFile = m_pFileDlg->GetPath();
396 if (sTargetsFile.isEmpty())
397 return;
399 OUString sSysPath;
400 osl::File::getSystemPathFromFileURL(sTargetsFile, sSysPath);
401 sTargetsFile = sSysPath;
403 weld::WaitObject aWaitObject(getDialog());
407 // Create path string, and read JSON from file
408 std::string sPathStr(OUStringToOString(sTargetsFile, RTL_TEXTENCODING_UTF8).getStr());
410 boost::property_tree::ptree aTargetsJSON;
412 boost::property_tree::read_json(sPathStr, aTargetsJSON);
414 // Clear the dialog
415 clearTargets();
417 // Recreate & add the targets to the dialog
418 for (const boost::property_tree::ptree::value_type& rValue :
419 aTargetsJSON.get_child("RedactionTargets"))
421 RedactionTarget* pTarget = JSONtoRedactionTarget(rValue);
422 addTarget(pTarget);
425 catch (css::uno::Exception& e)
427 SAL_WARN("sfx.doc",
428 "Exception caught while trying to load the targets JSON from file: " << e.Message);
429 return;
430 //TODO: Warn the user with a message box
434 IMPL_LINK_NOARG(SfxAutoRedactDialog, SaveHdl, sfx2::FileDialogHelper*, void)
436 assert(m_pFileDlg);
438 OUString sTargetsFile;
439 if (ERRCODE_NONE == m_pFileDlg->GetError())
440 sTargetsFile = m_pFileDlg->GetPath();
442 if (sTargetsFile.isEmpty())
443 return;
445 OUString sSysPath;
446 osl::File::getSystemPathFromFileURL(sTargetsFile, sSysPath);
447 sTargetsFile = sSysPath;
449 weld::WaitObject aWaitObject(getDialog());
453 // Put the targets into a JSON array
454 boost::property_tree::ptree aTargetsArray;
455 for (const auto& targetPair : m_aTableTargets)
457 aTargetsArray.push_back(std::make_pair("", redactionTargetToJSON(targetPair.first)));
460 // Build the JSON tree
461 boost::property_tree::ptree aTargetsTree;
462 aTargetsTree.add_child("RedactionTargets", aTargetsArray);
464 // Create path string, and write JSON to file
465 std::string sPathStr(OUStringToOString(sTargetsFile, RTL_TEXTENCODING_UTF8).getStr());
467 boost::property_tree::write_json(sPathStr, aTargetsTree);
469 catch (css::uno::Exception& e)
471 SAL_WARN("sfx.doc",
472 "Exception caught while trying to save the targets JSON to file: " << e.Message);
473 return;
474 //TODO: Warn the user with a message box
478 void SfxAutoRedactDialog::StartFileDialog(StartFileDialogType nType, const OUString& rTitle)
480 OUString aFilterAllStr(SfxResId(STR_SFX_FILTERNAME_ALL));
481 OUString aFilterJsonStr(SfxResId(STR_REDACTION_JSON_FILE_FILTER));
483 bool bSave = nType == StartFileDialogType::SaveAs;
484 short nDialogType = bSave ? css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
485 : css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
486 m_pFileDlg.reset(new sfx2::FileDialogHelper(nDialogType, FileDialogFlags::NONE, getDialog()));
488 m_pFileDlg->SetTitle(rTitle);
489 m_pFileDlg->AddFilter(aFilterAllStr, FILEDIALOG_FILTER_ALL);
490 m_pFileDlg->AddFilter(aFilterJsonStr, FILEDIALOG_FILTER_JSON);
491 m_pFileDlg->SetCurrentFilter(aFilterJsonStr);
493 Link<sfx2::FileDialogHelper*, void> aDlgClosedLink
494 = bSave ? LINK(this, SfxAutoRedactDialog, SaveHdl)
495 : LINK(this, SfxAutoRedactDialog, LoadHdl);
496 m_pFileDlg->StartExecuteModal(aDlgClosedLink);
499 void SfxAutoRedactDialog::addTarget(RedactionTarget* pTarget)
501 // Only the visual/display part
502 m_xTargetsBox->InsertTarget(pTarget);
504 // Actually add to the targets vector
505 if (m_xTargetsBox->GetTargetByName(pTarget->sName))
506 m_aTableTargets.emplace_back(pTarget, pTarget->sName);
507 else
509 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
510 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
511 SfxResId(STR_REDACTION_TARGET_ADD_ERROR)));
512 xBox->run();
513 delete pTarget;
517 void SfxAutoRedactDialog::clearTargets()
519 // Clear the targets box
520 m_xTargetsBox->clear();
522 // Clear the targets vector
523 auto delTarget
524 = [](const std::pair<RedactionTarget*, OUString>& targetPair) { delete targetPair.first; };
526 std::for_each(m_aTableTargets.begin(), m_aTableTargets.end(), delTarget);
528 m_aTableTargets.clear();
531 SfxAutoRedactDialog::SfxAutoRedactDialog(weld::Window* pParent)
532 : SfxDialogController(pParent, "sfx/ui/autoredactdialog.ui", "AutoRedactDialog")
533 , m_bIsValidState(true)
534 , m_bTargetsCopied(false)
535 , m_xRedactionTargetsLabel(m_xBuilder->weld_label("labelRedactionTargets"))
536 , m_xTargetsBox(new TargetsTable(m_xBuilder->weld_tree_view("targets")))
537 , m_xLoadBtn(m_xBuilder->weld_button("btnLoadTargets"))
538 , m_xSaveBtn(m_xBuilder->weld_button("btnSaveTargets"))
539 , m_xAddBtn(m_xBuilder->weld_button("add"))
540 , m_xEditBtn(m_xBuilder->weld_button("edit"))
541 , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
543 // Can be used to remember the last set of redaction targets?
544 OUString sExtraData;
545 SvtViewOptions aDlgOpt(EViewType::Dialog,
546 OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
548 if (aDlgOpt.Exists())
550 css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem");
551 aUserItem >>= sExtraData;
554 // update the targets configuration if necessary
555 if (!sExtraData.isEmpty())
557 weld::WaitObject aWaitCursor(m_xDialog.get());
561 // Create path string, and read JSON from file
562 boost::property_tree::ptree aTargetsJSON;
563 std::stringstream aStream(std::string(sExtraData.toUtf8()));
565 boost::property_tree::read_json(aStream, aTargetsJSON);
567 // Recreate & add the targets to the dialog
568 for (const boost::property_tree::ptree::value_type& rValue :
569 aTargetsJSON.get_child("RedactionTargets"))
571 RedactionTarget* pTarget = JSONtoRedactionTarget(rValue);
572 addTarget(pTarget);
575 catch (css::uno::Exception& e)
577 SAL_WARN("sfx.doc",
578 "Exception caught while trying to load the last dialog state: " << e.Message);
579 return;
580 //TODO: Warn the user with a message box
584 // Handler connections
585 m_xLoadBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, Load));
586 m_xSaveBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, Save));
587 m_xAddBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, AddHdl));
588 m_xEditBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, EditHdl));
589 m_xDeleteBtn->connect_clicked(LINK(this, SfxAutoRedactDialog, DeleteHdl));
592 SfxAutoRedactDialog::~SfxAutoRedactDialog()
594 if (m_aTableTargets.empty())
596 // Clear the dialog data
597 SvtViewOptions aDlgOpt(EViewType::Dialog,
598 OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
599 aDlgOpt.Delete();
600 return;
605 // Put the targets into a JSON array
606 boost::property_tree::ptree aTargetsArray;
607 for (const auto& targetPair : m_aTableTargets)
609 aTargetsArray.push_back(std::make_pair("", redactionTargetToJSON(targetPair.first)));
612 // Build the JSON tree
613 boost::property_tree::ptree aTargetsTree;
614 aTargetsTree.add_child("RedactionTargets", aTargetsArray);
615 std::stringstream aStream;
617 boost::property_tree::write_json(aStream, aTargetsTree, false);
619 OUString sUserDataStr(OUString::fromUtf8(aStream.str().c_str()));
621 // Store the dialog data
622 SvtViewOptions aDlgOpt(EViewType::Dialog,
623 OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8));
624 aDlgOpt.SetUserItem("UserItem", css::uno::makeAny(sUserDataStr));
626 if (!m_bTargetsCopied)
627 clearTargets();
629 catch (css::uno::Exception& e)
631 SAL_WARN("sfx.doc",
632 "Exception caught while trying to store the dialog state: " << e.Message);
633 return;
634 //TODO: Warn the user with a message box
638 bool SfxAutoRedactDialog::hasTargets() const
640 //TODO: Add also some validity checks?
641 if (m_aTableTargets.empty())
642 return false;
644 return true;
647 bool SfxAutoRedactDialog::getTargets(std::vector<std::pair<RedactionTarget*, OUString>>& r_aTargets)
649 if (m_aTableTargets.empty())
650 return true;
652 r_aTargets = m_aTableTargets;
653 m_bTargetsCopied = true;
654 return true;
657 IMPL_LINK_NOARG(SfxAddTargetDialog, SelectTypeHdl, weld::ComboBox&, void)
659 if (m_xType->get_active_id() == "predefined")
661 // Hide the usual content widgets
662 // We will just set the id as content
663 // And handle with proper regex in the SfxRedactionHelper
664 m_xLabelContent->set_sensitive(false);
665 m_xLabelContent->set_visible(false);
666 m_xContent->set_sensitive(false);
667 m_xContent->set_visible(false);
668 m_xWholeWords->set_sensitive(false);
669 m_xWholeWords->set_visible(false);
670 m_xCaseSensitive->set_sensitive(false);
671 m_xCaseSensitive->set_visible(false);
673 // And show the predefined targets
674 m_xLabelPredefContent->set_sensitive(true);
675 m_xLabelPredefContent->set_visible(true);
676 m_xPredefContent->set_sensitive(true);
677 m_xPredefContent->set_visible(true);
679 else
681 m_xLabelPredefContent->set_sensitive(false);
682 m_xLabelPredefContent->set_visible(false);
683 m_xPredefContent->set_sensitive(false);
684 m_xPredefContent->set_visible(false);
686 m_xLabelContent->set_sensitive(true);
687 m_xLabelContent->set_visible(true);
688 m_xContent->set_sensitive(true);
689 m_xContent->set_visible(true);
690 m_xWholeWords->set_sensitive(true);
691 m_xWholeWords->set_visible(true);
692 m_xCaseSensitive->set_sensitive(true);
693 m_xCaseSensitive->set_visible(true);
697 SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& rName)
698 : GenericDialogController(pParent, "sfx/ui/addtargetdialog.ui", "AddTargetDialog")
699 , m_xName(m_xBuilder->weld_entry("name"))
700 , m_xType(m_xBuilder->weld_combo_box("type"))
701 , m_xLabelContent(m_xBuilder->weld_label("label_content"))
702 , m_xContent(m_xBuilder->weld_entry("content"))
703 , m_xLabelPredefContent(m_xBuilder->weld_label("label_content_predef"))
704 , m_xPredefContent(m_xBuilder->weld_combo_box("content_predef"))
705 , m_xCaseSensitive(m_xBuilder->weld_check_button("checkboxCaseSensitive"))
706 , m_xWholeWords(m_xBuilder->weld_check_button("checkboxWholeWords"))
708 m_xName->set_text(rName);
709 m_xName->select_region(0, rName.getLength());
711 m_xType->connect_changed(LINK(this, SfxAddTargetDialog, SelectTypeHdl));
714 SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& sName,
715 const RedactionTargetType& eTargetType,
716 const OUString& sContent, bool bCaseSensitive,
717 bool bWholeWords)
718 : GenericDialogController(pParent, "sfx/ui/addtargetdialog.ui", "AddTargetDialog")
719 , m_xName(m_xBuilder->weld_entry("name"))
720 , m_xType(m_xBuilder->weld_combo_box("type"))
721 , m_xLabelContent(m_xBuilder->weld_label("label_content"))
722 , m_xContent(m_xBuilder->weld_entry("content"))
723 , m_xLabelPredefContent(m_xBuilder->weld_label("label_content_predef"))
724 , m_xPredefContent(m_xBuilder->weld_combo_box("content_predef"))
725 , m_xCaseSensitive(m_xBuilder->weld_check_button("checkboxCaseSensitive"))
726 , m_xWholeWords(m_xBuilder->weld_check_button("checkboxWholeWords"))
728 m_xName->set_text(sName);
729 m_xName->select_region(0, sName.getLength());
731 m_xType->set_active_id(getTypeID(eTargetType));
732 m_xType->connect_changed(LINK(this, SfxAddTargetDialog, SelectTypeHdl));
734 if (eTargetType == RedactionTargetType::REDACTION_TARGET_PREDEFINED)
736 SelectTypeHdl(*m_xPredefContent);
737 m_xPredefContent->set_active(sContent.getToken(0, ';').toInt32());
739 else
741 m_xContent->set_text(sContent);
744 m_xCaseSensitive->set_active(bCaseSensitive);
745 m_xWholeWords->set_active(bWholeWords);
747 set_title(SfxResId(STR_REDACTION_EDIT_TARGET));
750 RedactionTargetType SfxAddTargetDialog::getType() const
752 OUString sTypeID = m_xType->get_active_id();
754 if (sTypeID == "text")
755 return RedactionTargetType::REDACTION_TARGET_TEXT;
756 else if (sTypeID == "regex")
757 return RedactionTargetType::REDACTION_TARGET_REGEX;
758 else if (sTypeID == "predefined")
759 return RedactionTargetType::REDACTION_TARGET_PREDEFINED;
760 else
761 return RedactionTargetType::REDACTION_TARGET_UNKNOWN;
764 OUString SfxAddTargetDialog::getContent() const
766 if (m_xType->get_active_id() == "predefined")
768 return OUString(OUString::number(m_xPredefContent->get_active()) + ";"
769 + m_xPredefContent->get_active_text());
772 return m_xContent->get_text();
775 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */