summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-10-30 11:06:52 +0100
committerLuboš Luňák <l.lunak@collabora.com>2014-11-14 13:25:39 +0100
commit6b4e5d0acd28a1ccbfad666fa39febf099c364b1 (patch)
treed042478ba0b508fb8dac351770a83a7af1339be8
parentacb201e5e874443dde7cb80a069a8722be7ce4fa (diff)
sw: add API that provides fast access to marks of a text node
sw::mark::MarkManager already provides two methods to provide not so slow mark access: - some marks (bookmarks, annotation marks) have their own container, so it's possible to iterate over only those types, not all of them - the containers are sorted by the start position of the marks, so it's easy to ignore marks that are after the current text node However, it's not possible to ignore marks ending before the current text node. This is a problem, as e.g. during ODF export, we have to iterate over every bookmark for each paragraph, so the operation is not linear. On the other hand, the start and end position of bookmarks are stored using SwPosition, and the SwIndex of the SwPosition is already registered in the SwIndexReg of the SwTxtNode, so the text node sort of already knows what bookmarks start/end at the current paragraph, it just doesn't known which position belongs to what mark (if it belongs to a mark). Fix the problem by adding a pointer to SwIndex that can optionally point back to the mark that owns it. Also, in the sw::mark::MarkBase methods (which are the only ones allowed to touch those positions) always set that pointer. With this, it's possible to get the bookmarks of a node (list of bookmarks which start or end in the current node) in a much faster way for text nodes. Conflicts: sw/inc/index.hxx sw/source/core/bastyp/index.cxx Change-Id: I7ceeff4dce852b4d72f2a73ae6a2423c7a781e41
-rw-r--r--sw/inc/index.hxx14
-rw-r--r--sw/source/core/bastyp/index.cxx9
-rw-r--r--sw/source/core/crsr/bookmrk.cxx3
3 files changed, 25 insertions, 1 deletions
diff --git a/sw/inc/index.hxx b/sw/inc/index.hxx
index e664538a285a..a53839121207 100644
--- a/sw/inc/index.hxx
+++ b/sw/inc/index.hxx
@@ -39,6 +39,12 @@ struct SwPosition;
#define INLINE inline
#endif
+namespace sw {
+namespace mark {
+class IMark;
+}
+}
+
/// Marks a character position inside a document model node.
class SW_DLLPUBLIC SwIndex
{
@@ -51,6 +57,9 @@ private:
SwIndex * m_pNext;
SwIndex * m_pPrev;
+ /// Pointer to a mark that owns this position to allow fast lookup of marks of an SwIndexReg.
+ const sw::mark::IMark* m_pMark;
+
SwIndex& ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue );
void Init(xub_StrLen const nIdx);
void Remove();
@@ -105,6 +114,10 @@ public:
// Returns pointer to IndexArray (for RTTI at SwIndexReg).
const SwIndexReg* GetIdxReg() const { return m_pIndexReg; }
+ const SwIndex* GetNext() const { return m_pNext; }
+
+ const sw::mark::IMark* GetMark() const { return m_pMark; }
+ void SetMark(const sw::mark::IMark* pMark);
};
#undef INLINE
@@ -134,6 +147,7 @@ public:
TYPEINFO();
void MoveTo( SwIndexReg& rArr );
+ const SwIndex* GetFirstIndex() const { return m_pFirst; }
};
diff --git a/sw/source/core/bastyp/index.cxx b/sw/source/core/bastyp/index.cxx
index 880998a199ff..1689477d5959 100644
--- a/sw/source/core/bastyp/index.cxx
+++ b/sw/source/core/bastyp/index.cxx
@@ -35,6 +35,7 @@ SwIndex::SwIndex(SwIndexReg *const pReg, xub_StrLen const nIdx)
, m_pIndexReg( pReg )
, m_pNext( 0 )
, m_pPrev( 0 )
+ , m_pMark( 0 )
{
Init(m_nIndex);
}
@@ -43,6 +44,7 @@ SwIndex::SwIndex( const SwIndex& rIdx, short nDiff )
: m_pIndexReg( rIdx.m_pIndexReg )
, m_pNext( 0 )
, m_pPrev( 0 )
+ , m_pMark( 0 )
{
ChgValue( rIdx, rIdx.m_nIndex + nDiff );
}
@@ -52,6 +54,7 @@ SwIndex::SwIndex( const SwIndex& rIdx )
, m_pIndexReg( rIdx.m_pIndexReg )
, m_pNext( 0 )
, m_pPrev( 0 )
+ , m_pMark( 0 )
{
ChgValue( rIdx, rIdx.m_nIndex );
}
@@ -213,10 +216,14 @@ SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx )
return *this;
}
+void SwIndex::SetMark(const sw::mark::IMark* pMark)
+{
+ m_pMark = pMark;
+}
+
// ----------
// SwIndexReg
// ----------
-
SwIndexReg::SwIndexReg()
: m_pFirst( 0 ), m_pLast( 0 )
{
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 09f3438ccb3c..81256fd6675a 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -133,6 +133,7 @@ namespace sw { namespace mark
, m_pPos1(new SwPosition(*(aPaM.GetPoint())))
, m_aName(rName)
{
+ m_pPos1->nContent.SetMark(this);
lcl_FixPosition(*m_pPos1);
if (aPaM.HasMark() && (*aPaM.GetMark() != *aPaM.GetPoint()))
{
@@ -152,11 +153,13 @@ namespace sw { namespace mark
void MarkBase::SetMarkPos(const SwPosition& rNewPos)
{
::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos1);
+ m_pPos1->nContent.SetMark(this);
}
void MarkBase::SetOtherMarkPos(const SwPosition& rNewPos)
{
::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos2);
+ m_pPos2->nContent.SetMark(this);
}
OUString MarkBase::ToString( ) const