summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2017-06-17 13:52:15 -0400
committerHenry Castro <hcastro@collabora.com>2017-12-07 19:14:18 +0100
commit6fd6e3c1d36d67002967f56e47255e360f4b08c1 (patch)
tree3d733efd3b054513590b211e209972f5328fd292
parented50a0a2ce51584fa3a8fba0094220a4bf25c650 (diff)
lokit: add .uno:DocumentRepair command
Change-Id: I5b13ea6f4785bc91c29111fa63c4a1b0ea9b2660 Reviewed-on: https://gerrit.libreoffice.org/38908 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Henry Castro <hcastro@collabora.com>
-rw-r--r--desktop/source/lib/init.cxx3
-rw-r--r--include/sfx2/sfxsids.hrc2
-rw-r--r--include/svl/hint.hxx1
-rw-r--r--include/svl/undo.hxx10
-rw-r--r--include/svx/sdrundomanager.hxx5
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx51
-rw-r--r--sc/source/core/data/document.cxx5
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx51
-rw-r--r--sd/source/ui/docshell/docshell.cxx5
-rw-r--r--sfx2/sdi/docslots.sdi4
-rw-r--r--sfx2/sdi/sfx.sdi19
-rw-r--r--sfx2/source/control/unoctitm.cxx3
-rw-r--r--sfx2/source/doc/objserv.cxx9
-rw-r--r--sfx2/source/view/viewfrm.cxx6
-rw-r--r--svl/source/undo/undo.cxx39
-rw-r--r--svx/source/svdraw/sdrundomanager.cxx16
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx48
-rw-r--r--sw/source/core/inc/UndoManager.hxx3
-rw-r--r--sw/source/core/undo/docundo.cxx8
19 files changed, 279 insertions, 9 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 2ea79a076e9a..51bcd2e34afb 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1747,7 +1747,8 @@ static void doc_iniUnoCommands ()
OUString(".uno:FontDialog"),
OUString(".uno:ParagraphDialog"),
OUString(".uno:OutlineBullet"),
- OUString(".uno:InsertIndexesEntry")
+ OUString(".uno:InsertIndexesEntry"),
+ OUString(".uno:DocumentRepair")
};
util::URL aCommandURL;
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index 043902f5b26a..7bac74572f8f 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -119,7 +119,7 @@
#define SID_FILE_FILTEROPTIONS (SID_SFX_START + 527)
#define SID_RELOAD (SID_SFX_START + 508)
#define SID_PRINTDOCDIRECT (SID_SFX_START + 509)
-// free (SID_SFX_START + 510)
+#define SID_DOC_REPAIR (SID_SFX_START + 510)
#define SID_DOC_SERVICE (SID_SFX_START + 511)
#define SID_PLUGIN_MODE (SID_SFX_START + 827)
#define SID_EXPORTDOC (SID_SFX_START + 829)
diff --git a/include/svl/hint.hxx b/include/svl/hint.hxx
index bce91f5462ae..4cee3ba569a9 100644
--- a/include/svl/hint.hxx
+++ b/include/svl/hint.hxx
@@ -35,6 +35,7 @@ enum class SfxHintId {
ColorsChanged,
LanguageChanged,
RedlineChanged,
+ DocumentRepair,
// VCL text hints
TextParaInserted,
diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx
index 7791d4a4b333..b0ee7e21f657 100644
--- a/include/svl/undo.hxx
+++ b/include/svl/undo.hxx
@@ -293,6 +293,7 @@ namespace svl
/// adds a new listener to be notified about changes in the UndoManager's state
virtual void AddUndoListener( SfxUndoListener& i_listener ) = 0;
virtual void RemoveUndoListener( SfxUndoListener& i_listener ) = 0;
+ virtual bool IsEmptyActions() const = 0;
};
}
@@ -343,6 +344,8 @@ public:
virtual bool IsUndoEnabled() const override;
virtual void AddUndoListener( SfxUndoListener& i_listener ) override;
virtual void RemoveUndoListener( SfxUndoListener& i_listener ) override;
+ virtual bool IsEmptyActions() const override;
+
/** marks the current top-level element of the Undo stack, and returns a unique ID for it
*/
@@ -379,6 +382,7 @@ protected:
undo actions on the then-current level are removed, too. This is continued until the top level is reached.
*/
void ClearAllLevels();
+ virtual void EmptyActionsChanged();
private:
size_t ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
@@ -391,8 +395,10 @@ private:
bool ImplIsInListAction_Lock() const;
void ImplEnableUndo_Lock( bool const i_enable );
- bool ImplUndo( SfxUndoContext* i_contextOrNull );
- bool ImplRedo( SfxUndoContext* i_contextOrNull );
+ bool ImplUndo( SfxUndoContext* i_contextOrNull );
+ bool ImplRedo( SfxUndoContext* i_contextOrNull );
+ void ImplCheckEmptyActions();
+ inline bool ImplIsEmptyActions() const;
friend class ::svl::undo::impl::LockGuard;
};
diff --git a/include/svx/sdrundomanager.hxx b/include/svx/sdrundomanager.hxx
index a42e57e60b36..df9ac0845827 100644
--- a/include/svx/sdrundomanager.hxx
+++ b/include/svx/sdrundomanager.hxx
@@ -24,6 +24,8 @@
#include <editeng/editund2.hxx>
#include <tools/link.hxx>
+class SfxObjectShell;
+
class SVX_DLLPUBLIC SdrUndoManager : public EditUndoManager
{
private:
@@ -35,8 +37,10 @@ private:
bool mbEndTextEditTriggeredFromUndo;
protected:
+ SfxObjectShell* m_pDocSh;
// call to check for TextEdit active
bool isTextEditActive() const;
+ virtual void EmptyActionsChanged() override;
public:
SdrUndoManager();
@@ -59,6 +63,7 @@ public:
// is needed to detect inside end text edit if it is a regular one or triggered
// by a last undo during text edit
bool isEndTextEditTriggeredFromUndo() { return mbEndTextEditTriggeredFromUndo; }
+ void SetDocShell(SfxObjectShell* pDocShell);
};
#endif // INCLUDED_SVX_SDRUNDOMANAGER_HXX
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index bc477a044e64..e2fc936bf269 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -85,6 +85,7 @@ public:
void testInsertGraphicInvalidations();
void testDocumentSizeWithTwoViews();
void testDisableUndoRepair();
+ void testDocumentRepair();
void testLanguageStatus();
CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
@@ -113,6 +114,7 @@ public:
CPPUNIT_TEST(testInsertGraphicInvalidations);
CPPUNIT_TEST(testDocumentSizeWithTwoViews);
CPPUNIT_TEST(testDisableUndoRepair);
+ CPPUNIT_TEST(testDocumentRepair);
CPPUNIT_TEST(testLanguageStatus);
CPPUNIT_TEST_SUITE_END();
@@ -1418,6 +1420,55 @@ void ScTiledRenderingTest::testDisableUndoRepair()
comphelper::LibreOfficeKit::setActive(false);
}
+void ScTiledRenderingTest::testDocumentRepair()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ // Create two views.
+ ScModelObj* pModelObj = createDoc("cursor-away.ods");
+ CPPUNIT_ASSERT(pModelObj);
+
+ // view #1
+ SfxViewShell* pView1 = SfxViewShell::Current();
+
+ // view #2
+ SfxLokHelper::createView();
+ SfxViewShell* pView2 = SfxViewShell::Current();
+ int nView2 = SfxLokHelper::getView();
+ CPPUNIT_ASSERT(pView1 != pView2);
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ // Insert a character in the second view.
+ SfxLokHelper::setView(nView2);
+ pModelObj->setPart(1);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN);
+ Scheduler::ProcessEventsToIdle();
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
void ScTiledRenderingTest::testLanguageStatus()
{
comphelper::LibreOfficeKit::setActive();
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 2d1834d57cd9..bc971f1b1c8f 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -6322,7 +6322,10 @@ SfxUndoManager* ScDocument::GetUndoManager()
{
// to support enhanced text edit for draw objects, use an SdrUndoManager
ScMutationGuard aGuard(this, ScMutationGuardFlags::CORE);
- mpUndoManager = new SdrUndoManager;
+
+ SdrUndoManager* pUndoManager = new SdrUndoManager;
+ pUndoManager->SetDocShell(GetDocumentShell());
+ mpUndoManager = pUndoManager;
}
return mpUndoManager;
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index b4110b79a4aa..24c4354217a8 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -104,6 +104,7 @@ public:
void testCommentCallbacks();
void testMultiViewInsertDeletePage();
void testDisableUndoRepair();
+ void testDocumentRepair();
void testLanguageStatus();
void testDefaultView();
@@ -143,6 +144,7 @@ public:
CPPUNIT_TEST(testCommentCallbacks);
CPPUNIT_TEST(testMultiViewInsertDeletePage);
CPPUNIT_TEST(testDisableUndoRepair);
+ CPPUNIT_TEST(testDocumentRepair);
CPPUNIT_TEST(testLanguageStatus);
CPPUNIT_TEST(testDefaultView);
@@ -1843,6 +1845,55 @@ void SdTiledRenderingTest::testDisableUndoRepair()
comphelper::LibreOfficeKit::setActive(false);
}
+void SdTiledRenderingTest::testDocumentRepair()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ // Create two views.
+ SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
+ CPPUNIT_ASSERT(pXImpressDocument);
+
+ // view #1
+ SfxViewShell* pView1 = SfxViewShell::Current();
+
+ // view #2
+ SfxLokHelper::createView();
+ SfxViewShell* pView2 = SfxViewShell::Current();
+ int nView2 = SfxLokHelper::getView();
+ CPPUNIT_ASSERT(pView1 != pView2);
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ // Insert a character in the second view.
+ SfxLokHelper::setView(nView2);
+ pXImpressDocument->setPart(1);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
+ Scheduler::ProcessEventsToIdle();
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
void SdTiledRenderingTest::testLanguageStatus()
{
// Load the document.
diff --git a/sd/source/ui/docshell/docshell.cxx b/sd/source/ui/docshell/docshell.cxx
index 967f22552eaa..9f4f5665a9c6 100644
--- a/sd/source/ui/docshell/docshell.cxx
+++ b/sd/source/ui/docshell/docshell.cxx
@@ -116,7 +116,10 @@ void DrawDocShell::Construct( bool bClipboard )
SetBaseModel( new SdXImpressDocument( this, bClipboard ) );
SetPool( &mpDoc->GetItemPool() );
- mpUndoManager = new sd::UndoManager;
+ sd::UndoManager* pUndoManager = new sd::UndoManager;
+ pUndoManager->SetDocShell(this);
+ mpUndoManager = pUndoManager;
+
if (!utl::ConfigManager::IsFuzzing()
&& officecfg::Office::Common::Undo::Steps::get() < 1)
{
diff --git a/sfx2/sdi/docslots.sdi b/sfx2/sdi/docslots.sdi
index a6da56c2488d..811467cd94be 100644
--- a/sfx2/sdi/docslots.sdi
+++ b/sfx2/sdi/docslots.sdi
@@ -202,6 +202,10 @@ interface OfficeDocument : Document
ExecMethod = ExecFile_Impl;
StateMethod = GetState_Impl;
]
+ SID_DOC_REPAIR
+ [
+ StateMethod = GetState_Impl;
+ ]
}
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index e00cd9aece28..659e3763bfd1 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -3335,6 +3335,25 @@ SfxStringItem Redo SID_REDO
GroupId = SfxGroupId::Edit;
]
+SfxBoolItem DocumentRepair SID_DOC_REPAIR
+
+[
+ AutoUpdate = FALSE,
+ FastCall = FALSE,
+ ReadOnlyDoc = FALSE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+ Asynchron;
+
+
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = ;
+]
+
SfxBoolItem Reload SID_RELOAD
()
[
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 9fd42581036f..d5adabbaa598 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1018,7 +1018,8 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c
aEvent.FeatureURL.Path == "PreviousTrackedChange" ||
aEvent.FeatureURL.Path == "AlignLeft" ||
aEvent.FeatureURL.Path == "AlignHorizontalCenter" ||
- aEvent.FeatureURL.Path == "AlignRight")
+ aEvent.FeatureURL.Path == "AlignRight" ||
+ aEvent.FeatureURL.Path == "DocumentRepair")
{
bool bTemp = false;
aEvent.State >>= bTemp;
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx
index 62f2f003016b..e104116f1d17 100644
--- a/sfx2/source/doc/objserv.cxx
+++ b/sfx2/source/doc/objserv.cxx
@@ -1069,6 +1069,15 @@ void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
rSet.DisableItem( nWhich );
break;
}
+ case SID_DOC_REPAIR:
+ {
+ svl::IUndoManager* pIUndoMgr = GetUndoManager();
+ if (pIUndoMgr)
+ rSet.Put( SfxBoolItem(nWhich, pIUndoMgr->IsEmptyActions()) );
+ else
+ rSet.DisableItem( nWhich );
+ break;
+ }
}
}
}
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 816a0aafbca3..e6db9e2d4fee 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -1247,6 +1247,12 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
break;
}
+ case SfxHintId::DocumentRepair:
+ {
+ GetBindings().Invalidate( SID_DOC_REPAIR );
+ break;
+ }
+
case SfxHintId::Deinitializing:
GetFrame().DoClose();
break;
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index 7227fb1db638..8fe198ce51f6 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -226,6 +226,7 @@ struct SfxUndoManager_Data
bool mbUndoEnabled;
bool mbDoing;
bool mbClearUntilTopLevel;
+ bool mbEmptyActions;
UndoListeners aListeners;
@@ -237,6 +238,7 @@ struct SfxUndoManager_Data
,mbUndoEnabled( true )
,mbDoing( false )
,mbClearUntilTopLevel( false )
+ ,mbEmptyActions( true )
{
pActUndoArray = pUndoArray.get();
}
@@ -398,6 +400,7 @@ using namespace ::svl::undo::impl;
SfxUndoManager::SfxUndoManager( size_t nMaxUndoActionCount )
:m_xData( new SfxUndoManager_Data( nMaxUndoActionCount ) )
{
+ m_xData->mbEmptyActions = !ImplIsEmptyActions();
}
@@ -478,6 +481,7 @@ void SfxUndoManager::SetMaxUndoActionCount( size_t nMaxUndoActionCount )
}
m_xData->pActUndoArray->nMaxUndoActions = nMaxUndoActionCount;
+ ImplCheckEmptyActions();
}
@@ -496,6 +500,7 @@ void SfxUndoManager::ImplClearCurrentLevel_NoNotify( UndoManagerGuard& i_guard )
m_xData->mnMarks = 0;
m_xData->mnEmptyMark = MARK_INVALID;
+ ImplCheckEmptyActions();
}
@@ -576,6 +581,7 @@ void SfxUndoManager::ImplClearUndo( UndoManagerGuard& i_guard )
i_guard.markForDeletion( pUndoAction );
--m_xData->pActUndoArray->nCurUndoAction;
}
+ ImplCheckEmptyActions();
// TODO: notifications? We don't have clearedUndo, only cleared and clearedRedo at the SfxUndoListener
}
@@ -593,6 +599,7 @@ void SfxUndoManager::ImplClearRedo( UndoManagerGuard& i_guard, bool const i_curr
i_guard.markForDeletion( pAction );
}
+ ImplCheckEmptyActions();
// notification - only if the top level's stack was cleared
if ( i_currentLevel == IUndoManager::TopLevel )
i_guard.scheduleNotification( &SfxUndoListener::clearedRedo );
@@ -646,6 +653,7 @@ bool SfxUndoManager::ImplAddUndoAction_NoNotify( SfxUndoAction *pAction, bool bT
// append new action
m_xData->pActUndoArray->aUndoActions.Insert( pAction, m_xData->pActUndoArray->nCurUndoAction++ );
+ ImplCheckEmptyActions();
return true;
}
@@ -713,6 +721,7 @@ void SfxUndoManager::RemoveLastUndoAction()
m_xData->pActUndoArray->aUndoActions.Remove(
m_xData->pActUndoArray->nCurUndoAction,
m_xData->pActUndoArray->aUndoActions.size() - m_xData->pActUndoArray->nCurUndoAction );
+ ImplCheckEmptyActions();
}
@@ -902,6 +911,7 @@ bool SfxUndoManager::ImplRedo( SfxUndoContext* i_contextOrNull )
throw;
}
+ ImplCheckEmptyActions();
aGuard.scheduleNotification( &SfxUndoListener::actionRedone, sActionComment );
return true;
@@ -1126,6 +1136,7 @@ size_t SfxUndoManager::ImplLeaveListAction( const bool i_merge, UndoManagerGuard
}
}
+ ImplIsEmptyActions();
// notify listeners
i_guard.scheduleNotification( &SfxUndoListener::listActionLeft, pListAction->GetComment() );
@@ -1229,6 +1240,7 @@ void SfxUndoManager::RemoveOldestUndoAction()
aGuard.markForDeletion( pActionToRemove );
m_xData->pUndoArray->aUndoActions.Remove( 0 );
--m_xData->pUndoArray->nCurUndoAction;
+ ImplCheckEmptyActions();
}
void SfxUndoManager::dumpAsXml(xmlTextWriterPtr pWriter) const
@@ -1320,6 +1332,33 @@ OUString SfxUndoManager::GetRedoActionsInfo() const
return OUString::fromUtf8(aStream.str().c_str());
}
+bool SfxUndoManager::IsEmptyActions() const
+{
+ UndoManagerGuard aGuard(*m_xData);
+
+ return ImplIsEmptyActions();
+}
+
+inline bool SfxUndoManager::ImplIsEmptyActions() const
+{
+ return m_xData->pUndoArray->nCurUndoAction || m_xData->pUndoArray->aUndoActions.size() - m_xData->pUndoArray->nCurUndoAction;
+}
+
+void SfxUndoManager::ImplCheckEmptyActions()
+{
+ bool bEmptyActions = ImplIsEmptyActions();
+ if (m_xData->mbEmptyActions != bEmptyActions)
+ {
+ m_xData->mbEmptyActions = bEmptyActions;
+ EmptyActionsChanged();
+ }
+}
+
+void SfxUndoManager::EmptyActionsChanged()
+{
+
+}
+
struct SfxListUndoAction::Impl
{
sal_uInt16 mnId;
diff --git a/svx/source/svdraw/sdrundomanager.cxx b/svx/source/svdraw/sdrundomanager.cxx
index cb5ecdc9bca3..6b051331f060 100644
--- a/svx/source/svdraw/sdrundomanager.cxx
+++ b/svx/source/svdraw/sdrundomanager.cxx
@@ -18,7 +18,8 @@
*/
#include <svx/sdrundomanager.hxx>
-
+#include <sfx2/objsh.hxx>
+#include <svl/hint.hxx>
SdrUndoManager::SdrUndoManager()
: EditUndoManager(20/*nMaxUndoActionCount*/)
@@ -131,4 +132,17 @@ bool SdrUndoManager::isTextEditActive() const
return maEndTextEditHdl.IsSet();
}
+void SdrUndoManager::SetDocShell(SfxObjectShell* pDocShell)
+{
+ m_pDocSh = pDocShell;
+}
+
+void SdrUndoManager::EmptyActionsChanged()
+{
+ if (m_pDocSh)
+ {
+ m_pDocSh->Broadcast(SfxHint(SfxHintId::DocumentRepair));
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 91f5f2235901..d6f95df456e7 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -32,6 +32,7 @@
#include <sfx2/viewsh.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
+#include <sfx2/viewfrm.hxx>
#include <sfx2/lokhelper.hxx>
#include <redline.hxx>
#include <IDocumentRedlineAccess.hxx>
@@ -94,7 +95,7 @@ public:
void testRedoRepairResult();
void testDisableUndoRepair();
void testAllTrackedChanges();
-
+ void testDocumentRepair();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -141,6 +142,7 @@ public:
CPPUNIT_TEST(testRedoRepairResult);
CPPUNIT_TEST(testDisableUndoRepair);
CPPUNIT_TEST(testAllTrackedChanges);
+ CPPUNIT_TEST(testDocumentRepair);
CPPUNIT_TEST_SUITE_END();
@@ -1887,6 +1889,50 @@ void SwTiledRenderingTest::testAllTrackedChanges()
comphelper::LibreOfficeKit::setActive(false);
}
+void SwTiledRenderingTest::testDocumentRepair()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ // Create two views.
+ SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+ // view #1
+ SfxViewShell* pView1 = SfxViewShell::Current();
+
+ // view #2
+ SfxLokHelper::createView();
+ SfxViewShell* pView2 = SfxViewShell::Current();
+ int nView2 = SfxLokHelper::getView();
+ CPPUNIT_ASSERT(pView1 != pView2);
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(false, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ // Insert a character in the second view.
+ SfxLokHelper::setView(nView2);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'u', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'u', 0);
+ Scheduler::ProcessEventsToIdle();
+ {
+ std::unique_ptr<SfxPoolItem> pItem1;
+ std::unique_ptr<SfxPoolItem> pItem2;
+ pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem1);
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, pItem2);
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem1.get()));
+ CPPUNIT_ASSERT(dynamic_cast< const SfxBoolItem* >(pItem2.get()));
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem1.get())->GetValue());
+ CPPUNIT_ASSERT_EQUAL(true, dynamic_cast< const SfxBoolItem* >(pItem2.get())->GetValue());
+ }
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx
index 6064757c4bc0..b5c2b44e2eab 100644
--- a/sw/source/core/inc/UndoManager.hxx
+++ b/sw/source/core/inc/UndoManager.hxx
@@ -94,6 +94,9 @@ public:
SwNodes & GetUndoNodes();
void SetDocShell(SwDocShell* pDocShell);
+protected:
+ virtual void EmptyActionsChanged() override;
+
private:
IDocumentDrawModelAccess & m_rDrawModelAccess;
IDocumentRedlineAccess & m_rRedlineAccess;
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index 751115d22a59..3f6168b95d6d 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -639,6 +639,14 @@ bool UndoManager::Redo()
}
}
+void UndoManager::EmptyActionsChanged()
+{
+ if (m_pDocShell)
+ {
+ m_pDocShell->Broadcast(SfxHint(SfxHintId::DocumentRepair));
+ }
+}
+
/** N.B.: this does _not_ call SdrUndoManager::Repeat because it is not
possible to wrap a list action around it:
calling EnterListAction here will cause SdrUndoManager::Repeat