summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-05-10 17:45:14 +0200
committerAndras Timar <andras.timar@collabora.com>2017-05-22 10:00:15 +0200
commit47fd47bf8c206cf9d60f9b872f2224a680e887e1 (patch)
treeab8ca12a88ebac52f8d90b86325dedc1caf39485 /sw
parent40460de56fd7347119965600007ee1c746e51760 (diff)
tdf#107512 sw: fix rollback of text attributes in SwUndoDelete
The problem is that in SwUndoDelete::UndoImpl(), first the formatting attributes are restored via TmpRollback(), and then all footnote/fly attributes are restored via Rollback(). This means that the SwHistory doesn't actually store the original positions of the formatting hints; ideally there wouldn't be 2 separate steps here, but that appears difficult to change now given the plethora of calls to DelContentIndex() ... So work around the problem by adding a new SetAttrMode::NOHINTEXPAND to prevent expanding the existing hints when the CH_TXTATR_BREAKWORD are inserted from SwUndoDelLayFormat. This fixes 2 problematic cases: at the start of the paragraph, and if the hint ends at the position before the CH_TXTATR_BREAKWORD. Let's hope this won't break anything anybody cares about. (cherry picked from commit 771d85baf18e5b503eb6248e1f41928b00265d8d) sw: CPPUNIT_ASSERT_EQUAL vs. integer FAIL (cherry picked from commit 7f44ca113170a641a1aecc8a48e2b99860e1e2f7) Change-Id: I557c4c9136f4225ca502019730fb9f0a9c03d23b Reviewed-on: https://gerrit.libreoffice.org/37485 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit 4820c9b981e060a55b3511272824dca7c2eb67d5)
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx132
1 files changed, 132 insertions, 0 deletions
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 4594b5ba4936..0818c701e8e3 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -3273,6 +3273,138 @@ void SwUiWriterTest::testUndoDelAsCharTdf107512()
query.ClearItem(RES_CHRATR_HIDDEN);
}
+void SwUiWriterTest::testUndoDelAsCharTdf107512()
+{
+ SwDoc * pDoc(createDoc());
+ sw::UndoManager & rUndoManager(pDoc->GetUndoManager());
+ IDocumentContentOperations & rIDCO(pDoc->getIDocumentContentOperations());
+ SwCursorShell * pShell(pDoc->GetEditShell());
+ SfxItemSet frameSet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
+ SfxItemSet grfSet(pDoc->GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
+ rIDCO.InsertString(*pShell->GetCursor(), "foo");
+ pShell->ClearMark();
+ SwFormatAnchor anchor(RndStdIds::FLY_AS_CHAR);
+ frameSet.Put(anchor);
+ GraphicObject grf;
+ pShell->SttEndDoc(true);
+ CPPUNIT_ASSERT(rIDCO.Insert(*pShell->GetCursor(), grf, &frameSet, &grfSet, nullptr));
+ pShell->SttEndDoc(false);
+ CPPUNIT_ASSERT(rIDCO.Insert(*pShell->GetCursor(), grf, &frameSet, &grfSet, nullptr));
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ SvxCharHiddenItem hidden(true, RES_CHRATR_HIDDEN);
+ pShell->SelectText(1, 4);
+ rIDCO.InsertPoolItem(*pShell->GetCursor(), hidden);
+ // now we have "\1foo\1" with the "foo" hidden
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+ SfxPoolItem const* pItem;
+ SfxItemSet query(pDoc->GetAttrPool(), RES_CHRATR_HIDDEN, RES_CHRATR_HIDDEN);
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+ query.ClearItem(RES_CHRATR_HIDDEN);
+
+ // delete from the start
+ pShell->SelectText(0, 4);
+ rIDCO.DeleteAndJoin(*pShell->GetCursor());
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Undo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Redo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Undo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 0, 1);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+ query.ClearItem(RES_CHRATR_HIDDEN);
+
+ // delete from the end
+ pShell->SelectText(1, 5);
+ rIDCO.DeleteAndJoin(*pShell->GetCursor());
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Undo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Redo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ rUndoManager.Undo();
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(0, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT(pShell->GetCursor()->GetNode().GetTextNode()->GetTextAttrForCharAt(4, RES_TXTATR_FLYCNT));
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc->GetFlyCount(FLYCNTTYPE_GRF));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pShell->GetCursor()->GetNode().GetTextNode()->Len());
+ CPPUNIT_ASSERT_EQUAL(OUString(OUStringLiteral1(CH_TXTATR_BREAKWORD) + "foo" + OUStringLiteral1(CH_TXTATR_BREAKWORD)), pShell->GetCursor()->GetNode().GetTextNode()->GetText());
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 4, 5);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::DEFAULT == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ query.ClearItem(RES_CHRATR_HIDDEN);
+ pShell->GetCursor()->GetNode().GetTextNode()->GetAttr(query, 1, 4);
+// CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(SfxItemState::SET == query.GetItemState(RES_CHRATR_HIDDEN, false, &pItem));
+ CPPUNIT_ASSERT(static_cast<SvxCharHiddenItem const*>(pItem)->GetValue());
+ query.ClearItem(RES_CHRATR_HIDDEN);
+}
+
void SwUiWriterTest::testUndoCharAttribute()
{
// Create a new empty Writer document