desktop/qa/desktop_lib/test_desktop_lib.cxx | 38 ++++++++++++++++ desktop/source/lib/init.cxx | 7 ++- include/LibreOfficeKit/LibreOfficeKitEnums.h | 25 +++++++++++ include/sfx2/viewsh.hxx | 4 + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 19 +++++++- libreofficekit/source/gtk/lokdocview.cxx | 6 ++ sfx2/source/control/unoctitm.cxx | 3 - sfx2/source/view/viewimp.hxx | 2 sfx2/source/view/viewsh.cxx | 14 ++++++ sw/inc/unoprnms.hxx | 1 sw/inc/viewsh.hxx | 2 sw/qa/extras/tiledrendering/tiledrendering.cxx | 32 +++++++++++++- sw/source/core/doc/DocumentRedlineManager.cxx | 8 +-- sw/source/core/doc/docredln.cxx | 45 ++++++++++++++++++++ sw/source/core/inc/unoport.hxx | 3 + sw/source/core/unocore/unomapproperties.hxx | 1 sw/source/core/unocore/unoredline.cxx | 18 +++++--- sw/source/core/view/viewsh.cxx | 4 - sw/source/core/view/vnew.cxx | 2 sw/source/uibase/uiview/view2.cxx | 8 +++ 20 files changed, 220 insertions(+), 22 deletions(-)
New commits: commit a0c66852c3da76674510e8559e102bcc1efd0676 Author: Miklos Vajna <[email protected]> Date: Fri Aug 19 16:46:15 2016 +0200 sw redlines: expose description as part of the UNO/LOK API A redline can have a manual comment and also an autogenerated description, like "Insert 'abc'". Expose this later property as well, as it provides useful additional information, especially when the comment property is empty. Change-Id: Id0f0ff62aef58d96b9b6071706c6f5b4a0d74800 (cherry picked from commit 9e310a4705ce956551059040696166aefb2388cb) diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index ffacd4c..d715329 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -1203,6 +1203,10 @@ void DesktopLOKTest::testRedlineWriter() // Make sure that pressing a key creates exactly one redline. CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree.get_child("redlines").size()); + for (boost::property_tree::ptree::value_type& rRedline : aTree.get_child("redlines")) + // This failed with boost::property_tree::ptree_bad_path, as there were no description field. + CPPUNIT_ASSERT_EQUAL(std::string("Insert 't'"), rRedline.second.get<std::string>("description")); + comphelper::LibreOfficeKit::setActive(false); } diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 0a9f2b2..b18e4d6 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1858,6 +1858,10 @@ static char* getTrackedChanges(LibreOfficeKitDocument* pThis) xRedline->getPropertyValue("RedlineComment") >>= sComment; aRedline.put("comment", sComment.toUtf8().getStr()); + OUString sDescription; + xRedline->getPropertyValue("RedlineDescription") >>= sDescription; + aRedline.put("description", sDescription.toUtf8().getStr()); + util::DateTime aDateTime; xRedline->getPropertyValue("RedlineDateTime") >>= aDateTime; OUString sDateTime = utl::toISO8601(aDateTime); diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index 2c3bcab..0805e62 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -417,6 +417,7 @@ typedef enum * "author": "Unknown Author", * "type": "Delete", * "comment": "", + * "description": "Delete 'abc'", * "dateTime": "2016-08-18T12:14:00" * } * } diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx index 1d77918..a1833d2 100644 --- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx @@ -485,7 +485,7 @@ static void documentRedline(GtkWidget* pButton, gpointer /*pItem*/) GtkWidget* pContentArea = gtk_dialog_get_content_area(GTK_DIALOG (pDialog)); // Build the table. - GtkTreeStore* pTreeStore = gtk_tree_store_new(5, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + GtkTreeStore* pTreeStore = gtk_tree_store_new(6, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); for (const auto& rValue : aTree.get_child("redlines")) { GtkTreeIter aTreeIter; @@ -495,11 +495,12 @@ static void documentRedline(GtkWidget* pButton, gpointer /*pItem*/) 1, rValue.second.get<std::string>("author").c_str(), 2, rValue.second.get<std::string>("type").c_str(), 3, rValue.second.get<std::string>("comment").c_str(), - 4, rValue.second.get<std::string>("dateTime").c_str(), + 4, rValue.second.get<std::string>("description").c_str(), + 5, rValue.second.get<std::string>("dateTime").c_str(), -1); } GtkWidget* pTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(pTreeStore)); - std::vector<std::string> aColumns = {"Index", "Author", "Type", "Comment", "Timestamp"}; + std::vector<std::string> aColumns = {"Index", "Author", "Type", "Comment", "Description", "Timestamp"}; for (size_t nColumn = 0; nColumn < aColumns.size(); ++nColumn) { GtkCellRenderer* pRenderer = gtk_cell_renderer_text_new(); diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 63589f2..fa87f40 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -536,6 +536,7 @@ #define UNO_NAME_REDLINE_AUTHOR "RedlineAuthor" #define UNO_NAME_REDLINE_DATE_TIME "RedlineDateTime" #define UNO_NAME_REDLINE_COMMENT "RedlineComment" +#define UNO_NAME_REDLINE_DESCRIPTION "RedlineDescription" #define UNO_NAME_REDLINE_TYPE "RedlineType" #define UNO_NAME_REDLINE_SUCCESSOR_DATA "RedlineSuccessorData" #define UNO_NAME_REDLINE_IDENTIFIER "RedlineIdentifier" diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx index b7b1c8a..90c6875 100644 --- a/sw/source/core/doc/docredln.cxx +++ b/sw/source/core/doc/docredln.cxx @@ -310,6 +310,7 @@ static void lcl_RedlineNotification(bool bAdd, size_t nPos, SwRangeRedline* pRed aRedline.put("author", pRedline->GetAuthorString(1).toUtf8().getStr()); aRedline.put("type", SwRedlineTypeToOUString(pRedline->GetRedlineData().GetType()).toUtf8().getStr()); aRedline.put("comment", pRedline->GetRedlineData().GetComment().toUtf8().getStr()); + aRedline.put("description", pRedline->GetDescr().toUtf8().getStr()); OUString sDateTime = utl::toISO8601(pRedline->GetRedlineData().GetTimeStamp().GetUNODateTime()); aRedline.put("dateTime", sDateTime.toUtf8().getStr()); boost::property_tree::ptree aTree; @@ -1673,6 +1674,7 @@ void SwRangeRedline::dumpAsXml(xmlTextWriterPtr pWriter) const xmlTextWriterWriteAttribute(pWriter, BAD_CAST("id"), BAD_CAST(OString::number(GetSeqNo()).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("author"), BAD_CAST(SW_MOD()->GetRedlineAuthor(GetAuthor()).toUtf8().getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("date"), BAD_CAST(DateTimeToOString(GetTimeStamp()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("descr"), BAD_CAST(const_cast<SwRangeRedline*>(this)->GetDescr().toUtf8().getStr())); OString sRedlineType; switch (GetType()) diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx index f53ac89..20d0162 100644 --- a/sw/source/core/unocore/unomapproperties.hxx +++ b/sw/source/core/unocore/unomapproperties.hxx @@ -68,6 +68,7 @@ {OUString(UNO_NAME_REDLINE_AUTHOR), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_REDLINE_DATE_TIME), 0, cppu::UnoType<css::util::DateTime>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_REDLINE_COMMENT), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ + {OUString(UNO_NAME_REDLINE_DESCRIPTION), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID | PropertyAttribute::READONLY, 0}, \ {OUString(UNO_NAME_REDLINE_TYPE), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_REDLINE_SUCCESSOR_DATA), 0, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ {OUString(UNO_NAME_REDLINE_IDENTIFIER), 0, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID|PropertyAttribute::READONLY, 0},\ diff --git a/sw/source/core/unocore/unoredline.cxx b/sw/source/core/unocore/unoredline.cxx index 093d247..10ccc8a 100644 --- a/sw/source/core/unocore/unoredline.cxx +++ b/sw/source/core/unocore/unoredline.cxx @@ -287,6 +287,8 @@ uno::Any SwXRedlinePortion::GetPropertyValue( const OUString& rPropertyName, co } else if(rPropertyName == UNO_NAME_REDLINE_COMMENT) aRet <<= rRedline.GetComment(); + else if(rPropertyName == UNO_NAME_REDLINE_DESCRIPTION) + aRet <<= const_cast<SwRangeRedline&>(rRedline).GetDescr(); else if(rPropertyName == UNO_NAME_REDLINE_TYPE) { aRet <<= SwRedlineTypeToOUString(rRedline.GetType()); @@ -315,7 +317,7 @@ uno::Any SwXRedlinePortion::GetPropertyValue( const OUString& rPropertyName, co uno::Sequence< beans::PropertyValue > SwXRedlinePortion::CreateRedlineProperties( const SwRangeRedline& rRedline, bool bIsStart ) throw() { - uno::Sequence< beans::PropertyValue > aRet(11); + uno::Sequence< beans::PropertyValue > aRet(12); const SwRedlineData* pNext = rRedline.GetRedlineData().Next(); beans::PropertyValue* pRet = aRet.getArray(); @@ -326,6 +328,8 @@ uno::Sequence< beans::PropertyValue > SwXRedlinePortion::CreateRedlineProperties pRet[nPropIdx++].Value <<= rRedline.GetTimeStamp().GetUNODateTime(); pRet[nPropIdx].Name = UNO_NAME_REDLINE_COMMENT; pRet[nPropIdx++].Value <<= rRedline.GetComment(); + pRet[nPropIdx].Name = UNO_NAME_REDLINE_DESCRIPTION; + pRet[nPropIdx++].Value <<= const_cast<SwRangeRedline&>(rRedline).GetDescr(); pRet[nPropIdx].Name = UNO_NAME_REDLINE_TYPE; pRet[nPropIdx++].Value <<= SwRedlineTypeToOUString(rRedline.GetType()); pRet[nPropIdx].Name = UNO_NAME_REDLINE_IDENTIFIER; @@ -401,6 +405,10 @@ void SwXRedline::setPropertyValue( const OUString& rPropertyName, const uno::Any OUString sTmp; aValue >>= sTmp; pRedline->SetComment(sTmp); } + else if(rPropertyName == UNO_NAME_REDLINE_DESCRIPTION) + { + SAL_WARN("sw.uno", "SwXRedline::setPropertyValue: can't set Description"); + } else if(rPropertyName == UNO_NAME_REDLINE_TYPE) { OSL_FAIL("currently not available"); commit 1e36a15754acb0debe7e0297ebd02a757c4e548f Author: Miklos Vajna <[email protected]> Date: Fri Aug 19 15:27:59 2016 +0200 sw lok: add callbacks for redline table insertion / removal An alternative would be to follow the Manage Changes dialog approach and subscribe to the SFX_HINT_DOCCHANGED notification in SwDocShell, cache the old redline table and find out the differences to the current one, but that way sound much more complex without benefits. (cherry picked from commit 0bc553f3ef3c188a96ea4875f4722ad4d40da4a3) Conflicts: sw/source/core/doc/docredln.cxx Change-Id: I20a45285b88255ccea9d6646c0b5288ac1c91879 diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h index 651e9bc..2c3bcab 100644 --- a/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -406,6 +406,30 @@ typedef enum */ LOK_CALLBACK_VIEW_LOCK, + /** + * The size of the change tracking table has changed. + * + * The payload example: + * { + * "redline": { + * "action": "Remove", + * "index": "1", + * "author": "Unknown Author", + * "type": "Delete", + * "comment": "", + * "dateTime": "2016-08-18T12:14:00" + * } + * } + * + * The format is the same as an entry of + * lok::Document::getCommandValues('.uno:AcceptTrackedChanges'), extra + * fields: + * + * - 'action' is either 'Add' or 'Remove', depending on if this is an + * insertion into the table or a removal. + */ + LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED, + } LibreOfficeKitCallbackType; diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index f3dbc6a..3c8640f 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -417,6 +417,8 @@ callbackTypeToString (int nType) return "LOK_CALLBACK_CELL_FORMULA"; case LOK_CALLBACK_VIEW_LOCK: return "LOK_CALLBACK_VIEW_LOCK"; + case LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED: + return "LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED"; } g_assert(false); return nullptr; @@ -1324,6 +1326,10 @@ callback (gpointer pData) gtk_widget_queue_draw(GTK_WIDGET(pDocView)); break; } + case LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED: + { + break; + } default: g_assert(false); break; diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 8cc2977..e5d6f24 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -69,6 +69,7 @@ public: void testShapeTextUndoShells(); void testShapeTextUndoGroupShells(); void testTrackChanges(); + void testTrackChangesCallback(); CPPUNIT_TEST_SUITE(SwTiledRenderingTest); CPPUNIT_TEST(testRegisterCallback); @@ -102,6 +103,7 @@ public: CPPUNIT_TEST(testShapeTextUndoShells); CPPUNIT_TEST(testShapeTextUndoGroupShells); CPPUNIT_TEST(testTrackChanges); + CPPUNIT_TEST(testTrackChangesCallback); CPPUNIT_TEST_SUITE_END(); private: @@ -117,13 +119,15 @@ private: int m_nSelectionBeforeSearchResult; int m_nSelectionAfterSearchResult; int m_nInvalidations; + int m_nRedlineTableSizeChanged; }; SwTiledRenderingTest::SwTiledRenderingTest() : m_bFound(true), m_nSelectionBeforeSearchResult(0), m_nSelectionAfterSearchResult(0), - m_nInvalidations(0) + m_nInvalidations(0), + m_nRedlineTableSizeChanged(0) { } @@ -197,6 +201,11 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) } } break; + case LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED: + { + ++m_nRedlineTableSizeChanged; + } + break; } } @@ -1170,6 +1179,27 @@ void SwTiledRenderingTest::testTrackChanges() comphelper::LibreOfficeKit::setActive(false); } +void SwTiledRenderingTest::testTrackChangesCallback() +{ + // Load a document. + comphelper::LibreOfficeKit::setActive(); + SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this); + + // Turn on track changes and type "x". + uno::Reference<beans::XPropertySet> xPropertySet(mxComponent, uno::UNO_QUERY); + xPropertySet->setPropertyValue("RecordChanges", uno::makeAny(true)); + m_nRedlineTableSizeChanged = 0; + pWrtShell->Insert("x"); + + // Assert that we get exactly one notification about the redline insert. + // This was 0, as LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED wasn't sent. + CPPUNIT_ASSERT_EQUAL(1, m_nRedlineTableSizeChanged); + + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx index df26133..b7b1c8a 100644 --- a/sw/source/core/doc/docredln.cxx +++ b/sw/source/core/doc/docredln.cxx @@ -18,6 +18,8 @@ */ #include <libxml/xmlwriter.h> +#include <boost/property_tree/json_parser.hpp> + #include <tools/datetimeutils.hxx> #include <hintids.hxx> #include <svl/itemiter.hxx> @@ -25,6 +27,10 @@ #include <editeng/colritem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/crossedoutitem.hxx> +#include <comphelper/lok.hxx> +#include <LibreOfficeKit/LibreOfficeKitEnums.h> +#include <unotools/datetime.hxx> +#include <sfx2/viewsh.hxx> #include <swmodule.hxx> #include <doc.hxx> #include <docredln.hxx> @@ -47,6 +53,7 @@ #include <rootfrm.hxx> #include <comcore.hrc> +#include <unoport.hxx> using namespace com::sun::star; @@ -291,12 +298,42 @@ bool SwExtraRedlineTable::DeleteTableCellRedline( SwDoc* pDoc, const SwTableBox& return bChg; } +/// Emits LOK notification about one addition / removal of a redline item. +static void lcl_RedlineNotification(bool bAdd, size_t nPos, SwRangeRedline* pRedline) +{ + if (!comphelper::LibreOfficeKit::isActive()) + return; + + boost::property_tree::ptree aRedline; + aRedline.put("action", (bAdd ? "Add" : "Remove")); + aRedline.put("index", nPos); + aRedline.put("author", pRedline->GetAuthorString(1).toUtf8().getStr()); + aRedline.put("type", SwRedlineTypeToOUString(pRedline->GetRedlineData().GetType()).toUtf8().getStr()); + aRedline.put("comment", pRedline->GetRedlineData().GetComment().toUtf8().getStr()); + OUString sDateTime = utl::toISO8601(pRedline->GetRedlineData().GetTimeStamp().GetUNODateTime()); + aRedline.put("dateTime", sDateTime.toUtf8().getStr()); + boost::property_tree::ptree aTree; + aTree.add_child("redline", aRedline); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + std::string aPayload = aStream.str(); + + SfxViewShell* pViewShell = SfxViewShell::GetFirst(); + while (pViewShell) + { + pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_REDLINE_TABLE_SIZE_CHANGED, aPayload.c_str()); + pViewShell = SfxViewShell::GetNext(*pViewShell); + } +} + + bool SwRedlineTable::Insert( SwRangeRedline* p, bool bIns ) { if( p->HasValidRange() ) { std::pair<vector_type::const_iterator, bool> rv = maVector.insert( p ); size_t nP = rv.first - begin(); + lcl_RedlineNotification(/*bAdd=*/true, nP, p); p->CallDisplayFunc(0, nP); return rv.second; } @@ -464,6 +501,7 @@ bool SwRedlineTable::Remove( const SwRangeRedline* p ) void SwRedlineTable::Remove( sal_uInt16 nP ) { + lcl_RedlineNotification(/*bAdd=*/false, nP, maVector[nP]); SwDoc* pDoc = nullptr; if( !nP && 1 == size() ) pDoc = maVector.front()->GetDoc(); @@ -487,8 +525,13 @@ void SwRedlineTable::DeleteAndDestroy( sal_uInt16 nP, sal_uInt16 nL ) if( !nP && nL && nL == size() ) pDoc = maVector.front()->GetDoc(); + size_t nCount = 0; for( vector_type::const_iterator it = maVector.begin() + nP; it != maVector.begin() + nP + nL; ++it ) + { + lcl_RedlineNotification(/*bAdd=*/false, nP + nCount, *it); delete *it; + ++nCount; + } maVector.erase( maVector.begin() + nP, maVector.begin() + nP + nL ); SwViewShell* pSh; diff --git a/sw/source/core/inc/unoport.hxx b/sw/source/core/inc/unoport.hxx index 8b9e724..1003448 100644 --- a/sw/source/core/inc/unoport.hxx +++ b/sw/source/core/inc/unoport.hxx @@ -42,6 +42,7 @@ #include <unocrsr.hxx> #include <calbck.hxx> #include <unobaseclass.hxx> +#include <IDocumentRedlineAccess.hxx> class SwFormatField; class SwFrameFormat; @@ -312,6 +313,8 @@ public: css::uno::RuntimeException, std::exception) override; }; +OUString SwRedlineTypeToOUString(RedlineType_t eType); + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/unocore/unoredline.cxx b/sw/source/core/unocore/unoredline.cxx index bd4d51ba..093d247 100644 --- a/sw/source/core/unocore/unoredline.cxx +++ b/sw/source/core/unocore/unoredline.cxx @@ -189,7 +189,7 @@ SwXRedlinePortion::~SwXRedlinePortion() { } -static OUString lcl_RedlineTypeToOUString(RedlineType_t eType) +OUString SwRedlineTypeToOUString(RedlineType_t eType) { OUString sRet; switch(eType & nsRedlineType_t::REDLINE_NO_FLAG_MASK) @@ -221,7 +221,7 @@ static uno::Sequence<beans::PropertyValue> lcl_GetSuccessorProperties(const SwRa pValues[2].Name = UNO_NAME_REDLINE_COMMENT; pValues[2].Value <<= pNext->GetComment(); pValues[3].Name = UNO_NAME_REDLINE_TYPE; - pValues[3].Value <<= lcl_RedlineTypeToOUString(pNext->GetType()); + pValues[3].Value <<= SwRedlineTypeToOUString(pNext->GetType()); } return aValues; } @@ -289,7 +289,7 @@ uno::Any SwXRedlinePortion::GetPropertyValue( const OUString& rPropertyName, co aRet <<= rRedline.GetComment(); else if(rPropertyName == UNO_NAME_REDLINE_TYPE) { - aRet <<= lcl_RedlineTypeToOUString(rRedline.GetType()); + aRet <<= SwRedlineTypeToOUString(rRedline.GetType()); } else if(rPropertyName == UNO_NAME_REDLINE_SUCCESSOR_DATA) { @@ -327,7 +327,7 @@ uno::Sequence< beans::PropertyValue > SwXRedlinePortion::CreateRedlineProperties pRet[nPropIdx].Name = UNO_NAME_REDLINE_COMMENT; pRet[nPropIdx++].Value <<= rRedline.GetComment(); pRet[nPropIdx].Name = UNO_NAME_REDLINE_TYPE; - pRet[nPropIdx++].Value <<= lcl_RedlineTypeToOUString(rRedline.GetType()); + pRet[nPropIdx++].Value <<= SwRedlineTypeToOUString(rRedline.GetType()); pRet[nPropIdx].Name = UNO_NAME_REDLINE_IDENTIFIER; pRet[nPropIdx++].Value <<= OUString::number( sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(&rRedline) ) ); commit 9f883783a6a5f52ab18d96d9fd412776987fffe5 Author: Miklos Vajna <[email protected]> Date: Fri Aug 19 11:10:43 2016 +0200 sw: remove never read SwViewShell::mbInLibreOfficeKitCallback This was read in the now removed SwViewShell::libreOfficeKitCallback(), so add a similar flag to SfxViewShell instead, and restore the lost condition. This fixes paint/invalidation loops when inserting the first comment to a Writer document in gtktiledviewer. Reviewed-on: https://gerrit.libreoffice.org/28236 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins <[email protected]> (cherry picked from commit 8b4705e0e0c76503b1ca61cb567d222f49466fc5) Conflicts: sfx2/source/view/viewsh.cxx Change-Id: Iad5ef90848f3b309ef8db4553760dd36d9b8a37c diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index e4b21a2..0bda743 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -331,6 +331,10 @@ public: void setTiledSearching(bool bTiledSearching); /// Are we doing tiled searching? bool isTiledSearching() const; + /// Set if we are doing tiled painting. + void setTiledPainting(bool bTiledPainting); + /// Are we doing tiled painting? + bool isTiledPainting() const; /// See lok::Document::getPart(). virtual int getPart() const; virtual void dumpAsXml(struct _xmlTextWriter* pWriter) const; diff --git a/sfx2/source/view/viewimp.hxx b/sfx2/source/view/viewimp.hxx index 81f39e1..9c50b7d 100644 --- a/sfx2/source/view/viewimp.hxx +++ b/sfx2/source/view/viewimp.hxx @@ -66,6 +66,8 @@ struct SfxViewShell_Impl void* m_pLibreOfficeKitViewData; /// Set if we are in the middle of a tiled search. bool m_bTiledSearching; + /// Set if we are in the middle of a tiled paint. + bool m_bTiledPainting; static sal_uInt32 m_nLastViewShellId; const sal_uInt32 m_nViewShellId; diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index e711099..694ea7d6 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -316,6 +316,7 @@ SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags) , m_pLibreOfficeKitViewCallback(nullptr) , m_pLibreOfficeKitViewData(nullptr) , m_bTiledSearching(false) +, m_bTiledPainting(false) , m_nViewShellId(SfxViewShell_Impl::m_nLastViewShellId++) {} @@ -1620,6 +1621,9 @@ void SfxViewShell::registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCa void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const { + if (pImp->m_bTiledPainting) + return; + if (pImp->m_bTiledSearching) { switch (nType) @@ -1648,6 +1652,16 @@ bool SfxViewShell::isTiledSearching() const return pImp->m_bTiledSearching; } +void SfxViewShell::setTiledPainting(bool bTiledPainting) +{ + pImp->m_bTiledPainting = bTiledPainting; +} + +bool SfxViewShell::isTiledPainting() const +{ + return pImp->m_bTiledPainting; +} + int SfxViewShell::getPart() const { return 0; diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx index 1f54481..bb3bc8f 100644 --- a/sw/inc/viewsh.hxx +++ b/sw/inc/viewsh.hxx @@ -190,8 +190,6 @@ protected: sal_uInt16 mnLockPaint; ///< != 0 if Paint is locked. bool mbSelectAll; ///< Special select all mode: whole document selected, even if doc starts with table. - bool mbInLibreOfficeKitCallback; - /// The virtual device we paint to will end up on the screen. bool mbOutputToWindow; diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 1affa5d..2a518cd 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -1843,7 +1843,7 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex // TODO clean up SwViewShell's approach to output devices (the many of // them - mpBufferedOut, mpOut, mpWin, ...) OutputDevice *pSaveOut = mpOut; - mbInLibreOfficeKitCallback = true; + GetSfxViewShell()->setTiledPainting(true); mpOut = &rDevice; // resizes the virtual device so to contain the entries context @@ -1896,7 +1896,7 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex // SwViewShell's output device tear down mpOut = pSaveOut; - mbInLibreOfficeKitCallback = false; + GetSfxViewShell()->setTiledPainting(false); } void SwViewShell::SetBrowseBorder( const Size& rNew ) diff --git a/sw/source/core/view/vnew.cxx b/sw/source/core/view/vnew.cxx index 9bd1868..95f104e 100644 --- a/sw/source/core/view/vnew.cxx +++ b/sw/source/core/view/vnew.cxx @@ -171,7 +171,6 @@ SwViewShell::SwViewShell( SwDoc& rDocument, vcl::Window *pWindow, mnStartAction( 0 ), mnLockPaint( 0 ), mbSelectAll(false), - mbInLibreOfficeKitCallback(false), mbOutputToWindow(false), mpPrePostOutDev(nullptr), // #i72754# maPrePostMapMode() @@ -251,7 +250,6 @@ SwViewShell::SwViewShell( SwViewShell& rShell, vcl::Window *pWindow, mnStartAction( 0 ), mnLockPaint( 0 ), mbSelectAll(false), - mbInLibreOfficeKitCallback(false), mbOutputToWindow(false), mpPrePostOutDev(nullptr), // #i72754# maPrePostMapMode() commit fc4340ba565d1aa7e008d78d5c07c1d424928abc Author: Miklos Vajna <[email protected]> Date: Fri Aug 19 11:11:28 2016 +0200 sw: fix indentation in DocumentRedlineManager::AppendRedline() Change-Id: I61cc418378ef6135c3da15cfa47b85fb422a7b34 (cherry picked from commit 0b95e19d257d2afc1ec161c712e213aedfd6ccbe) diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index c880293..34fe092 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -1178,9 +1178,9 @@ bool DocumentRedlineManager::AppendRedline( SwRangeRedline* pNewRedl, bool bCall pRedl->IsOwnRedline( *pNewRedl ) ) { - // Set to NONE, so that the Delete::Redo merges the Redline data correctly! - // The ShowMode needs to be retained! - meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)); + // Set to NONE, so that the Delete::Redo merges the Redline data correctly! + // The ShowMode needs to be retained! + meRedlineMode = (RedlineMode_t)(eOld & ~(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE)); switch( eCmpPos ) { case POS_EQUAL: @@ -1192,7 +1192,7 @@ bool DocumentRedlineManager::AppendRedline( SwRangeRedline* pNewRedl, bool bCall case POS_INSIDE: if( bCallDelete ) { - meRedlineMode = (RedlineMode_t)(meRedlineMode | nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES); + meRedlineMode = (RedlineMode_t)(meRedlineMode | nsRedlineMode_t::REDLINE_IGNOREDELETE_REDLINES); // DeleteAndJoin does not yield the // desired result if there is no paragraph to commit 2fa72bab4452a629fe6912d8278c5959cecfb454 Author: Miklos Vajna <[email protected]> Date: Fri Aug 19 09:58:33 2016 +0200 tdf#101592 sw: track changes state is doc-specific, not view-specific So update the bindings of all views after changing it. Reviewed-on: https://gerrit.libreoffice.org/28233 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins <[email protected]> (cherry picked from commit d890ec2f130188af9d998abf5968f06e7218b7a4) Conflicts: desktop/qa/desktop_lib/test_desktop_lib.cxx Change-Id: I5355f40ba27be521dcdf343b08305f3736979bbb diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 29b3d02..ffacd4c 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -30,6 +30,9 @@ #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <unotools/tempfile.hxx> #include <vcl/svapp.hxx> +#include <sfx2/viewsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/bindings.hxx> #include <lib/init.hxx> @@ -42,7 +45,8 @@ public: DesktopLOKTest() : UnoApiTest("/desktop/qa/data/"), m_nSelectionBeforeSearchResult(0), m_nSelectionAfterSearchResult(0), - m_bModified(false) + m_bModified(false), + m_nTrackChanges(0) { } @@ -93,6 +97,7 @@ public: void testContextMenuImpress(); void testNotificationCompression(); void testRedlineWriter(); + void testTrackChanges(); CPPUNIT_TEST_SUITE(DesktopLOKTest); CPPUNIT_TEST(testModifiedStatus); @@ -121,6 +126,7 @@ public: CPPUNIT_TEST(testContextMenuImpress); CPPUNIT_TEST(testNotificationCompression); CPPUNIT_TEST(testRedlineWriter); + CPPUNIT_TEST(testTrackChanges); CPPUNIT_TEST_SUITE_END(); uno::Reference<lang::XComponent> mxComponent; @@ -137,6 +143,7 @@ public: // for testModifiedStatus osl::Condition m_aStateChangedCondition; bool m_bModified; + int m_nTrackChanges; // for testContextMenu{Calc, Writer} osl::Condition m_aContextMenuCondition; @@ -226,6 +233,8 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload) m_bModified = aPayload.copy(aPrefix.getLength()).toBoolean(); m_aStateChangedCondition.set(); } + else if (aPayload.startsWith(".uno:TrackChanges=") && aPayload.endsWith("=true")) + ++m_nTrackChanges; } break; case LOK_CALLBACK_CONTEXT_MENU: @@ -793,6 +802,29 @@ void DesktopLOKTest::testModifiedStatus() comphelper::LibreOfficeKit::setActive(false); } +void DesktopLOKTest::testTrackChanges() +{ + // Load a document and create two views. + LibLibreOffice_Impl aOffice; + comphelper::LibreOfficeKit::setActive(); + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + pDocument->pClass->initializeForRendering(pDocument, nullptr); + pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); + pDocument->pClass->createView(pDocument); + pDocument->pClass->initializeForRendering(pDocument, nullptr); + pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); + Scheduler::ProcessEventsToIdle(); + + // Enable trak changes and assert that both views get notified. + m_nTrackChanges = 0; + pDocument->pClass->postUnoCommand(pDocument, ".uno:TrackChanges", nullptr, false); + Scheduler::ProcessEventsToIdle(); + // This was 1, only the active view was notified. + CPPUNIT_ASSERT_EQUAL(2, m_nTrackChanges); + + comphelper::LibreOfficeKit::setActive(false); +} + void DesktopLOKTest::testSheetOperations() { comphelper::LibreOfficeKit::setActive(); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index cc2ab9f..0a9f2b2 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1046,7 +1046,8 @@ static void doc_iniUnoCommands () OUString(".uno:NumberFormatPercent"), OUString(".uno:NumberFormatDate"), OUString(".uno:SortAscending"), - OUString(".uno:SortDescending") + OUString(".uno:SortDescending"), + OUString(".uno:TrackChanges"), }; util::URL aCommandURL; diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx index 9e369f4..1d77918 100644 --- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx @@ -116,6 +116,7 @@ public: GtkToolItem* m_pJustifypara; GtkToolItem* m_pInsertAnnotation; GtkToolItem* m_pDeleteComment; + GtkToolItem* m_pTrackChanges; GtkWidget* m_pFormulabarEntry; GtkWidget* m_pScrolledWindow; std::map<GtkToolItem*, std::string> m_aToolItemCommandNames; @@ -165,6 +166,7 @@ public: m_pJustifypara(nullptr), m_pInsertAnnotation(nullptr), m_pDeleteComment(nullptr), + m_pTrackChanges(nullptr), m_pFormulabarEntry(nullptr), m_pScrolledWindow(nullptr), m_bToolItemBroadcast(true), @@ -1117,6 +1119,7 @@ static void signalEdit(LOKDocView* pLOKDocView, gboolean bWasEdit, gpointer /*pD setSensitiveIfInEdit(rWindow.m_pRedo, bEdit, rWindow); setSensitiveIfInEdit(rWindow.m_pPasteButton, bEdit, rWindow); setSensitiveIfInEdit(rWindow.m_pSaveButton, bEdit, rWindow); + setSensitiveIfInEdit(rWindow.m_pTrackChanges, bEdit, rWindow); } /// LOKDocView changed command state -> inform the tool button. @@ -1709,6 +1712,15 @@ static GtkWidget* createWindow(TiledWindow& rWindow) lcl_registerToolItem(rWindow, rWindow.m_pDeleteComment, ".uno:DeleteComment"); gtk_widget_set_sensitive(GTK_WIDGET(rWindow.m_pDeleteComment), false); + // Track changes + rWindow.m_pTrackChanges = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pTrackChanges), "media-record-symbolic"); + gtk_tool_item_set_tooltip_text(rWindow.m_pTrackChanges, "Track Changes"); + gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pTrackChanges, -1); + g_signal_connect(G_OBJECT(rWindow.m_pTrackChanges), "toggled", G_CALLBACK(toggleToolItem), nullptr); + lcl_registerToolItem(rWindow, rWindow.m_pTrackChanges, ".uno:TrackChanges"); + gtk_widget_set_sensitive(GTK_WIDGET(rWindow.m_pTrackChanges), false); + // Formula bar GtkToolItem* pFormulaEntryContainer = gtk_tool_item_new(); rWindow.m_pFormulabarEntry = gtk_entry_new(); diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx index face827..77a86ba 100644 --- a/sfx2/source/control/unoctitm.cxx +++ b/sfx2/source/control/unoctitm.cxx @@ -1120,7 +1120,8 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c aEvent.FeatureURL.Path == "SuperScript" || aEvent.FeatureURL.Path == "Strikeout" || aEvent.FeatureURL.Path == "Underline" || - aEvent.FeatureURL.Path == "ModifiedStatus") + aEvent.FeatureURL.Path == "ModifiedStatus" || + aEvent.FeatureURL.Path == "TrackChanges") { bool bTemp = false; aEvent.State >>= bTemp; diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index 69e7dc9..70dd0b3 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -604,6 +604,14 @@ void SwView::Execute(SfxRequest &rReq) ? nsRedlineMode_t::REDLINE_ON : 0; const sal_uInt16 nMode = m_pWrtShell->GetRedlineMode(); m_pWrtShell->SetRedlineModeAndCheckInsMode( (nMode & ~nsRedlineMode_t::REDLINE_ON) | nOn); + + // Notify all view shells of this document, as the track changes mode is document-global. + SwDocShell* pDocShell = GetDocShell(); + for (SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst(pDocShell); pViewFrame; pViewFrame = SfxViewFrame::GetNext(*pViewFrame, pDocShell)) + { + pViewFrame->GetBindings().Invalidate(FN_REDLINE_ON); + pViewFrame->GetBindings().Update(FN_REDLINE_ON); + } } } break; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
