Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions

PL_ListenerCoupleCloser Class Reference

When copying a selection from a document, one might have the case where there are matched pairs of markers in the document. More...

#include <pl_ListenerCoupleCloser.h>

Inheritance diagram for PL_ListenerCoupleCloser:
PL_Listener

List of all members.

Classes

struct  AfterContentListener
struct  BeforeContentListener
struct  NullContentListener

Public Member Functions

 PL_ListenerCoupleCloser ()
virtual ~PL_ListenerCoupleCloser ()
void setDelegate (PL_Listener *delegate)
PD_DocumentgetDocument (void)
void setDocument (PD_Document *pDoc)
void reset ()
virtual bool populate (fl_ContainerLayout *sfh, const PX_ChangeRecord *pcr)
virtual bool populateStrux (pf_Frag_Strux *sdh, const PX_ChangeRecord *pcr, fl_ContainerLayout **psfh)
PL_FinishingListenergetAfterContentListener ()
PL_FinishingListenergetBeforeContentListener ()
PL_FinishingListenergetNullContentListener ()
virtual bool change (fl_ContainerLayout *, const PX_ChangeRecord *)
virtual bool insertStrux (fl_ContainerLayout *, const PX_ChangeRecord *, pf_Frag_Strux *, PL_ListenerId, void(*)(pf_Frag_Strux *sdhNew, PL_ListenerId lid, fl_ContainerLayout *sfhNew))
virtual bool signal (UT_uint32)

Protected Types

typedef std::list< std::string > stringlist_t

Protected Member Functions

bool shouldClose (const std::string &id, bool isEnd, stringlist_t &sl)
bool shouldOpen (const std::string &id, bool isEnd, stringlist_t &sl)
void trackOpenClose (const std::string &id, bool isEnd, stringlist_t &unclosed, stringlist_t &unopened)

Protected Attributes

PD_Documentm_pDocument
PL_Listenerm_delegate
stringlist_t m_rdfUnclosedAnchorStack
stringlist_t m_rdfUnopenedAnchorStack
stringlist_t m_bookmarkUnclosedStack
stringlist_t m_bookmarkUnopenedStack
AfterContentListener m_AfterContentListener
BeforeContentListener m_BeforeContentListener
NullContentListener m_NullContentListener

Private Member Functions

virtual bool populateAfter (fl_ContainerLayout *sfh, const PX_ChangeRecord *pcr)
virtual bool populateStruxAfter (pf_Frag_Strux *sdh, const PX_ChangeRecord *pcr, fl_ContainerLayout **psfh)
virtual bool populateBefore (fl_ContainerLayout *sfh, const PX_ChangeRecord *pcr)
virtual bool populateStruxBefore (pf_Frag_Strux *sdh, const PX_ChangeRecord *pcr, fl_ContainerLayout **psfh)

Detailed Description

When copying a selection from a document, one might have the case where there are matched pairs of markers in the document.

When only one of the pair of markers is in the selection to copy, a simple copy using a listener on just that range will likely output an invalid document.

Consider the document below with the selection highlighted below it. If one attaches a pl_listener and calls PD_Document::tellListenerSubset() they will only see the bm-start tag. To generate a valid document, a listener would have to remember which pair tags are still open and close them in an appropriate order.

This is some text <bm-start>I can jump here<bm-end> ^-------------------------^

The closer class maintains a reference to the document and a delegate listener. The delegate listener will see all the populate() calls for the given document range, and then the closer will call populate() on the delegate for tags which are open in the range but not closed in the range. And the converse, where a tag is closed in the range but opened before the start of the range.

For the above document fragment, the delegate will the following because they are in the selected document range: " text " <bm-start> "I can jump"

From there the closer will find the matching <bm-end> and call delegate->populate(). So the delegate will see something like the following as the selection and have matched start and end bookmark tags.

text <bm-start>I can jump<bm-end>

Having this functionality in a separate closer class allows for extension by inheritance, and allows tellListenerSubset() to handle cases that one might not consider right off the bat, such as the following where the missing matching tag is actually before the selected range. In this case the closer will emit the required matching populate(bm-start) before the selected document content. Handling open tags before the range is a bit tricky because the call to delegate->populate() must be in document order and not the reverse order that might be used to step backwards from the desired range. This scenario is handled for you with the PL_ListenerCoupleCloser and pt_PieceTable::tellListenerSubset(): The delegate listener only ever sees items once, and in document ordering.

Some text <bm-start>I can jump here<bm-end> and then more waffle ^-------------------------^

While all range cases might not be covered right now, this class is a good foundation for adding new cases as they are found such that all listeners can benefit from proper closed ranges.

This class can be passed as the "closer" parameter to PD_Document::tellListenerSubset() and maintains the open/closed state of matched tags. Once the document range has been visited PD_Document::tellListenerSubset() calls methods like populateClose() in the closer which in turn might call populate() on the delegate listener.


Member Typedef Documentation

typedef std::list< std::string > PL_ListenerCoupleCloser::stringlist_t [protected]

Constructor & Destructor Documentation

PL_ListenerCoupleCloser::PL_ListenerCoupleCloser (  ) 
PL_ListenerCoupleCloser::~PL_ListenerCoupleCloser (  )  [virtual]

Member Function Documentation

virtual bool PL_ListenerCoupleCloser::change ( fl_ContainerLayout ,
const PX_ChangeRecord  
) [inline, virtual]

Implements PL_Listener.

PL_FinishingListener * PL_ListenerCoupleCloser::getAfterContentListener (  ) 
PL_FinishingListener * PL_ListenerCoupleCloser::getBeforeContentListener (  ) 
PD_Document * PL_ListenerCoupleCloser::getDocument ( void   ) 

References m_pDocument.

Referenced by populate(), populateAfter(), and populateBefore().

PL_FinishingListener * PL_ListenerCoupleCloser::getNullContentListener (  ) 
virtual bool PL_ListenerCoupleCloser::insertStrux ( fl_ContainerLayout ,
const PX_ChangeRecord ,
pf_Frag_Strux ,
PL_ListenerId  ,
void(*)(pf_Frag_Strux *sdhNew,PL_ListenerId lid,fl_ContainerLayout *sfhNew)   
) [inline, virtual]

Implements PL_Listener.

bool PL_ListenerCoupleCloser::populateStrux ( pf_Frag_Strux sdh,
const PX_ChangeRecord pcr,
fl_ContainerLayout **  psfh 
) [virtual]
bool PL_ListenerCoupleCloser::populateStruxAfter ( pf_Frag_Strux sdh,
const PX_ChangeRecord pcr,
fl_ContainerLayout **  psfh 
) [private, virtual]
bool PL_ListenerCoupleCloser::populateStruxBefore ( pf_Frag_Strux sdh,
const PX_ChangeRecord pcr,
fl_ContainerLayout **  psfh 
) [private, virtual]
void PL_ListenerCoupleCloser::reset ( void   ) 
void PL_ListenerCoupleCloser::setDelegate ( PL_Listener delegate  ) 

References m_delegate.

Referenced by pt_PieceTable::tellListenerSubset().

void PL_ListenerCoupleCloser::setDocument ( PD_Document pDoc  ) 
bool PL_ListenerCoupleCloser::shouldClose ( const std::string &  id,
bool  isEnd,
stringlist_t sl 
) [protected]

Referenced by populateAfter().

bool PL_ListenerCoupleCloser::shouldOpen ( const std::string &  id,
bool  isEnd,
stringlist_t sl 
) [protected]

Referenced by populateBefore().

virtual bool PL_ListenerCoupleCloser::signal ( UT_uint32   )  [inline, virtual]

Implements PL_Listener.

void PL_ListenerCoupleCloser::trackOpenClose ( const std::string &  id,
bool  isEnd,
stringlist_t unclosed,
stringlist_t unopened 
) [protected]

Referenced by populate().


Member Data Documentation


The documentation for this class was generated from the following files: