summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2016-02-12 07:12:07 -0400
committerHenry Castro <hcastro@collabora.com>2016-02-16 11:14:37 +0000
commit80d7c5859b9e7a834a915d7e8bbbe9bc2130108a (patch)
tree4cdc3cd73c1f8ed9d9523621e4594ecdc94caceb
parent3f7a0f7dba759ed3763c900112b5eeb7ccfdd84d (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.h12
-rw-r--r--sd/qa/unit/tiledrendering/data/insert-delete.odpbin0 -> 13178 bytes
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx128
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx4
-rw-r--r--sd/source/ui/slidesorter/model/SlideSorterModel.cxx36
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
new file mode 100644
index 000000000000..e388fb60b692
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/insert-delete.odp
Binary files differ
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)