sfx2/inc/SfxRedactionHelper.hxx | 25 +++++++- sfx2/inc/autoredactdialog.hxx | 7 +- sfx2/source/doc/SfxRedactionHelper.cxx | 103 +++++++++++++++++++++++++++------ sfx2/source/doc/autoredactdialog.cxx | 89 +++++++++++++++++++++++++++- sfx2/uiconfig/ui/addtargetdialog.ui | 52 +++++++++++++++- 5 files changed, 249 insertions(+), 27 deletions(-)
New commits: commit 6afcbdf2fbe159eac03a86dfd76f5d8df4a41fe5 Author: Muhammet Kara <muhammet.k...@collabora.com> AuthorDate: Sat Jun 15 12:08:35 2019 +0300 Commit: Muhammet Kara <muhammet.k...@collabora.com> CommitDate: Mon Jun 17 23:31:30 2019 +0200 Add predefined targets to auto redaction Change-Id: Ib8cf8b50944667d6a87a5cafb6995ad195699358 Reviewed-on: https://gerrit.libreoffice.org/74092 Tested-by: Jenkins Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/74233 Tested-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/sfx2/inc/SfxRedactionHelper.hxx b/sfx2/inc/SfxRedactionHelper.hxx index 2f470386d2dc..ae72c39f4886 100644 --- a/sfx2/inc/SfxRedactionHelper.hxx +++ b/sfx2/inc/SfxRedactionHelper.hxx @@ -120,6 +120,20 @@ public: /// Fill the search options based on the given redaction target static void fillSearchOptions(i18nutil::SearchOptions2& rSearchOpt, const RedactionTarget* pTarget); + +private: + static constexpr OUStringLiteral m_aPredefinedTargets[6] = { + "\\b(?:\\d[ -]*?){13,16}\\b", //Credit card numbers + "\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b", //Email addresses + "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + "\\b", //IP addresses + "([12]\\d{3}[./-](0[1-9]|1[0-2])[./" + "-](0[1-9]|[12]\\d|3[01]))|((0[1-9]|[12]\\d|3[01])[./-](0[1-9]|1[0-2])[./" + "-][12]\\d{3})", //Dates (numerical) + "\\s*[a-zA-Z]{2}(?:\\s*\\d\\s*){6}[a-zA-Z]?\\s*", //National Insurance Number (UK) + "([1-9])(?!\\1{2}-\\1{2}-\\1{4})[1-9]{2}-[1-9]{2}-[1-9]{4}" //Social Security Number (US) + }; }; #endif // INCLUDED_CUI_SOURCE_INC_SFXREDACTIONHELPER_HXX diff --git a/sfx2/inc/autoredactdialog.hxx b/sfx2/inc/autoredactdialog.hxx index bab00cf536a3..2cec20cc64c8 100644 --- a/sfx2/inc/autoredactdialog.hxx +++ b/sfx2/inc/autoredactdialog.hxx @@ -155,10 +155,15 @@ class SfxAddTargetDialog : public weld::GenericDialogController private: std::unique_ptr<weld::Entry> m_xName; std::unique_ptr<weld::ComboBox> m_xType; + std::unique_ptr<weld::Label> m_xLabelContent; std::unique_ptr<weld::Entry> m_xContent; + std::unique_ptr<weld::Label> m_xLabelPredefContent; + std::unique_ptr<weld::ComboBox> m_xPredefContent; std::unique_ptr<weld::CheckButton> m_xCaseSensitive; std::unique_ptr<weld::CheckButton> m_xWholeWords; + DECL_LINK(SelectTypeHdl, weld::ComboBox&, void); + public: SfxAddTargetDialog(weld::Window* pWindow, const OUString& rName); SfxAddTargetDialog(weld::Window* pWindow, const OUString& sName, @@ -167,7 +172,7 @@ public: OUString getName() const { return m_xName->get_text(); } RedactionTargetType getType() const; - OUString getContent() const { return m_xContent->get_text(); } + OUString getContent() const; bool isCaseSensitive() const { return m_xCaseSensitive->get_state() == TriState::TRISTATE_TRUE; diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx index 75459d093ea9..6e602b048acf 100644 --- a/sfx2/source/doc/SfxRedactionHelper.cxx +++ b/sfx2/source/doc/SfxRedactionHelper.cxx @@ -531,7 +531,8 @@ void SfxRedactionHelper::fillSearchOptions(i18nutil::SearchOptions2& rSearchOpt, return; } - if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_REGEX) + if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_REGEX + || pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED) { rSearchOpt.algorithmType = util::SearchAlgorithms_REGEXP; rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::REGEXP; @@ -543,10 +544,20 @@ void SfxRedactionHelper::fillSearchOptions(i18nutil::SearchOptions2& rSearchOpt, } rSearchOpt.Locale = GetAppLanguageTag().getLocale(); - rSearchOpt.searchString = pTarget->sContent; + if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED) + { + sal_Int32 nPredefIndex = pTarget->sContent.getToken(0, ';').toInt32(); + //sal_Int32 nPredefIndex = sContent.toInt32(); + + rSearchOpt.searchString = m_aPredefinedTargets[nPredefIndex]; + } + else + rSearchOpt.searchString = pTarget->sContent; + rSearchOpt.replaceString.clear(); - if (!pTarget->bCaseSensitive && pTarget->sType != RedactionTargetType::REDACTION_TARGET_REGEX) + if (!pTarget->bCaseSensitive && pTarget->sType != RedactionTargetType::REDACTION_TARGET_REGEX + && pTarget->sType != RedactionTargetType::REDACTION_TARGET_PREDEFINED) rSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE; if (pTarget->bWholeWords) rSearchOpt.searchFlag |= util::SearchFlags::NORM_WORD_ONLY; diff --git a/sfx2/source/doc/autoredactdialog.cxx b/sfx2/source/doc/autoredactdialog.cxx index 73ec02cfc420..798ab965d831 100644 --- a/sfx2/source/doc/autoredactdialog.cxx +++ b/sfx2/source/doc/autoredactdialog.cxx @@ -128,11 +128,19 @@ void TargetsTable::InsertTarget(RedactionTarget* pTarget) pTarget->sName = GetNameProposal(); } + OUString sContent = pTarget->sContent; + + if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED) + { + //selection_num;selection_name + sContent = sContent.getToken(1, ';'); + } + // Add to the end int nRow = m_xControl->n_children(); m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(pTarget)), pTarget->sName); m_xControl->set_text(nRow, getTypeName(pTarget->sType), 1); - m_xControl->set_text(nRow, pTarget->sContent, 2); + m_xControl->set_text(nRow, sContent, 2); m_xControl->set_text(nRow, pTarget->bCaseSensitive ? OUString("Yes") : OUString("No"), 3); m_xControl->set_text(nRow, pTarget->bWholeWords ? OUString("Yes") : OUString("No"), 4); } @@ -176,9 +184,17 @@ OUString TargetsTable::GetNameProposal() void TargetsTable::setRowData(const int& nRowIndex, const RedactionTarget* pTarget) { + OUString sContent = pTarget->sContent; + + if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_PREDEFINED) + { + //selection_num;selection_name + sContent = sContent.getToken(1, ';'); + } + m_xControl->set_text(nRowIndex, pTarget->sName, 0); m_xControl->set_text(nRowIndex, getTypeName(pTarget->sType), 1); - m_xControl->set_text(nRowIndex, pTarget->sContent, 2); + m_xControl->set_text(nRowIndex, sContent, 2); m_xControl->set_text(nRowIndex, pTarget->bCaseSensitive ? OUString("Yes") : OUString("No"), 3); m_xControl->set_text(nRowIndex, pTarget->bWholeWords ? OUString("Yes") : OUString("No"), 4); } @@ -600,16 +616,61 @@ bool SfxAutoRedactDialog::moveTargets( return true; } +IMPL_LINK_NOARG(SfxAddTargetDialog, SelectTypeHdl, weld::ComboBox&, void) +{ + if (m_xType->get_active_id() == "predefined") + { + // Hide the usual content widgets + // We will just set the id as content + // And handle with proper regex in the SfxRedactionHelper + m_xLabelContent->set_sensitive(false); + m_xLabelContent->set_visible(false); + m_xContent->set_sensitive(false); + m_xContent->set_visible(false); + m_xWholeWords->set_sensitive(false); + m_xWholeWords->set_visible(false); + m_xCaseSensitive->set_sensitive(false); + m_xCaseSensitive->set_visible(false); + + // And show the predefined targets + m_xLabelPredefContent->set_sensitive(true); + m_xLabelPredefContent->set_visible(true); + m_xPredefContent->set_sensitive(true); + m_xPredefContent->set_visible(true); + } + else + { + m_xLabelPredefContent->set_sensitive(false); + m_xLabelPredefContent->set_visible(false); + m_xPredefContent->set_sensitive(false); + m_xPredefContent->set_visible(false); + + m_xLabelContent->set_sensitive(true); + m_xLabelContent->set_visible(true); + m_xContent->set_sensitive(true); + m_xContent->set_visible(true); + m_xWholeWords->set_sensitive(true); + m_xWholeWords->set_visible(true); + m_xCaseSensitive->set_sensitive(true); + m_xCaseSensitive->set_visible(true); + } +} + SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& rName) : GenericDialogController(pParent, "sfx/ui/addtargetdialog.ui", "AddTargetDialog") , m_xName(m_xBuilder->weld_entry("name")) , m_xType(m_xBuilder->weld_combo_box("type")) + , m_xLabelContent(m_xBuilder->weld_label("label_content")) , m_xContent(m_xBuilder->weld_entry("content")) + , m_xLabelPredefContent(m_xBuilder->weld_label("label_content_predef")) + , m_xPredefContent(m_xBuilder->weld_combo_box("content_predef")) , m_xCaseSensitive(m_xBuilder->weld_check_button("checkboxCaseSensitive")) , m_xWholeWords(m_xBuilder->weld_check_button("checkboxWholeWords")) { m_xName->set_text(rName); m_xName->select_region(0, rName.getLength()); + + m_xType->connect_changed(LINK(this, SfxAddTargetDialog, SelectTypeHdl)); } SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& sName, @@ -619,7 +680,10 @@ SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& sN : GenericDialogController(pParent, "sfx/ui/addtargetdialog.ui", "AddTargetDialog") , m_xName(m_xBuilder->weld_entry("name")) , m_xType(m_xBuilder->weld_combo_box("type")) + , m_xLabelContent(m_xBuilder->weld_label("label_content")) , m_xContent(m_xBuilder->weld_entry("content")) + , m_xLabelPredefContent(m_xBuilder->weld_label("label_content_predef")) + , m_xPredefContent(m_xBuilder->weld_combo_box("content_predef")) , m_xCaseSensitive(m_xBuilder->weld_check_button("checkboxCaseSensitive")) , m_xWholeWords(m_xBuilder->weld_check_button("checkboxWholeWords")) { @@ -628,7 +692,15 @@ SfxAddTargetDialog::SfxAddTargetDialog(weld::Window* pParent, const OUString& sN m_xType->set_active_id(getTypeID(eTargetType)); - m_xContent->set_text(sContent); + if (eTargetType == RedactionTargetType::REDACTION_TARGET_PREDEFINED) + { + SelectTypeHdl(*m_xPredefContent); + m_xPredefContent->set_active(sContent.getToken(0, ';').toInt32()); + } + else + { + m_xContent->set_text(sContent); + } m_xCaseSensitive->set_active(bCaseSensitive); m_xWholeWords->set_active(bWholeWords); @@ -650,4 +722,15 @@ RedactionTargetType SfxAddTargetDialog::getType() const return RedactionTargetType::REDACTION_TARGET_UNKNOWN; } +OUString SfxAddTargetDialog::getContent() const +{ + if (m_xType->get_active_id() == "predefined") + { + return OUString(OUString::number(m_xPredefContent->get_active()) + ";" + + m_xPredefContent->get_active_text()); + } + + return m_xContent->get_text(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sfx2/uiconfig/ui/addtargetdialog.ui b/sfx2/uiconfig/ui/addtargetdialog.ui index 3d45c7a240bd..d4283222fb65 100644 --- a/sfx2/uiconfig/ui/addtargetdialog.ui +++ b/sfx2/uiconfig/ui/addtargetdialog.ui @@ -24,8 +24,8 @@ <object class="GtkButtonBox"> <property name="can_focus">False</property> <child> - <object class="GtkButton" id="cancel"> - <property name="label">gtk-cancel</property> + <object class="GtkButton" id="close"> + <property name="label">gtk-ok</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -39,8 +39,8 @@ </packing> </child> <child> - <object class="GtkButton" id="close"> - <property name="label">gtk-ok</property> + <object class="GtkButton" id="cancel"> + <property name="label">gtk-cancel</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> @@ -145,6 +145,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="margin_left">2</property> + <property name="margin_bottom">2</property> <property name="activates_default">True</property> <accessibility> <relation type="labelled-by" target="label_content"/> @@ -159,6 +160,9 @@ <object class="GtkComboBoxText" id="type"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="margin_left">2</property> + <property name="margin_bottom">2</property> + <property name="active">0</property> <items> <item id="text" translatable="yes" context="addtargetdialog|type">Text</item> <item id="regex" translatable="yes" context="addtargetdialog|type">Regex</item> @@ -173,6 +177,44 @@ <property name="top_attach">1</property> </packing> </child> + <child> + <object class="GtkLabel" id="label_content_predef"> + <property name="sensitive">False</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="addtargetdialog|label_content_predef">Content:</property> + <property name="use_underline">True</property> + <accessibility> + <relation type="label-for" target="content_predef"/> + </accessibility> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkComboBoxText" id="content_predef"> + <property name="sensitive">False</property> + <property name="can_focus">False</property> + <property name="margin_left">2</property> + <property name="active">0</property> + <items> + <item id="creditcard" translatable="yes" context="addtargetdialog|content_predef">Credit card numbers</item> + <item id="email" translatable="yes" context="addtargetdialog|content_predef">Email addresses</item> + <item id="ip" translatable="yes" context="addtargetdialog|content_predef">IP addresses</item> + <item id="numdates" translatable="yes" context="addtargetdialog|content_predef">Dates (Numerical)</item> + <item id="uknin" translatable="yes" context="addtargetdialog|content_predef">National Insurance Number (UK)</item> + <item id="usssn" translatable="yes" context="addtargetdialog|content_predef">Social Security Number (US)</item> + </items> + <accessibility> + <relation type="labelled-by" target="label_content_predef"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> </object> <packing> <property name="expand">False</property> @@ -227,8 +269,8 @@ </object> </child> <action-widgets> - <action-widget response="-6">cancel</action-widget> <action-widget response="-5">close</action-widget> + <action-widget response="-6">cancel</action-widget> <action-widget response="-11">help</action-widget> </action-widgets> </object> commit 9c11b37f6c00cf3f52902089b4af151233879354 Author: Muhammet Kara <muhammet.k...@collabora.com> AuthorDate: Thu Jun 13 18:32:27 2019 +0300 Commit: Muhammet Kara <muhammet.k...@collabora.com> CommitDate: Mon Jun 17 23:31:15 2019 +0200 Use utl::TextSearch in the auto redaction process * Add support for: * Case sensitive and insensitive text search * Regex search (always case sensitive) regarless of the choice * Multiple occurences of the same target on a single TEXTARRAY Change-Id: I580059f77286e8c4226cafdd1eb9472f8e1a9a9d Reviewed-on: https://gerrit.libreoffice.org/74049 Tested-by: Jenkins Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/74232 Tested-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/sfx2/inc/SfxRedactionHelper.hxx b/sfx2/inc/SfxRedactionHelper.hxx index 9be54ca8ac22..2f470386d2dc 100644 --- a/sfx2/inc/SfxRedactionHelper.hxx +++ b/sfx2/inc/SfxRedactionHelper.hxx @@ -33,6 +33,11 @@ class DocumentToGraphicRenderer; class SfxViewFrame; struct RedactionTarget; +namespace i18nutil +{ +struct SearchOptions2; +} + struct PageMargins { // Page margins in mm100th @@ -92,7 +97,7 @@ public: * */ static PageMargins getPageMarginsForCalc(css::uno::Reference<css::frame::XModel>& xModel); - static void searchInMetaFile(const OUString& sSearchTerm, const GDIMetaFile& rMtf, + static void searchInMetaFile(const RedactionTarget* pRedactionTarget, const GDIMetaFile& rMtf, std::vector<tools::Rectangle>& aRedactionRectangles, uno::Reference<XComponent>& xComponent); @@ -111,6 +116,10 @@ public: const GDIMetaFile& rGDIMetaFile, uno::Reference<drawing::XDrawPage>& xPage, uno::Reference<XComponent>& xComponent); + + /// Fill the search options based on the given redaction target + static void fillSearchOptions(i18nutil::SearchOptions2& rSearchOpt, + const RedactionTarget* pTarget); }; #endif // INCLUDED_CUI_SOURCE_INC_SFXREDACTIONHELPER_HXX diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx index c5f015ea9d08..75459d093ea9 100644 --- a/sfx2/source/doc/SfxRedactionHelper.cxx +++ b/sfx2/source/doc/SfxRedactionHelper.cxx @@ -24,6 +24,18 @@ #include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <com/sun/star/sheet/XSpreadsheetView.hpp> +// Search util +#include <i18nutil/searchopt.hxx> +#include <com/sun/star/util/SearchAlgorithms.hpp> +#include <com/sun/star/util/SearchAlgorithms2.hpp> +#include <com/sun/star/util/SearchFlags.hpp> +#include <com/sun/star/util/SearchResult.hpp> +#include <unotools/configmgr.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <unotools/textsearch.hxx> + #include <sfx2/request.hxx> #include <sfx2/sfxsids.hrc> #include <sfx2/viewfrm.hxx> @@ -114,7 +126,7 @@ void setPageMargins(uno::Reference<beans::XPropertySet>& xPageProperySet, // #i10613# Extracted from ImplCheckRect::ImplCreate tools::Rectangle ImplCalcActionBounds(const MetaAction& rAct, const OutputDevice& rOut, - const OUString& sSubString, const sal_Int32& nStrPos) + const sal_Int32& nStrStartPos, const sal_Int32& nStrEndPos) { tools::Rectangle aActionBounds; @@ -129,17 +141,16 @@ tools::Rectangle ImplCalcActionBounds(const MetaAction& rAct, const OutputDevice { // #105987# ImplLayout takes everything in logical coordinates std::unique_ptr<SalLayout> pSalLayout1 = rOut.ImplLayout( - aString, 0, nStrPos, rTextAct.GetPoint(), 0, rTextAct.GetDXArray()); - std::unique_ptr<SalLayout> pSalLayout2 - = rOut.ImplLayout(aString, 0, nStrPos + sSubString.getLength(), - rTextAct.GetPoint(), 0, rTextAct.GetDXArray()); + aString, 0, nStrStartPos, rTextAct.GetPoint(), 0, rTextAct.GetDXArray()); + std::unique_ptr<SalLayout> pSalLayout2 = rOut.ImplLayout( + aString, 0, nStrEndPos, rTextAct.GetPoint(), 0, rTextAct.GetDXArray()); if (pSalLayout2) { tools::Rectangle aBoundRect2( const_cast<OutputDevice&>(rOut).ImplGetTextBoundRect(*pSalLayout2)); aActionBounds = rOut.PixelToLogic(aBoundRect2); } - if (pSalLayout1 && nStrPos > 0) + if (pSalLayout1 && nStrStartPos > 0) { tools::Rectangle aBoundRect1( const_cast<OutputDevice&>(rOut).ImplGetTextBoundRect(*pSalLayout1)); @@ -407,10 +418,17 @@ SfxRedactionHelper::getPageMarginsForCalc(css::uno::Reference<css::frame::XModel return aPageMargins; } -void SfxRedactionHelper::searchInMetaFile(const rtl::OUString& sSearchTerm, const GDIMetaFile& rMtf, +void SfxRedactionHelper::searchInMetaFile(const RedactionTarget* pRedactionTarget, + const GDIMetaFile& rMtf, std::vector<::tools::Rectangle>& aRedactionRectangles, uno::Reference<XComponent>& xComponent) { + // Initialize search + i18nutil::SearchOptions2 aSearchOptions; + fillSearchOptions(aSearchOptions, pRedactionTarget); + + utl::TextSearch textSearch(aSearchOptions); + MetaAction* pCurrAct; // Watch for TEXTARRAY actions. @@ -422,22 +440,28 @@ void SfxRedactionHelper::searchInMetaFile(const rtl::OUString& sSearchTerm, cons { MetaTextArrayAction* pMetaTextArrayAction = static_cast<MetaTextArrayAction*>(pCurrAct); - //sal_Int32 aIndex = pMetaTextArrayAction->GetIndex(); - //sal_Int32 aLength = pMetaTextArrayAction->GetLen(); - //Point aPoint = pMetaTextArrayAction->GetPoint(); + // Search operation takes place here OUString sText = pMetaTextArrayAction->GetText(); - sal_Int32 nFoundIndex = sText.indexOf(sSearchTerm); + sal_Int32 nStart = 0; + sal_Int32 nEnd = sText.getLength(); + + bool bFound = textSearch.SearchForward(sText, &nStart, &nEnd); // If found the string, add the corresponding rectangle to the collection - if (nFoundIndex >= 0) + while (bFound) { OutputDevice* pOutputDevice = SfxObjectShell::GetShellFromComponent(xComponent)->GetDocumentRefDev(); - tools::Rectangle aNewRect(ImplCalcActionBounds( - *pMetaTextArrayAction, *pOutputDevice, sSearchTerm, nFoundIndex)); + tools::Rectangle aNewRect( + ImplCalcActionBounds(*pMetaTextArrayAction, *pOutputDevice, nStart, nEnd)); if (!aNewRect.IsEmpty()) aRedactionRectangles.push_back(aNewRect); + + // Search for the next occurence + nStart = nEnd; + nEnd = sText.getLength(); + bFound = textSearch.SearchForward(sText, &nStart, &nEnd); } } } @@ -484,14 +508,48 @@ void SfxRedactionHelper::autoRedactPage(const RedactionTarget* pRedactionTarget, if (pRedactionTarget == nullptr || pRedactionTarget->sContent.isEmpty()) return; - OUString sContent(pRedactionTarget->sContent); - // Search for the redaction strings, and get the rectangle coordinates std::vector<::tools::Rectangle> aRedactionRectangles; - searchInMetaFile(sContent, rGDIMetaFile, aRedactionRectangles, xComponent); + searchInMetaFile(pRedactionTarget, rGDIMetaFile, aRedactionRectangles, xComponent); // Add the redaction rectangles to the page addRedactionRectToPage(xComponent, xPage, aRedactionRectangles); } +namespace +{ +const LanguageTag& GetAppLanguageTag() { return Application::GetSettings().GetLanguageTag(); } +} + +void SfxRedactionHelper::fillSearchOptions(i18nutil::SearchOptions2& rSearchOpt, + const RedactionTarget* pTarget) +{ + if (!pTarget) + { + SAL_WARN("sfx.doc", + "pTarget (pointer to Redactiontarget) is null. This should never happen."); + return; + } + + if (pTarget->sType == RedactionTargetType::REDACTION_TARGET_REGEX) + { + rSearchOpt.algorithmType = util::SearchAlgorithms_REGEXP; + rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::REGEXP; + } + else + { + rSearchOpt.algorithmType = util::SearchAlgorithms_ABSOLUTE; + rSearchOpt.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE; + } + + rSearchOpt.Locale = GetAppLanguageTag().getLocale(); + rSearchOpt.searchString = pTarget->sContent; + rSearchOpt.replaceString.clear(); + + if (!pTarget->bCaseSensitive && pTarget->sType != RedactionTargetType::REDACTION_TARGET_REGEX) + rSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE; + if (pTarget->bWholeWords) + rSearchOpt.searchFlag |= util::SearchFlags::NORM_WORD_ONLY; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits