diff options
author | Henry Castro <hcastro@collabora.com> | 2016-02-12 07:12:07 -0400 |
---|---|---|
committer | Henry Castro <hcastro@collabora.com> | 2016-02-16 11:14:37 +0000 |
commit | 80d7c5859b9e7a834a915d7e8bbbe9bc2130108a (patch) | |
tree | 4cdc3cd73c1f8ed9d9523621e4594ecdc94caceb | |
parent | 3f7a0f7dba759ed3763c900112b5eeb7ccfdd84d (diff) |
sd lok: add LOK_CALLBACK_PARTS_COUNT_CHANGED callback
In the tiled rendering case, when a slide is deleted or inserted
the sorted slides are updated on client side.
However, when .uno:Undo and .uno:Redo actions are requested on
client side the sorted slides are required to update all
sorted slides.
So every time when .uno:InsertPage, .uno:DeletePage, .uno:Undo, .uno:Redo
actions are requested, it will notify verbose action (PageInserted, PageDeleted)
with index on client side to update the sorted slide index.
Change-Id: Iebda2aa11be13aea8fbb6d0cc50442805d7485e9
Reviewed-on: https://gerrit.libreoffice.org/22309
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Henry Castro <hcastro@collabora.com>
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitEnums.h | 12 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/data/insert-delete.odp | bin | 0 -> 13178 bytes | |||
-rw-r--r-- | sd/qa/unit/tiledrendering/tiledrendering.cxx | 128 | ||||
-rw-r--r-- | sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx | 4 | ||||
-rw-r--r-- | sd/source/ui/slidesorter/model/SlideSorterModel.cxx | 36 |
5 files changed, 170 insertions, 10 deletions
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index 901bf6bcd9e6..e855b6ab9da7 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -280,6 +280,18 @@ typedef enum * } */ LOK_CALLBACK_ERROR, + + /** + * A part has been added to or removed from the document. + * + * { + * "action" : "PartInserted" | "PartDeleted" + * "part" : "Part Index" + * } + * + * Note: this is currently emitted by Impress. + */ + LOK_CALLBACK_PARTS_COUNT_CHANGED } LibreOfficeKitCallbackType; diff --git a/sd/qa/unit/tiledrendering/data/insert-delete.odp b/sd/qa/unit/tiledrendering/data/insert-delete.odp Binary files differnew file mode 100644 index 000000000000..e388fb60b692 --- /dev/null +++ b/sd/qa/unit/tiledrendering/data/insert-delete.odp diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 4bf086a9242b..770f03bd7b22 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -25,10 +25,14 @@ #include <svl/srchitem.hxx> #include <comphelper/lok.hxx> +#include <ImpressViewShellBase.hxx> +#include <SlideSorterViewShell.hxx> +#include <SlideSorter.hxx> #include <DrawDocShell.hxx> #include <ViewShell.hxx> #include <sdpage.hxx> #include <unomodel.hxx> +#include <drawdoc.hxx> using namespace css; @@ -44,6 +48,7 @@ public: virtual void tearDown() override; #if !defined(WNT) && !defined(MACOSX) + void testInsertPage(); void testRegisterCallback(); void testPostKeyEvent(); void testPostMouseEvent(); @@ -60,6 +65,7 @@ public: CPPUNIT_TEST_SUITE(SdTiledRenderingTest); #if !defined(WNT) && !defined(MACOSX) + CPPUNIT_TEST(testInsertPage); CPPUNIT_TEST(testRegisterCallback); CPPUNIT_TEST(testPostKeyEvent); CPPUNIT_TEST(testPostMouseEvent); @@ -90,6 +96,7 @@ private: sal_Int32 m_nPart; std::vector<OString> m_aSearchResultSelection; std::vector<int> m_aSearchResultPart; + std::vector<unsigned> m_aPageList; int m_nSelectionBeforeSearchResult; int m_nSelectionAfterSearchResult; #endif @@ -216,6 +223,19 @@ void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload) } } break; + case LOK_CALLBACK_PARTS_COUNT_CHANGED: + { + boost::property_tree::ptree aTree; + std::stringstream aStream(pPayload); + boost::property_tree::read_json(aStream, aTree); + auto aAction = aTree.get<std::string>("action", ""); + auto aPart = aTree.get<std::string>("part", ""); + if (!aAction.empty() && !aPart.empty()) + { + m_aPageList.push_back(std::atoi(aPart.data())); + } + } + break; } } @@ -499,6 +519,114 @@ void SdTiledRenderingTest::testSearchAllFollowedBySearch() CPPUNIT_ASSERT_EQUAL(OString("match"), pXImpressDocument->getTextSelection("text/plain;charset=utf-8", aUsedFormat)); } +void SdTiledRenderingTest::testInsertPage() +{ + uno::Sequence<beans::PropertyValue> aFilterOptions; + uno::Reference<frame::XDesktop2> xLoader(mxDesktop, uno::UNO_QUERY); + CPPUNIT_ASSERT(xLoader.is()); + + uno::Reference<lang::XComponent> xComponent; + xComponent = xLoader->loadComponentFromURL( + getURLFromSrc(DATA_DIRECTORY) + OUString("insert-delete.odp"), + "_blank", + 0, + aFilterOptions); + CPPUNIT_ASSERT(xComponent.is()); + + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + CPPUNIT_ASSERT(pFoundShell); + + ::sd::DrawDocShell* xDocSh = dynamic_cast<sd::DrawDocShell*>(pFoundShell); + CPPUNIT_ASSERT(xDocSh); + + sd::ViewShell* pViewShell = xDocSh->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + + sd::slidesorter::SlideSorterViewShell* pSSVS = nullptr; + for (int i = 0; i < 1000; i++) + { + // Process all Tasks - slide sorter is created here + while (Scheduler::ProcessTaskScheduling(true)); + if ((pSSVS = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase())) != nullptr) + break; + TimeValue aSleep(0, 100 * 1000000); // 100 msec + osl::Thread::wait(aSleep); + } + CPPUNIT_ASSERT(pSSVS); + + comphelper::LibreOfficeKit::setActive(); + SdXImpressDocument* pXImpressDocument = SdXImpressDocument::getImplementation(xDocSh->GetModel()); + CPPUNIT_ASSERT(pXImpressDocument); + SdDrawDocument *pDoc = pXImpressDocument->GetDocShell()->GetDoc(); + CPPUNIT_ASSERT(pDoc); + + // the document has 1 slide + CPPUNIT_ASSERT(pDoc->GetSdPageCount(PK_STANDARD) == 1); + + pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this); + + uno::Sequence<beans::PropertyValue> aArgs; + + // Insert slides + for(unsigned nIterator=1; nIterator <= 10; nIterator++) + comphelper::dispatchCommand(".uno:InsertPage", aArgs); + + // Verify inserted slides + for(unsigned nIterator=0; nIterator < m_aPageList.size(); nIterator++) + { + SdPage* pPage = pDoc->GetSdPage(m_aPageList[nIterator], PK_STANDARD); + CPPUNIT_ASSERT(pPage); + } + + m_aPageList.clear(); + + // Delete slides + for(unsigned nIterator=1; nIterator <= 10; nIterator++) + comphelper::dispatchCommand(".uno:DeletePage", aArgs); + + // Verify deleted slides + for(unsigned nIterator=0; nIterator < m_aPageList.size(); nIterator++) + { + SdPage* pPage = pDoc->GetSdPage(m_aPageList[nIterator], PK_STANDARD); + CPPUNIT_ASSERT(pPage == nullptr); + } + + m_aPageList.clear(); + + // Undo deleted slides + for(unsigned nIterator=1; nIterator <= 10; nIterator++) + comphelper::dispatchCommand(".uno:Undo", aArgs); + + // Verify inserted slides + for(unsigned nIterator=0; nIterator < m_aPageList.size(); nIterator++) + { + SdPage* pPage = pDoc->GetSdPage(m_aPageList[nIterator], PK_STANDARD); + CPPUNIT_ASSERT(pPage); + } + + m_aPageList.clear(); + + // Redo deleted slides + for(unsigned nIterator=1; nIterator <= 10; nIterator++) + comphelper::dispatchCommand(".uno:Redo", aArgs); + + // Verify deleted slides + for(unsigned nIterator=0; nIterator < m_aPageList.size(); nIterator++) + { + SdPage* pPage = pDoc->GetSdPage(m_aPageList[nIterator], PK_STANDARD); + CPPUNIT_ASSERT(pPage == nullptr); + } + + // the document has 1 slide + CPPUNIT_ASSERT(pDoc->GetSdPageCount(PK_STANDARD) == 1); + + comphelper::LibreOfficeKit::setActive(false); + + uno::Reference<util::XCloseable> xClose(xComponent, uno::UNO_QUERY); + CPPUNIT_ASSERT(xClose.is()); + xClose->close(false); +} + #endif CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx index 8f22b6ba4d3d..64b2a232d9af 100644 --- a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx +++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx @@ -219,8 +219,8 @@ private: void AdaptSize(); SdPage* GetPage (const sal_Int32 nCoreIndex) const; - void InsertSlide (SdPage* pPage); - void DeleteSlide (const SdPage* pPage); + sal_Int32 InsertSlide (SdPage* pPage); + sal_Int32 DeleteSlide (const SdPage* pPage); void UpdateIndices (const sal_Int32 nFirstIndex); }; diff --git a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx index 4d9ddfaf5e4c..8912d523c1ba 100644 --- a/sd/source/ui/slidesorter/model/SlideSorterModel.cxx +++ b/sd/source/ui/slidesorter/model/SlideSorterModel.cxx @@ -32,6 +32,7 @@ #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include "ViewShellBase.hxx" #include "DrawViewShell.hxx" @@ -41,6 +42,8 @@ #include "FrameView.hxx" #include <tools/diagnose_ex.h> +#include <boost/property_tree/json_parser.hpp> +#include <comphelper/lok.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -521,6 +524,7 @@ vcl::Region SlideSorterModel::RestoreSelection() bool SlideSorterModel::NotifyPageEvent (const SdrPage* pSdrPage) { ::osl::MutexGuard aGuard (maMutex); + sal_Int32 nIndex = -1; SdPage* pPage = const_cast<SdPage*>(dynamic_cast<const SdPage*>(pSdrPage)); if (pPage == nullptr) @@ -534,30 +538,42 @@ bool SlideSorterModel::NotifyPageEvent (const SdrPage* pSdrPage) return false; if (pPage->IsInserted()) - InsertSlide(pPage); + nIndex = InsertSlide(pPage); else - DeleteSlide(pPage); + nIndex = DeleteSlide(pPage); CheckModel(*this); + if (comphelper::LibreOfficeKit::isActive() && + nIndex != -1) + { + boost::property_tree::ptree aTree; + std::stringstream aStream; + aTree.put("action", pPage->IsInserted() ? "PartInserted" : "PartDeleted"); + aTree.put("part", OUString::number(nIndex).toUtf8().getStr()); + boost::property_tree::write_json(aStream, aTree); + const OString aPayload = aStream.str().c_str(); + GetDocument()->libreOfficeKitCallback(LOK_CALLBACK_PARTS_COUNT_CHANGED, aPayload.getStr()); + } + return true; } -void SlideSorterModel::InsertSlide (SdPage* pPage) +sal_Int32 SlideSorterModel::InsertSlide (SdPage* pPage) { // Find the index at which to insert the given page. sal_uInt16 nCoreIndex (pPage->GetPageNum()); sal_Int32 nIndex (FromCoreIndex(nCoreIndex)); if (pPage != GetPage(nIndex)) - return; + return -1; // Check that the pages in the document before and after the given page // are present in this model. if (nIndex>0) if (GetPage(nIndex-1) != GetPageDescriptor(nIndex-1)->GetPage()) - return; + return -1; if (size_t(nIndex)<maPageDescriptors.size()-1) if (GetPage(nIndex+1) != GetPageDescriptor(nIndex)->GetPage()) - return; + return -1; // Insert the given page at index nIndex maPageDescriptors.insert( @@ -570,9 +586,11 @@ void SlideSorterModel::InsertSlide (SdPage* pPage) // Update page indices. UpdateIndices(nIndex+1); + + return nIndex; } -void SlideSorterModel::DeleteSlide (const SdPage* pPage) +sal_Int32 SlideSorterModel::DeleteSlide (const SdPage* pPage) { sal_Int32 nIndex(0); @@ -599,11 +617,13 @@ void SlideSorterModel::DeleteSlide (const SdPage* pPage) { if (maPageDescriptors[nIndex]) if (maPageDescriptors[nIndex]->GetPage() != pPage) - return; + return -1; maPageDescriptors.erase(maPageDescriptors.begin()+nIndex); UpdateIndices(nIndex); } + + return nIndex; } void SlideSorterModel::UpdateIndices (const sal_Int32 nFirstIndex) |