tdf#102384 sw: avoid moving cursors of other windows in SwTextNode::Update()

There is a list of exceptional SwIndex containers in that member
function, like bookmarks, at-char anchored fly frames, etc. If we're
growing (so basically in the safe case), don't touch the cursors of
other windows, either.

This helps to avoid the surprising "I didn't do anything and my cursor
moved" behavior.

Change-Id: I9941fdcb6b7ad4b6e18a321cecc72fdf73d917fd
This commit is contained in:
Miklos Vajna
2016-09-23 18:15:14 +02:00
parent d17d7c63d2
commit ecdec24c03
2 changed files with 47 additions and 0 deletions

View File

@@ -91,6 +91,7 @@
#include <comphelper/propertysequence.hxx>
#include <sfx2/classificationhelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokhelper.hxx>
#include <config_features.h>
static const char* DATA_DIRECTORY = "/sw/qa/extras/uiwriter/data/";
@@ -206,6 +207,7 @@ public:
void testRedlineViewAuthor();
void testTdf78727();
void testRedlineTimestamp();
void testCursorWindows();
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
@@ -313,6 +315,7 @@ public:
CPPUNIT_TEST(testRedlineViewAuthor);
CPPUNIT_TEST(testTdf78727);
CPPUNIT_TEST(testRedlineTimestamp);
CPPUNIT_TEST(testCursorWindows);
CPPUNIT_TEST_SUITE_END();
private:
@@ -3978,6 +3981,27 @@ void SwUiWriterTest::testRedlineTimestamp()
CPPUNIT_ASSERT(nSec1 != 0 || nSec2 != 0);
}
void SwUiWriterTest::testCursorWindows()
{
// Create a new document with one window.
SwDoc* pDoc = createDoc();
SwDocShell* pDocShell = pDoc->GetDocShell();
SwWrtShell* pWrtShell1 = pDocShell->GetWrtShell();
// Create a second view and type something.
SfxLokHelper::createView();
SwWrtShell* pWrtShell2 = pDocShell->GetWrtShell();
OUString aText("foo");
pWrtShell2->Insert(aText);
// Assert that only the cursor of the actual window move, not other cursors.
SwShellCursor* pShellCursor1 = pWrtShell1->getShellCursor(false);
SwShellCursor* pShellCursor2 = pWrtShell2->getShellCursor(false);
// This was 3, not 0 -- cursor of the other window moved.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), pShellCursor1->Start()->nContent.GetIndex());
CPPUNIT_ASSERT_EQUAL(aText.getLength(), pShellCursor2->Start()->nContent.GetIndex());
}
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest);
CPPUNIT_PLUGIN_IMPLEMENT();

View File

@@ -87,6 +87,7 @@
#include <attrhint.hxx>
#include <memory>
#include <unoparagraph.hxx>
#include <wrtsh.hxx>
//UUUU
#include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
@@ -1157,6 +1158,28 @@ void SwTextNode::Update(
#if OSL_DEBUG_LEVEL > 0
assert( checkFormats.empty());
#endif
// The cursors of other shells shouldn't be moved, either.
if (SwDocShell* pDocShell = GetDoc()->GetDocShell())
{
for (SwViewShell& rShell : pDocShell->GetWrtShell()->GetRingContainer())
{
auto pWrtShell = dynamic_cast<SwWrtShell*>(&rShell);
if (!pWrtShell || pWrtShell == pDocShell->GetWrtShell())
continue;
SwShellCursor* pCursor = pWrtShell->GetCursor_();
if (!pCursor)
continue;
SwIndex& rIndex = const_cast<SwIndex&>(pCursor->Start()->nContent);
if (&pCursor->Start()->nNode.GetNode() == this && rIndex.GetIndex() == rPos.GetIndex())
{
// The cursor position of this other shell is exactly our insert position.
rIndex.Assign(&aTmpIdxReg, rIndex.GetIndex());
}
}
}
}
// base class