simplify IMark hierarchy (10)

use more type-safe container for AnnotationMark, which also avoids some
dynamic_cast

Change-Id: I1b1d44f81f2a3d626a1f13fbe952eecd1ea0390a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171564
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2024-08-07 12:05:42 +02:00
parent fb56e1e284
commit 49bca657d7
12 changed files with 63 additions and 32 deletions
+1
View File
@@ -29,6 +29,7 @@ $(eval $(call gb_Library_use_custom_headers,msword,\
$(eval $(call gb_Library_set_precompiled_header,msword,sw/inc/pch/precompiled_msword))
$(eval $(call gb_Library_set_include,msword,\
-I$(SRCDIR)/sw/source/core/inc \
-I$(SRCDIR)/sw/source/filter/inc \
-I$(SRCDIR)/sw/inc \
$$(INCLUDE) \
+6 -5
View File
@@ -30,6 +30,7 @@ class SwTextNode;
class SwCursorShell;
namespace sw::mark {
class AnnotationMark;
class SaveBookmark; // FIXME: Ugly: SaveBookmark is a core-internal class, and should not be used in the interface
class MarkBase;
class Fieldmark;
@@ -302,11 +303,11 @@ class IDocumentMarkAccess
virtual void ClearFieldActivation() = 0;
// Annotation Marks
virtual const_iterator getAnnotationMarksBegin() const = 0;
virtual const_iterator getAnnotationMarksEnd() const = 0;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator getAnnotationMarksBegin() const = 0;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator getAnnotationMarksEnd() const = 0;
virtual sal_Int32 getAnnotationMarksCount() const = 0;
virtual const_iterator findAnnotationMark( const OUString& rName ) const = 0;
virtual sw::mark::MarkBase* getAnnotationMarkFor(const SwPosition& rPosition) const = 0;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator findAnnotationMark( const OUString& rName ) const = 0;
virtual sw::mark::AnnotationMark* getAnnotationMarkFor(const SwPosition& rPosition) const = 0;
// handle and restore text ranges of annotations of tracked deletions
// based on the helper bookmarks (which can survive I/O and hiding redlines)
virtual ::sw::mark::Bookmark* makeAnnotationBookmark(const SwPaM& rPaM,
@@ -320,7 +321,7 @@ class IDocumentMarkAccess
@returns
an iterator pointing to the mark, or pointing to getAnnotationMarksEnd() if nothing was found.
*/
virtual const_iterator findFirstAnnotationStartsAfter(const SwPosition& rPos) const =0;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator findFirstAnnotationStartsAfter(const SwPosition& rPos) const =0;
/** Returns the MarkType used to create the mark
*/
+2 -2
View File
@@ -22,7 +22,7 @@
#include "txtfld.hxx"
namespace sw::mark { class MarkBase; }
namespace sw::mark { class AnnotationMark; }
class SwTextAnnotationField final : public SwTextField
{
@@ -34,7 +34,7 @@ public:
virtual ~SwTextAnnotationField() override;
::sw::mark::MarkBase* GetAnnotationMark() const;
::sw::mark::AnnotationMark* GetAnnotationMark() const;
};
#endif
+2 -1
View File
@@ -58,6 +58,7 @@
#include <editsh.hxx>
#include <viewopt.hxx>
#include <annotationmark.hxx>
using namespace ::com::sun::star::i18n;
@@ -1494,7 +1495,7 @@ bool SwCursor::SelectWordWT( SwViewShell const * pViewShell, sal_Int16 nWordType
{
SetMark();
GetMark()->Assign(*pStartNode, nStartIndex);
if (sw::mark::MarkBase* pAnnotationMark = pMarksAccess->getAnnotationMarkFor(*GetPoint()))
if (sw::mark::AnnotationMark* pAnnotationMark = pMarksAccess->getAnnotationMarkFor(*GetPoint()))
{
// An annotation mark covers the selected word. Check
// if it covers only the word: in that case we select
@@ -73,6 +73,7 @@
#include <fmtflcnt.hxx>
#include <docedt.hxx>
#include <frameformats.hxx>
#include <annotationmark.hxx>
#include <formatflysplit.hxx>
#include <o3tl/safeint.hxx>
#include <sal/log.hxx>
+37 -11
View File
@@ -113,6 +113,32 @@ namespace
return bCRFirst; // cross-ref sorts *before*
}
// specialise to avoid loplugin:faileddyncast
template<>
bool lcl_MarkOrderingByStart(const AnnotationMark *const pFirst,
const AnnotationMark *const pSecond)
{
SwPosition const& rFirstStart(pFirst->GetMarkStart());
SwPosition const& rSecondStart(pSecond->GetMarkStart());
if (rFirstStart.GetNode() != rSecondStart.GetNode())
{
return rFirstStart.GetNode() < rSecondStart.GetNode();
}
const sal_Int32 nFirstContent = rFirstStart.GetContentIndex();
const sal_Int32 nSecondContent = rSecondStart.GetContentIndex();
if (nFirstContent != 0 || nSecondContent != 0)
{
return nFirstContent < nSecondContent;
}
SwContentNode const*const pFirstNode(rFirstStart.nContent.GetContentNode());
SwContentNode const*const pSecondNode(rSecondStart.nContent.GetContentNode());
if ((pFirstNode != nullptr) != (pSecondNode != nullptr))
{ // consistency with SwPosition::operator<
return pSecondNode != nullptr;
}
return false; // equal
}
template<class MarkT>
bool lcl_MarkOrderingByEnd(const MarkT *const pFirst,
const MarkT *const pSecond)
@@ -613,7 +639,7 @@ namespace sw::mark
lcl_InsertMarkSorted(m_vFieldmarks, static_cast<Fieldmark*>(pMark.get()));
break;
case IDocumentMarkAccess::MarkType::ANNOTATIONMARK:
lcl_InsertMarkSorted( m_vAnnotationMarks, pMark.get() );
lcl_InsertMarkSorted( m_vAnnotationMarks, static_cast<AnnotationMark*>(pMark.get()) );
break;
case IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER:
case IDocumentMarkAccess::MarkType::DDE_BOOKMARK:
@@ -1242,7 +1268,7 @@ namespace sw::mark
case IDocumentMarkAccess::MarkType::ANNOTATIONMARK:
{
auto const ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, *ppMark);
auto const ppAnnotationMark = lcl_FindMark(m_vAnnotationMarks, static_cast<AnnotationMark*>(*ppMark));
assert(ppAnnotationMark != m_vAnnotationMarks.end() &&
"<MarkManager::deleteMark(..)> - Annotation Mark not found in Annotation Mark container.");
m_vAnnotationMarks.erase(ppAnnotationMark);
@@ -1629,12 +1655,12 @@ namespace sw::mark
Fieldmark* MarkManager::getFieldmarkBefore(const SwPosition& rPos, bool bLoop) const
{ return lcl_getMarkBefore(m_vFieldmarks, rPos, bLoop); }
IDocumentMarkAccess::const_iterator MarkManager::getAnnotationMarksBegin() const
std::vector<sw::mark::AnnotationMark*>::const_iterator MarkManager::getAnnotationMarksBegin() const
{
return m_vAnnotationMarks.begin();
}
IDocumentMarkAccess::const_iterator MarkManager::getAnnotationMarksEnd() const
std::vector<sw::mark::AnnotationMark*>::const_iterator MarkManager::getAnnotationMarksEnd() const
{
return m_vAnnotationMarks.end();
}
@@ -1644,30 +1670,30 @@ namespace sw::mark
return m_vAnnotationMarks.size();
}
IDocumentMarkAccess::const_iterator MarkManager::findAnnotationMark( const OUString& rName ) const
std::vector<sw::mark::AnnotationMark*>::const_iterator MarkManager::findAnnotationMark( const OUString& rName ) const
{
return lcl_FindMarkByName<MarkBase>( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
return lcl_FindMarkByName<AnnotationMark>( rName, m_vAnnotationMarks.begin(), m_vAnnotationMarks.end() );
}
MarkBase* MarkManager::getAnnotationMarkFor(const SwPosition& rPos) const
AnnotationMark* MarkManager::getAnnotationMarkFor(const SwPosition& rPos) const
{
auto const pAnnotationMark = find_if(
m_vAnnotationMarks.begin(),
m_vAnnotationMarks.end(),
[&rPos] (const ::sw::mark::MarkBase *const pMark) { return pMark->IsCoveringPosition(rPos); } );
[&rPos] (const ::sw::mark::AnnotationMark *const pMark) { return pMark->IsCoveringPosition(rPos); } );
if (pAnnotationMark == m_vAnnotationMarks.end())
return nullptr;
return *pAnnotationMark;
}
// finds the first that is starting after
IDocumentMarkAccess::const_iterator MarkManager::findFirstAnnotationStartsAfter(const SwPosition& rPos) const
std::vector<sw::mark::AnnotationMark*>::const_iterator MarkManager::findFirstAnnotationStartsAfter(const SwPosition& rPos) const
{
return std::upper_bound(
m_vAnnotationMarks.begin(),
m_vAnnotationMarks.end(),
rPos,
CompareIMarkStartsAfter<MarkBase>());
CompareIMarkStartsAfter<AnnotationMark>());
}
// create helper bookmark for annotations on tracked deletions
@@ -1701,7 +1727,7 @@ namespace sw::mark
(nPos = rBookmarkName.indexOf(S_ANNOTATION_BOOKMARK)) > -1 )
{
::sw::UndoGuard const undoGuard(m_rDoc.GetIDocumentUndoRedo());
IDocumentMarkAccess::const_iterator pMark = findAnnotationMark(rBookmarkName.copy(0, nPos));
auto pMark = findAnnotationMark(rBookmarkName.copy(0, nPos));
if ( pMark != getAnnotationMarksEnd() )
{
const SwPaM aPam((**iter).GetMarkStart(), (**pMark).GetMarkEnd());
+1
View File
@@ -64,6 +64,7 @@
#include <flowfrm.hxx>
#include <txtfrm.hxx>
#include <annotationmark.hxx>
using namespace com::sun::star;
+7 -6
View File
@@ -31,6 +31,7 @@ class SfxViewShell;
namespace sw::mark {
typedef std::unordered_map<OUString, sal_Int32> MarkBasenameMapUniqueOffset_t;
class AnnotationMark;
class FieldmarkWithDropDownButton;
class MarkManager final
@@ -114,12 +115,12 @@ namespace sw::mark {
void dumpAsXml(xmlTextWriterPtr pWriter) const;
// Annotation Marks
virtual const_iterator getAnnotationMarksBegin() const override;
virtual const_iterator getAnnotationMarksEnd() const override;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator getAnnotationMarksBegin() const override;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator getAnnotationMarksEnd() const override;
virtual sal_Int32 getAnnotationMarksCount() const override;
virtual const_iterator findAnnotationMark( const OUString& rName ) const override;
virtual sw::mark::MarkBase* getAnnotationMarkFor(const SwPosition& rPos) const override;
virtual const_iterator findFirstAnnotationStartsAfter(const SwPosition& rPos) const override;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator findAnnotationMark( const OUString& rName ) const override;
virtual sw::mark::AnnotationMark* getAnnotationMarkFor(const SwPosition& rPos) const override;
virtual std::vector<sw::mark::AnnotationMark*>::const_iterator findFirstAnnotationStartsAfter(const SwPosition& rPos) const override;
virtual void assureSortedMarkContainers() const override;
@@ -155,7 +156,7 @@ namespace sw::mark {
mutable MarkBasenameMapUniqueOffset_t m_aMarkBasenameMapUniqueOffset;
// container for annotation marks
container_t m_vAnnotationMarks;
std::vector<sw::mark::AnnotationMark*> m_vAnnotationMarks;
SwDoc& m_rDoc;
+1 -1
View File
@@ -782,7 +782,7 @@ SwTextAnnotationField::~SwTextAnnotationField()
{
}
::sw::mark::MarkBase* SwTextAnnotationField::GetAnnotationMark() const
::sw::mark::AnnotationMark* SwTextAnnotationField::GetAnnotationMark() const
{
auto pPostItField = dynamic_cast<const SwPostItField*>(GetFormatField().GetField());
assert(pPostItField);
+1
View File
@@ -85,6 +85,7 @@
#include <vcl/svapp.hxx>
#include <textapi.hxx>
#include <fmtmeta.hxx>
#include <annotationmark.hxx>
#include <vector>
using namespace ::com::sun::star;
+2 -5
View File
@@ -274,11 +274,8 @@ namespace
ppMark != pCandidatesEnd;
++ppMark )
{
::sw::mark::AnnotationMark* const pAnnotationMark =
dynamic_cast< ::sw::mark::AnnotationMark* >(*ppMark);
if (!pAnnotationMark)
continue;
::sw::mark::AnnotationMark* const pAnnotationMark = *ppMark;
assert(pAnnotationMark);
const SwPosition& rStartPos = pAnnotationMark->GetMarkStart();
if (rStartPos.GetNode() != rOwnNode)
+2 -1
View File
@@ -110,6 +110,7 @@
#include <ndgrf.hxx>
#include <ndole.hxx>
#include <formatflysplit.hxx>
#include <annotationmark.hxx>
#include <cstdio>
@@ -2068,7 +2069,7 @@ bool MSWordExportBase::GetAnnotationMarks( const SwWW8AttrIter& rAttrs, sal_Int3
const sal_Int32 nMarks = pMarkAccess->getAnnotationMarksCount();
for ( sal_Int32 i = 0; i < nMarks; i++ )
{
MarkBase* pMark = pMarkAccess->getAnnotationMarksBegin()[i];
AnnotationMark* pMark = pMarkAccess->getAnnotationMarksBegin()[i];
// Only keep the bookmarks starting or ending in this node
if ( pMark->GetMarkStart().GetNode() == rNd ||