summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorOliver Specht <oliver.specht@cib.de>2024-09-10 12:43:06 +0200
committerGabor Kelemen <gabor.kelemen.extern@allotropia.de>2024-09-23 20:20:28 +0200
commita593c27e8897280871dc310184ff568bf34a6ebe (patch)
tree494bc2df409bc93e5a1f00e9d9cfbdee239ab295 /sw
parent87039e3e772c7b36480e70019dea0faa15feef6b (diff)
tdf#162326 remove character formats and styles on style apply
Removes the character attributes and character styles when a paragraph or a character style is applied and the Ctrl button is pressed. Change-Id: I8b2809d1a2b91e501ed8a11ac9f3aebec6c12c47 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173154 Reviewed-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de> Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/doc.hxx1
-rw-r--r--sw/inc/editsh.hxx4
-rw-r--r--sw/inc/swtypes.hxx6
-rw-r--r--sw/qa/extras/uiwriter/data/tdf162326.odtbin0 -> 10857 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter9.cxx65
-rw-r--r--sw/source/core/crsr/findcoll.cxx2
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx61
-rw-r--r--sw/source/core/doc/docfmt.cxx25
-rw-r--r--sw/source/core/edit/edfcol.cxx5
-rw-r--r--sw/source/core/inc/DocumentContentOperationsManager.hxx4
-rw-r--r--sw/source/core/txtnode/txtedt.cxx2
-rw-r--r--sw/source/uibase/app/docst.cxx10
12 files changed, 172 insertions, 13 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index a1bcea1eca4f..6e037f3878c9 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -814,6 +814,7 @@ public:
SW_DLLPUBLIC bool SetTextFormatColl(const SwPaM &rRg, SwTextFormatColl *pFormat,
const bool bReset = true,
const bool bResetListAttrs = false,
+ const bool bResetAllCharAttrs = false,
SwRootFrame const* pLayout = nullptr);
SwTextFormatColl* FindTextFormatCollByName( const OUString& rName ) const
{ return mpTextFormatCollTable->FindFormatByName(rName); }
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 0de62a1d27de..0e9d8064901b 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -335,7 +335,9 @@ public:
// #i62675#
/// Add 2nd optional parameter <bResetListAttrs> - see also <SwDoc::SetTextFormatColl(..)>
- SW_DLLPUBLIC void SetTextFormatColl(SwTextFormatColl*, const bool bResetListAttrs = false);
+ SW_DLLPUBLIC void SetTextFormatColl(SwTextFormatColl*,
+ const bool bResetListAttrs = false,
+ SetAttrMode nMode = SetAttrMode::DEFAULT);
SW_DLLPUBLIC SwTextFormatColl *MakeTextFormatColl(const OUString &rFormatCollName,
SwTextFormatColl *pDerivedFrom = nullptr);
void FillByEx(SwTextFormatColl*);
diff --git a/sw/inc/swtypes.hxx b/sw/inc/swtypes.hxx
index 2a528403f2a4..f692dc91a0b1 100644
--- a/sw/inc/swtypes.hxx
+++ b/sw/inc/swtypes.hxx
@@ -151,11 +151,13 @@ enum class SetAttrMode
/// for Undo, translated to SwInsertFlags::NOHINTEXPAND
NOHINTEXPAND = 0x0100,
/// don't change the cursor position
- NO_CURSOR_CHANGE = 0x0200
+ NO_CURSOR_CHANGE = 0x0200,
+ // remove all char attributes and char styles when para/char styles are applied
+ REMOVE_ALL_ATTR = 0x0400
};
namespace o3tl
{
- template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x3ff> {};
+ template<> struct typed_flags<SetAttrMode> : is_typed_flags<SetAttrMode, 0x7ff> {};
}
namespace sw {
diff --git a/sw/qa/extras/uiwriter/data/tdf162326.odt b/sw/qa/extras/uiwriter/data/tdf162326.odt
new file mode 100644
index 000000000000..9fb91e41896a
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf162326.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx
index f7bcf7e2af1a..e0acf8fd8468 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -14,6 +14,9 @@
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <vcl/scheduler.hxx>
+
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
#include <com/sun/star/table/TableBorder2.hpp>
#include <com/sun/star/text/XDocumentIndex.hpp>
#include <com/sun/star/text/XTextFrame.hpp>
@@ -46,7 +49,6 @@
#include <IDocumentLinksAdministration.hxx>
#include <fmtinfmt.hxx>
#include <rootfrm.hxx>
-
#include <svx/svdview.hxx>
#include <svx/svdmark.hxx>
@@ -736,6 +738,67 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf144752)
CPPUNIT_ASSERT_EQUAL(u"Word"_ustr, pWrtShell->GetSelText());
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162326_Pargraph)
+{
+ createSwDoc("tdf162326.odt");
+ SwXTextDocument* pDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
+ getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
+ CPPUNIT_ASSERT_EQUAL(
+ awt::FontSlant_ITALIC,
+ getProperty<awt::FontSlant>(getRun(getParagraph(2), 2), u"CharPosture"_ustr));
+ CPPUNIT_ASSERT_EQUAL(short(1),
+ getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
+
+ pWrtShell->Down(/*bSelect=*/true, 3);
+
+ dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
+ { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
+ comphelper::makePropertyValue(u"Style"_ustr, u"Footnote"_ustr),
+ comphelper::makePropertyValue(u"KeyModifier"_ustr, uno::Any(KEY_MOD1)) });
+
+ CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
+ getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
+ CPPUNIT_ASSERT_THROW(getRun(getParagraph(2), 2), css::container::NoSuchElementException);
+ CPPUNIT_ASSERT_THROW(getRun(getParagraph(3), 2), css::container::NoSuchElementException);
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf162326_Character)
+{
+ createSwDoc("tdf162326.odt");
+ SwXTextDocument* pDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD,
+ getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
+ CPPUNIT_ASSERT_EQUAL(
+ awt::FontSlant_ITALIC,
+ getProperty<awt::FontSlant>(getRun(getParagraph(2), 2), u"CharPosture"_ustr));
+ CPPUNIT_ASSERT_EQUAL(short(1),
+ getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
+
+ pWrtShell->Down(/*bSelect=*/true, 3);
+
+ //add Ctrl/MOD_1
+ dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
+ { comphelper::makePropertyValue(u"FamilyName"_ustr, u"CharacterStyles"_ustr),
+ comphelper::makePropertyValue(u"Style"_ustr, u"Definition"_ustr),
+ comphelper::makePropertyValue(u"KeyModifier"_ustr, uno::Any(KEY_MOD1)) });
+
+ CPPUNIT_ASSERT_EQUAL(awt::FontWeight::NORMAL,
+ getProperty<float>(getRun(getParagraph(1), 1), u"CharWeight"_ustr));
+ CPPUNIT_ASSERT_THROW(getRun(getParagraph(2), 2), css::container::NoSuchElementException);
+ //last runs are not changed because the selection ends at the beginning of that paragraph
+ CPPUNIT_ASSERT_EQUAL(short(1),
+ getProperty<short>(getRun(getParagraph(3), 2), u"CharUnderline"_ustr));
+}
+
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/crsr/findcoll.cxx b/sw/source/core/crsr/findcoll.cxx
index 31a64aa3313f..2f633bd29186 100644
--- a/sw/source/core/crsr/findcoll.cxx
+++ b/sw/source/core/crsr/findcoll.cxx
@@ -60,7 +60,7 @@ int SwFindParaFormatColl::DoFind(SwPaM & rCursor, SwMoveFnCollection const & fnM
else if( pReplColl )
{
rCursor.GetDoc().SetTextFormatColl(rCursor,
- const_cast<SwTextFormatColl*>(pReplColl), true, false, m_pLayout);
+ const_cast<SwTextFormatColl*>(pReplColl), true, false, false, m_pLayout);
nRet = FIND_NO_RING;
}
return nRet;
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index ce7bb41149dc..0f24abd95bc3 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -230,7 +230,6 @@ namespace
}
rChgPos.SetContent( nContentPos );
}
-
}
namespace sw
@@ -3689,12 +3688,34 @@ bool DocumentContentOperationsManager::InsertPoolItem(
SwRootFrame const*const pLayout,
SwTextAttr **ppNewTextAttr)
{
+ SwHistory* pHistory = nullptr;
SwDataChanged aTmp( rRg );
std::unique_ptr<SwUndoAttr> pUndoAttr;
if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
{
m_rDoc.GetIDocumentUndoRedo().ClearRedo();
pUndoAttr.reset(new SwUndoAttr( rRg, rHt, nFlags ));
+ pHistory = &pUndoAttr->GetHistory();
+ }
+
+ if (nFlags & SetAttrMode::REMOVE_ALL_ATTR)
+ {
+ std::shared_ptr<const SfxItemSet> pDelSet = lcl_createDelSet(m_rDoc);
+ SwPosition aStart(*rRg.GetMark()->GetNode().GetContentNode(), rRg.GetMark()->GetContentIndex());
+ SwPosition aEnd(*rRg.GetPoint()->GetNode().GetContentNode(), rRg.GetPoint()->GetContentIndex());
+ sw::DocumentContentOperationsManager::ParaRstFormat aPara(
+ &aStart, &aEnd, pHistory, nullptr, nullptr /* //TODO: is layout required? m_rDoc.GetLayout()*/);
+ // aPara.pFormatColl = pPara->pFormatColl;
+ aPara.bReset = true;
+ // #i62675#
+ aPara.bResetListAttrs = false;
+ aPara.bResetAllCharAttrs = true;
+ aPara.pDelSet = pDelSet.get();
+ m_rDoc.GetNodes().ForEach(
+ aStart.GetNode().GetIndex(),
+ aEnd.GetNode().GetIndex(),
+ ::sw::DocumentContentOperationsManager::lcl_RstTextAttr,
+ &aPara);
}
SfxItemSet aSet( m_rDoc.GetAttrPool(), rHt.Which(), rHt.Which() );
@@ -4206,6 +4227,44 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
}
/*
+ create ItemSet to be used in ParaRstFormat
+*/
+std::shared_ptr<SfxItemSet> DocumentContentOperationsManager::lcl_createDelSet(SwDoc& rDoc)
+{
+ std::shared_ptr<SfxItemSet> pDelSet(new SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
+ RES_TXTATR_INETFMT, RES_TXTATR_UNKNOWN_CONTAINER,
+ RES_PARATR_BEGIN, RES_FRMATR_END - 1,
+ RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1>(rDoc.GetAttrPool()));
+ o3tl::sorted_vector<sal_uInt16> aAttribs;
+
+ constexpr std::pair<sal_uInt16, sal_uInt16> aResetableSetRange[] = {
+ // tdf#40496: we don't want to change writing direction, so exclude RES_FRAMEDIR:
+ { RES_TXTATR_CHARFMT,RES_TXTATR_CHARFMT },
+ { RES_FRMATR_BEGIN, RES_FRAMEDIR - 1 },
+ { RES_FRAMEDIR + 1, RES_FRMATR_END - 1 },
+ { RES_CHRATR_BEGIN, RES_CHRATR_LANGUAGE - 1 },
+ { RES_CHRATR_LANGUAGE + 1, RES_CHRATR_CJK_LANGUAGE - 1 },
+ { RES_CHRATR_CJK_LANGUAGE + 1, RES_CHRATR_CTL_LANGUAGE - 1 },
+ { RES_CHRATR_CTL_LANGUAGE + 1, RES_CHRATR_END - 1 },
+ { RES_PARATR_BEGIN, RES_PARATR_END - 1 },
+ { RES_PARATR_LIST_AUTOFMT, RES_PARATR_LIST_AUTOFMT },
+ { RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER },
+ { RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1 },
+ };
+ for (const auto& [nBegin, nEnd] : aResetableSetRange)
+ {
+ for (sal_uInt16 i = nBegin; i <= nEnd; ++i)
+ aAttribs.insert( i );
+ }
+ for( auto it = aAttribs.rbegin(); it != aAttribs.rend(); ++it )
+ {
+ if( POOLATTR_END > *it )
+ pDelSet->Put( *GetDfltAttr( *it ));
+ }
+ return pDelSet;
+}
+
+/*
* Reset the text's hard formatting
*/
/** @params pArgs contains the document's ChrFormatTable
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index b7f8d4ba7791..8116bb80b424 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -1020,6 +1020,22 @@ static bool lcl_SetTextFormatColl( SwNode* pNode, void* pArgs )
SwTextFormatColl* pFormat = pPara->pFormatColl;
if ( pPara->bReset )
{
+ if (pCNd->IsTextNode() && pPara->bResetAllCharAttrs && pPara->pDelSet && pPara->pDelSet->Count())
+ {
+ //TODO: copy to select the text node completely
+ SwPosition aStart(*pCNd, 0);
+ SwPosition aEnd(*pCNd, pCNd->GetTextNode()->GetText().getLength());
+ sw::DocumentContentOperationsManager::ParaRstFormat aPara(
+ &aStart, &aEnd, pPara->pHistory, nullptr, pPara->pLayout);
+ aPara.pFormatColl = pPara->pFormatColl;
+ aPara.bReset = pPara->bReset;
+ // #i62675#
+ aPara.bResetListAttrs = pPara->bResetListAttrs;
+ aPara.bResetAllCharAttrs = pPara->bResetAllCharAttrs;
+ aPara.pDelSet = pPara->pDelSet;
+ sw::DocumentContentOperationsManager::lcl_RstTextAttr(pCNd, &aPara);
+ }
+
lcl_RstAttr(pCNd, pPara);
// #i62675# check, if paragraph style has changed
@@ -1088,6 +1104,7 @@ bool SwDoc::SetTextFormatColl(const SwPaM &rRg,
SwTextFormatColl *pFormat,
const bool bReset,
const bool bResetListAttrs,
+ const bool bResetAllCharAttrs,
SwRootFrame const*const pLayout)
{
SwDataChanged aTmp( rRg );
@@ -1104,12 +1121,20 @@ bool SwDoc::SetTextFormatColl(const SwPaM &rRg,
GetIDocumentUndoRedo().AppendUndo(std::move(pUndo));
}
+ std::shared_ptr<SfxItemSet> pDelSet;
sw::DocumentContentOperationsManager::ParaRstFormat aPara(
pStt, pEnd, pHst, nullptr, pLayout);
aPara.pFormatColl = pFormat;
aPara.bReset = bReset;
// #i62675#
aPara.bResetListAttrs = bResetListAttrs;
+ aPara.bResetAllCharAttrs = bResetAllCharAttrs;
+ if (bResetAllCharAttrs)
+ {
+ o3tl::sorted_vector<sal_uInt16> aAttribs;
+ pDelSet = sw::DocumentContentOperationsManager::lcl_createDelSet(*this);
+ aPara.pDelSet = pDelSet.get();
+ }
GetNodes().ForEach( pStt->GetNodeIndex(), pEnd->GetNodeIndex()+1,
lcl_SetTextFormatColl, &aPara );
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index c0b1d27c3315..a998f5a51884 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -2197,7 +2197,8 @@ void SwEditShell::ClassifyDocPerHighestParagraphClass()
// #i62675#
void SwEditShell::SetTextFormatColl(SwTextFormatColl *pFormat,
- const bool bResetListAttrs)
+ const bool bResetListAttrs,
+ SetAttrMode nMode)
{
SwTextFormatColl *pLocal = pFormat? pFormat: (*GetDoc()->GetTextFormatColls())[0];
StartAllAction();
@@ -2227,7 +2228,7 @@ void SwEditShell::SetTextFormatColl(SwTextFormatColl *pFormat,
}
// Change the paragraph style to pLocal and remove all direct paragraph formatting.
- GetDoc()->SetTextFormatColl(rPaM, pLocal, true, bResetListAttrs, GetLayout());
+ GetDoc()->SetTextFormatColl(rPaM, pLocal, true, bResetListAttrs, !!(nMode & SetAttrMode::REMOVE_ALL_ATTR), GetLayout());
// If there are hints on the nodes which cover the whole node, then remove those, too.
SwPaM aPaM(*rPaM.Start(), *rPaM.End());
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 3cb378f00069..62540462bb77 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -127,6 +127,7 @@ public:
bool bReset;
bool bResetListAttrs; // #i62575#
bool bResetAll;
+ bool bResetAllCharAttrs;
bool bInclRefToxMark;
/// From the attributes included in the range, delete only the ones which have exactly same range. Don't delete the ones which are simply included in the range.
bool bExactRange;
@@ -144,13 +145,14 @@ public:
, bReset(false) // #i62675#
, bResetListAttrs(false)
, bResetAll(true)
+ , bResetAllCharAttrs(false)
, bInclRefToxMark(false)
, bExactRange(false)
{
}
};
static bool lcl_RstTextAttr( SwNode* pNd, void* pArgs ); //originally from docfmt.cxx
-
+ static std::shared_ptr<SfxItemSet> lcl_createDelSet(SwDoc& rDoc);
virtual ~DocumentContentOperationsManager() override;
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 24de64a8f9e0..c08d36505730 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -381,7 +381,7 @@ static bool lcl_HaveCommonAttributes( IStyleAccess& rStyleAccess,
*
* @param nStt starting position
* @param nLen length of the deletion
- * @param nthat ???
+ * @param nWhich ???
* @param pSet ???
* @param bInclRefToxMark ???
*/
diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx
index eba940a48dfc..65bf850b5b0a 100644
--- a/sw/source/uibase/app/docst.cxx
+++ b/sw/source/uibase/app/docst.cxx
@@ -1197,8 +1197,12 @@ SfxStyleFamily SwDocShell::ApplyStyles(const OUString &rName, SfxStyleFamily nFa
case SfxStyleFamily::Char:
{
SwFormatCharFormat aFormat(pStyle->GetCharFormat());
- pSh->SetAttrItem( aFormat, (nMode & KEY_SHIFT) ?
- SetAttrMode::DONTREPLACE : SetAttrMode::DEFAULT );
+ SetAttrMode nFlags = (nMode & KEY_SHIFT) ?
+ SetAttrMode::DONTREPLACE : SetAttrMode::DEFAULT;
+ if (nMode & KEY_MOD1)
+ nFlags |= SetAttrMode::REMOVE_ALL_ATTR;
+ pSh->SetAttrItem( aFormat, nFlags );
+
break;
}
case SfxStyleFamily::Para:
@@ -1215,7 +1219,7 @@ SfxStyleFamily SwDocShell::ApplyStyles(const OUString &rName, SfxStyleFamily nFa
// #i62675#
// clear also list attributes at affected text nodes, if paragraph
// style has the list style attribute set.
- pSh->SetTextFormatColl( pStyle->GetCollection(), true );
+ pSh->SetTextFormatColl( pStyle->GetCollection(), true, (nMode & KEY_MOD1) ? SetAttrMode::REMOVE_ALL_ATTR : SetAttrMode::DEFAULT);
}
break;
}