diff options
author | Muhammet Kara <muhammet.kara@collabora.com> | 2019-06-13 18:32:27 +0300 |
---|---|---|
committer | Muhammet Kara <muhammet.kara@collabora.com> | 2019-06-14 20:14:44 +0200 |
commit | f8a325eff30b40fdd3f76d82d10b5eed8659afd2 (patch) | |
tree | 93205caaca554af56ce2365953de9264aa40df84 /sfx2/source | |
parent | b5323c72ff7e5bcde34089e49fe98e589dcc5acb (diff) |
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.kara@collabora.com>
Diffstat (limited to 'sfx2/source')
-rw-r--r-- | sfx2/source/doc/SfxRedactionHelper.cxx | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/sfx2/source/doc/SfxRedactionHelper.cxx b/sfx2/source/doc/SfxRedactionHelper.cxx index 413cf3b0a84d..244c5ababd26 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> @@ -116,7 +128,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; @@ -131,17 +143,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)); @@ -409,10 +420,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. @@ -424,22 +442,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); } } } @@ -486,14 +510,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: */ |