diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2020-05-31 14:03:36 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2020-06-04 00:44:04 +0200 |
commit | 1f8a46ae50c6977add4c4116f114df3a58796be3 (patch) | |
tree | 9337187a45471757f839fa7c476f99b88ea5433d | |
parent | 7b2170f6239f0c4f16a1cbd3ec54a861405aa07a (diff) |
vcl: VectorGraphicSearch - support changing search string
Initial implementation only allowed to set the search string once.
This change allows to change the search string and still retain
the last position of a found string, so the search continues
from this positon forward or backwards. This mimicks how we search
through the GUI (which is the main use for this functionallity
anyway).
Change-Id: I8a7aee4b6b6525f483f105feaa1f83c4a0ad9594
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95460
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r-- | include/vcl/VectorGraphicSearch.hxx | 3 | ||||
-rw-r--r-- | vcl/qa/cppunit/VectorGraphicSearchTest.cxx | 33 | ||||
-rw-r--r-- | vcl/source/graphic/VectorGraphicSearch.cxx | 79 |
3 files changed, 86 insertions, 29 deletions
diff --git a/include/vcl/VectorGraphicSearch.hxx b/include/vcl/VectorGraphicSearch.hxx index 2dc8cca3b76a..c9faaa51f1c9 100644 --- a/include/vcl/VectorGraphicSearch.hxx +++ b/include/vcl/VectorGraphicSearch.hxx @@ -32,8 +32,7 @@ private: std::unique_ptr<Implementation> mpImplementation; Graphic maGraphic; - bool searchPDF(std::shared_ptr<VectorGraphicData> const& rData, OUString const& rSearchString, - SearchStartPosition eStartPosition); + bool searchPDF(std::shared_ptr<VectorGraphicData> const& rData); public: VectorGraphicSearch(Graphic const& rGraphic); diff --git a/vcl/qa/cppunit/VectorGraphicSearchTest.cxx b/vcl/qa/cppunit/VectorGraphicSearchTest.cxx index 5f65b4ba7e3d..8dbdcac0e2e1 100644 --- a/vcl/qa/cppunit/VectorGraphicSearchTest.cxx +++ b/vcl/qa/cppunit/VectorGraphicSearchTest.cxx @@ -27,10 +27,12 @@ class VectorGraphicSearchTest : public test::BootstrapFixtureBase void test(); void testNextPrevious(); + void testSearchStringChange(); CPPUNIT_TEST_SUITE(VectorGraphicSearchTest); CPPUNIT_TEST(test); CPPUNIT_TEST(testNextPrevious); + CPPUNIT_TEST(testSearchStringChange); CPPUNIT_TEST_SUITE_END(); }; @@ -160,6 +162,37 @@ void VectorGraphicSearchTest::testNextPrevious() } } +void VectorGraphicSearchTest::testSearchStringChange() +{ + OUString aURL = getFullUrl("Pangram.pdf"); + SvFileStream aStream(aURL, StreamMode::READ); + GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream); + aGraphic.makeAvailable(); + + VectorGraphicSearch aSearch(aGraphic); + + // Set search to "lazy" + CPPUNIT_ASSERT_EQUAL(true, aSearch.search("lazy")); + + CPPUNIT_ASSERT_EQUAL(true, aSearch.next()); + CPPUNIT_ASSERT_EQUAL(34, aSearch.index()); + + CPPUNIT_ASSERT_EQUAL(true, aSearch.next()); + CPPUNIT_ASSERT_EQUAL(817, aSearch.index()); + + // Change search to "fox" + CPPUNIT_ASSERT_EQUAL(true, aSearch.search("fox")); + + CPPUNIT_ASSERT_EQUAL(true, aSearch.next()); + CPPUNIT_ASSERT_EQUAL(822, aSearch.index()); + + // Change search to "Quick" + CPPUNIT_ASSERT_EQUAL(true, aSearch.search("Quick")); + CPPUNIT_ASSERT_EQUAL(true, aSearch.previous()); + CPPUNIT_ASSERT_EQUAL(784, aSearch.index()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(VectorGraphicSearchTest); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/graphic/VectorGraphicSearch.cxx b/vcl/source/graphic/VectorGraphicSearch.cxx index 635ed240307a..95064407f553 100644 --- a/vcl/source/graphic/VectorGraphicSearch.cxx +++ b/vcl/source/graphic/VectorGraphicSearch.cxx @@ -33,18 +33,18 @@ private: public: sal_Int32 mnPageIndex; + int mnCurrentIndex; OUString maSearchString; SearchStartPosition meStartPosition; - SearchContext(FPDF_DOCUMENT pPdfDocument, sal_Int32 nPageIndex, OUString const& rSearchString, - SearchStartPosition eStartPosition) + SearchContext(FPDF_DOCUMENT pPdfDocument, sal_Int32 nPageIndex) : mpPdfDocument(pPdfDocument) , mpPage(nullptr) , mpTextPage(nullptr) , mpSearchHandle(nullptr) , mnPageIndex(nPageIndex) - , maSearchString(rSearchString) - , meStartPosition(eStartPosition) + , mnCurrentIndex(-1) + , meStartPosition(SearchStartPosition::Begin) { } @@ -73,13 +73,30 @@ public: return aSize; } - bool initialize() + bool initialize(OUString const& rSearchString, SearchStartPosition eStartPosition) { if (!mpPdfDocument) return false; + + if (rSearchString == maSearchString) + return true; + + if (mpSearchHandle) + FPDFText_FindClose(mpSearchHandle); + + if (mpTextPage) + FPDFText_ClosePage(mpTextPage); + + if (mpPage) + FPDF_ClosePage(mpPage); + + maSearchString = rSearchString; + meStartPosition = eStartPosition; + mpPage = FPDF_LoadPage(mpPdfDocument, mnPageIndex); if (!mpPage) return false; + mpTextPage = FPDFText_LoadPage(mpPage); if (!mpTextPage) return false; @@ -89,6 +106,9 @@ public: // Index where to start to search. -1 => at the end int nStartIndex = meStartPosition == SearchStartPosition::End ? -1 : 0; + if (mnCurrentIndex >= 0) + nStartIndex = mnCurrentIndex; + // FPDF_MATCHCASE, FPDF_MATCHWHOLEWORD, FPDF_CONSECUTIVE // FPDF_MATCHCASE - If not set, it will not match case by default. // FPDF_MATCHWHOLEWORD - If not set, it will not match the whole word by default. @@ -102,15 +122,21 @@ public: bool next() { - if (mpSearchHandle) - return FPDFText_FindNext(mpSearchHandle); + if (mpSearchHandle && FPDFText_FindNext(mpSearchHandle)) + { + mnCurrentIndex = index(); + return true; + } return false; } bool previous() { - if (mpSearchHandle) - return FPDFText_FindPrev(mpSearchHandle); + if (mpSearchHandle && FPDFText_FindPrev(mpSearchHandle)) + { + mnCurrentIndex = index(); + return true; + } return false; } @@ -202,22 +228,24 @@ VectorGraphicSearch::~VectorGraphicSearch() { mpImplementation.reset(); } bool VectorGraphicSearch::search(OUString const& rSearchString, SearchStartPosition eStartPosition) { - auto pData = maGraphic.getVectorGraphicData(); - - if (pData && pData->getVectorGraphicDataType() == VectorGraphicDataType::Pdf) + if (!mpImplementation->mpSearchContext) { - return searchPDF(pData, rSearchString, eStartPosition); + auto pData = maGraphic.getVectorGraphicData(); + + if (pData && pData->getVectorGraphicDataType() == VectorGraphicDataType::Pdf) + { + if (searchPDF(pData)) + { + return mpImplementation->mpSearchContext->initialize(rSearchString, eStartPosition); + } + } + return false; } - return false; + return mpImplementation->mpSearchContext->initialize(rSearchString, eStartPosition); } -bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& rData, - OUString const& rSearchString, - SearchStartPosition eStartPosition) +bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& rData) { - if (rSearchString.isEmpty()) - return false; - mpImplementation->mpPdfDocument = FPDF_LoadMemDocument(rData->getVectorGraphicDataArray().getConstArray(), rData->getVectorGraphicDataArrayLength(), /*password=*/nullptr); @@ -249,10 +277,9 @@ bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& rD sal_Int32 nPageIndex = std::max(rData->getPageIndex(), sal_Int32(0)); - mpImplementation->mpSearchContext.reset(new SearchContext( - mpImplementation->mpPdfDocument, nPageIndex, rSearchString, eStartPosition)); - - return mpImplementation->mpSearchContext->initialize(); + mpImplementation->mpSearchContext.reset( + new SearchContext(mpImplementation->mpPdfDocument, nPageIndex)); + return true; } basegfx::B2DSize VectorGraphicSearch::pageSize() @@ -311,9 +338,7 @@ bool VectorGraphicSearch::search(OUString const& /*rSearchString*/, return false; } -bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& /*rData*/, - OUString const& /*rSearchString*/, - SearchStartPosition /*eStartPosition*/) +bool VectorGraphicSearch::searchPDF(std::shared_ptr<VectorGraphicData> const& /*rData*/) { return false; } |