14#include <sfx2/strings.hrc>
16#include <osl/file.hxx>
23#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
25#include <boost/property_tree/json_parser.hpp>
46 std::vector<int> aWidths{ 100, 50, 200, 105, 105 };
48 m_xControl->set_selection_mode(SelectionMode::Multiple);
55 OUString sTypeName(
SfxResId(STR_REDACTION_TARGET_TYPE_UNKNOWN));
60 sTypeName =
SfxResId(STR_REDACTION_TARGET_TYPE_TEXT);
63 sTypeName =
SfxResId(STR_REDACTION_TARGET_TYPE_REGEX);
66 sTypeName =
SfxResId(STR_REDACTION_TARGET_TYPE_PREDEF);
69 sTypeName =
SfxResId(STR_REDACTION_TARGET_TYPE_UNKNOWN);
79 OUString sTypeID(
"unknown");
90 sTypeID =
"predefined";
105 SAL_WARN(
"sfx.doc",
"pTarget is null in TargetsTable::InsertTarget()");
115 OUString sContent = pTarget->
sContent;
120 sContent = sContent.getToken(1,
';');
141 return weld::fromId<RedactionTarget*>(
m_xControl->get_id(nEntry));
146 OUString sDefaultTargetName(
SfxResId(STR_REDACTION_TARGET));
147 sal_Int32 nHighestTargetId = 0;
156 nHighestTargetId = std::max<sal_Int32>(nHighestTargetId, nCurrTargetId);
159 return sDefaultTargetName +
" " + OUString::number(nHighestTargetId + 1);
164 OUString sContent = pTarget->
sContent;
169 sContent = sContent.getToken(1,
';');
187 StartFileDialog(StartFileDialogType::Open,
SfxResId(STR_REDACTION_LOAD_TARGETS));
193 StartFileDialog(StartFileDialogType::SaveAs,
SfxResId(STR_REDACTION_SAVE_TARGETS));
209 if (aAddTargetDialog.
getName().isEmpty()
215 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
216 SfxResId(STR_REDACTION_FIELDS_REQUIRED)));
219 else if (m_aTargetsBox.GetTargetByName(aAddTargetDialog.
getName()))
223 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
224 SfxResId(STR_REDACTION_TARGET_NAME_CLASH)));
228 }
while (bIncomplete);
236 m_aTargetsBox.InsertTarget(redactiontarget);
239 if (m_aTargetsBox.GetTargetByName(redactiontarget->
sName))
240 m_aTableTargets.emplace_back(redactiontarget, redactiontarget->
sName);
244 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
245 SfxResId(STR_REDACTION_TARGET_ADD_ERROR)));
247 delete redactiontarget;
253 sal_Int32 nSelectedRow = m_aTargetsBox.get_selected_index();
256 if (nSelectedRow < 0)
260 if (m_aTargetsBox.get_selected_rows().size() > 1)
263 std::unique_ptr<weld::MessageDialog> xBox(
265 SfxResId(STR_REDACTION_MULTI_EDIT)));
271 RedactionTarget* pTarget = weld::fromId<RedactionTarget*>(m_aTargetsBox.get_id(nSelectedRow));
286 if (aEditTargetDialog.
getName().isEmpty()
292 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
293 SfxResId(STR_REDACTION_FIELDS_REQUIRED)));
297 && m_aTargetsBox.GetTargetByName(aEditTargetDialog.
getName()))
301 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
302 SfxResId(STR_REDACTION_TARGET_NAME_CLASH)));
306 }
while (bIncomplete);
316 m_aTargetsBox.setRowData(nSelectedRow, pTarget);
320 if (m_xEditBtn->get_sensitive())
321 m_xEditBtn->clicked();
326 std::vector<int> aSelectedRows = m_aTargetsBox.get_selected_rows();
329 if (aSelectedRows.empty())
332 if (aSelectedRows.size() > 1)
334 OUString sMsg(
SfxResId(STR_REDACTION_MULTI_DELETE)
335 .replaceFirst(
"$(TARGETSCOUNT)", OUString::number(aSelectedRows.size())));
338 getDialog(), VclMessageType::Question, VclButtonsType::OkCancel, sMsg));
345 for (
const auto&
i : aSelectedRows)
347 m_aTableTargets.erase(m_aTableTargets.begin() + (
i - delta));
348 m_aTargetsBox.remove(
i - delta++);
354boost::property_tree::ptree redactionTargetToJSON(
const RedactionTarget* pTarget)
356 boost::property_tree::ptree aNode;
357 aNode.put(
"sName", pTarget->
sName.toUtf8().getStr());
358 aNode.put(
"eType", pTarget->
sType);
359 aNode.put(
"sContent", pTarget->
sContent.toUtf8().getStr());
362 aNode.put(
"nID", pTarget->
nID);
367std::unique_ptr<RedactionTarget>
368JSONtoRedactionTarget(
const boost::property_tree::ptree::value_type& rValue)
370 OUString
sName = OUString::fromUtf8(rValue.second.get<std::string>(
"sName"));
373 OUString sContent = OUString::fromUtf8(rValue.second.get<std::string>(
"sContent"));
375 = OUString::fromUtf8(rValue.second.get<std::string>(
"bCaseSensitive")).toBoolean();
377 = OUString::fromUtf8(rValue.second.get<std::string>(
"bWholeWords")).toBoolean();
378 sal_uInt32 nID = atoi(rValue.second.get<std::string>(
"nID").c_str());
380 return std::unique_ptr<RedactionTarget>(
389 OUString sTargetsFile;
391 sTargetsFile = m_pFileDlg->GetPath();
393 if (sTargetsFile.isEmpty())
397 osl::File::getSystemPathFromFileURL(sTargetsFile, sSysPath);
398 sTargetsFile = sSysPath;
407 boost::property_tree::ptree aTargetsJSON;
409 boost::property_tree::read_json(sPathStr, aTargetsJSON);
415 for (
const boost::property_tree::ptree::value_type& rValue :
416 aTargetsJSON.get_child(
"RedactionTargets"))
418 addTarget(JSONtoRedactionTarget(rValue));
421 catch (css::uno::Exception& e)
424 "Exception caught while trying to load the targets JSON from file: " << e.Message);
434 OUString sTargetsFile;
436 sTargetsFile = m_pFileDlg->GetPath();
438 if (sTargetsFile.isEmpty())
442 osl::File::getSystemPathFromFileURL(sTargetsFile, sSysPath);
443 sTargetsFile = sSysPath;
450 boost::property_tree::ptree aTargetsArray;
451 for (
const auto& targetPair : m_aTableTargets)
453 aTargetsArray.push_back(
454 std::make_pair(
"", redactionTargetToJSON(targetPair.first.get())));
458 boost::property_tree::ptree aTargetsTree;
459 aTargetsTree.add_child(
"RedactionTargets", aTargetsArray);
464 boost::property_tree::write_json(sPathStr, aTargetsTree);
466 catch (css::uno::Exception& e)
469 "Exception caught while trying to save the targets JSON to file: " << e.Message);
477 OUString aFilterAllStr(
SfxResId(STR_SFX_FILTERNAME_ALL));
478 OUString aFilterJsonStr(
SfxResId(STR_REDACTION_JSON_FILE_FILTER));
480 bool bSave =
nType == StartFileDialogType::SaveAs;
481 short nDialogType = bSave ? css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
482 : css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
494 m_pFileDlg->StartExecuteModal(aDlgClosedLink);
503 auto name = pTarget->sName;
509 getDialog(), VclMessageType::Warning, VclButtonsType::Ok,
510 SfxResId(STR_REDACTION_TARGET_ADD_ERROR)));
526 , m_bIsValidState(true)
527 , m_bTargetsCopied(false)
528 , m_aTargetsBox(m_xBuilder->weld_tree_view(
"targets"))
529 , m_xLoadBtn(m_xBuilder->weld_button(
"btnLoadTargets"))
530 , m_xSaveBtn(m_xBuilder->weld_button(
"btnSaveTargets"))
531 , m_xAddBtn(m_xBuilder->weld_button(
"add"))
532 , m_xEditBtn(m_xBuilder->weld_button(
"edit"))
533 , m_xDeleteBtn(m_xBuilder->weld_button(
"delete"))
541 css::uno::Any aUserItem = aDlgOpt.
GetUserItem(
"UserItem");
542 aUserItem >>= sExtraData;
546 if (!sExtraData.isEmpty())
553 boost::property_tree::ptree aTargetsJSON;
554 std::stringstream aStream(std::string(sExtraData.toUtf8()));
556 boost::property_tree::read_json(aStream, aTargetsJSON);
559 for (
const boost::property_tree::ptree::value_type& rValue :
560 aTargetsJSON.get_child(
"RedactionTargets"))
562 addTarget(JSONtoRedactionTarget(rValue));
565 catch (css::uno::Exception& e)
568 "Exception caught while trying to load the last dialog state: " << e.Message);
596 boost::property_tree::ptree aTargetsArray;
599 aTargetsArray.push_back(
600 std::make_pair(
"", redactionTargetToJSON(targetPair.first.get())));
604 boost::property_tree::ptree aTargetsTree;
605 aTargetsTree.add_child(
"RedactionTargets", aTargetsArray);
606 std::stringstream aStream;
608 boost::property_tree::write_json(aStream, aTargetsTree,
false);
610 OUString sUserDataStr(OUString::fromUtf8(aStream.str()));
614 aDlgOpt.
SetUserItem(
"UserItem", css::uno::Any(sUserDataStr));
619 catch (css::uno::Exception& e)
622 "Exception caught while trying to store the dialog state: " << e.Message);
643 r_aTargets.push_back({ *rPair.first, rPair.second });
650 if (m_xType->get_active_id() ==
"predefined")
655 m_xLabelContent->set_sensitive(
false);
656 m_xLabelContent->set_visible(
false);
659 m_xWholeWords->set_sensitive(
false);
660 m_xWholeWords->set_visible(
false);
661 m_xCaseSensitive->set_sensitive(
false);
662 m_xCaseSensitive->set_visible(
false);
665 m_xLabelPredefContent->set_sensitive(
true);
666 m_xLabelPredefContent->set_visible(
true);
667 m_xPredefContent->set_sensitive(
true);
668 m_xPredefContent->set_visible(
true);
672 m_xLabelPredefContent->set_sensitive(
false);
673 m_xLabelPredefContent->set_visible(
false);
674 m_xPredefContent->set_sensitive(
false);
675 m_xPredefContent->set_visible(
false);
677 m_xLabelContent->set_sensitive(
true);
678 m_xLabelContent->set_visible(
true);
681 m_xWholeWords->set_sensitive(
true);
682 m_xWholeWords->set_visible(
true);
683 m_xCaseSensitive->set_sensitive(
true);
684 m_xCaseSensitive->set_visible(
true);
689 : GenericDialogController(pParent,
"sfx/ui/addtargetdialog.ui",
"AddTargetDialog")
690 , m_xName(m_xBuilder->weld_entry(
"name"))
691 , m_xType(m_xBuilder->weld_combo_box(
"type"))
692 , m_xLabelContent(m_xBuilder->weld_label(
"label_content"))
693 ,
m_xContent(m_xBuilder->weld_entry(
"content"))
694 , m_xLabelPredefContent(m_xBuilder->weld_label(
"label_content_predef"))
695 , m_xPredefContent(m_xBuilder->weld_combo_box(
"content_predef"))
696 , m_xCaseSensitive(m_xBuilder->weld_check_button(
"checkboxCaseSensitive"))
697 , m_xWholeWords(m_xBuilder->weld_check_button(
"checkboxWholeWords"))
700 m_xName->select_region(0, rName.getLength());
707 const OUString& sContent,
bool bCaseSensitive,
709 : GenericDialogController(pParent,
"sfx/ui/addtargetdialog.ui",
"AddTargetDialog")
710 , m_xName(m_xBuilder->weld_entry(
"name"))
711 , m_xType(m_xBuilder->weld_combo_box(
"type"))
712 , m_xLabelContent(m_xBuilder->weld_label(
"label_content"))
713 ,
m_xContent(m_xBuilder->weld_entry(
"content"))
714 , m_xLabelPredefContent(m_xBuilder->weld_label(
"label_content_predef"))
715 , m_xPredefContent(m_xBuilder->weld_combo_box(
"content_predef"))
716 , m_xCaseSensitive(m_xBuilder->weld_check_button(
"checkboxCaseSensitive"))
717 , m_xWholeWords(m_xBuilder->weld_check_button(
"checkboxWholeWords"))
722 m_xType->set_active_id(getTypeID(eTargetType));
743 OUString sTypeID =
m_xType->get_active_id();
745 if (sTypeID ==
"text")
747 else if (sTypeID ==
"regex")
749 else if (sTypeID ==
"predefined")
757 if (
m_xType->get_active_id() ==
"predefined")
uno::Reference< ucb::XContent > m_xContent
IMPL_LINK_NOARG(SfxAutoRedactDialog, Load, weld::Button &, void)
constexpr OUStringLiteral FILEDIALOG_FILTER_JSON
@ REDACTION_TARGET_UNKNOWN
@ REDACTION_TARGET_PREDEFINED
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
std::unique_ptr< weld::CheckButton > m_xCaseSensitive
std::unique_ptr< weld::Entry > m_xContent
std::unique_ptr< weld::ComboBox > m_xType
OUString getContent() const
RedactionTargetType getType() const
SfxAddTargetDialog(weld::Window *pWindow, const OUString &rName)
std::unique_ptr< weld::ComboBox > m_xPredefContent
bool isWholeWords() const
bool isCaseSensitive() const
std::unique_ptr< weld::Entry > m_xName
std::unique_ptr< weld::CheckButton > m_xWholeWords
std::unique_ptr< sfx2::FileDialogHelper > m_pFileDlg
void addTarget(std::unique_ptr< RedactionTarget > pTarget)
Carry out proper addition both to the targets box, and to the tabletargets vector.
std::vector< std::pair< std::unique_ptr< RedactionTarget >, OUString > > m_aTableTargets
void clearTargets()
Clear all targets both visually and from the targets vector.
std::unique_ptr< weld::Button > m_xEditBtn
std::unique_ptr< weld::Button > m_xSaveBtn
virtual ~SfxAutoRedactDialog() override
bool hasTargets() const
Check if the dialog has any valid redaction targets.
std::unique_ptr< weld::Button > m_xDeleteBtn
SfxAutoRedactDialog(weld::Window *pParent)
void StartFileDialog(StartFileDialogType nType, const OUString &rTitle)
TargetsTable m_aTargetsBox
bool getTargets(std::vector< std::pair< RedactionTarget, OUString > > &r_aTargets)
Copies targets vector Does a shallow copy.
std::unique_ptr< weld::Button > m_xAddBtn
std::unique_ptr< weld::Button > m_xLoadBtn
css::uno::Any GetUserItem(const OUString &sName) const
void SetUserItem(const OUString &sName, const css::uno::Any &aValue)
void connect_row_activated(const Link< weld::TreeView &, bool > &rLink)
std::unique_ptr< weld::TreeView > m_xControl
int GetRowByTargetName(std::u16string_view sName)
OUString GetNameProposal() const
void setRowData(int nRowIndex, const RedactionTarget *pTarget)
void InsertTarget(RedactionTarget *pTarget)
RedactionTarget * GetTargetByName(std::u16string_view sName)
TargetsTable(std::unique_ptr< weld::TreeView > xControl)
void set_title(const OUString &rTitle)
virtual Dialog * getDialog() override
std::shared_ptr< weld::Dialog > m_xDialog
constexpr OUStringLiteral FILEDIALOG_FILTER_ALL
#define LINK(Instance, Class, Member)
#define SAL_WARN(area, stream)
rtl::OUString getTypeName(rtl::OUString const &rEnvDcp)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
OUString toId(const void *pValue)
OUString SfxResId(TranslateId aId)
Keeps information for a single redaction target.
RedactionTargetType sType