summaryrefslogtreecommitdiff
path: root/sw/source/core
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2019-05-07 17:22:41 +0200
committerLászló Németh <nemeth@numbertext.org>2019-05-08 11:45:49 +0200
commit91b2239783dc716bd71ce7962bfd7e341dfe4175 (patch)
tree8d819f2b9cd829a6ff5d7ac7b97fac35a91bc5a3 /sw/source/core
parent230cb99604aba01153d713ff86e7f8175792ac68 (diff)
tdf#116501 fix freezing at embedded text tables
by disabling their in-row splitting using loop control. Change-Id: Ibd93213fa0ce45458ce188de20da982e4abc17c5 Reviewed-on: https://gerrit.libreoffice.org/71920 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw/source/core')
-rw-r--r--sw/source/core/inc/layact.hxx5
-rw-r--r--sw/source/core/inc/tabfrm.hxx10
-rw-r--r--sw/source/core/layout/layact.cxx21
-rw-r--r--sw/source/core/layout/tabfrm.cxx4
4 files changed, 38 insertions, 2 deletions
diff --git a/sw/source/core/inc/layact.hxx b/sw/source/core/inc/layact.hxx
index 8f5960837031..1253233778e6 100644
--- a/sw/source/core/inc/layact.hxx
+++ b/sw/source/core/inc/layact.hxx
@@ -95,6 +95,11 @@ class SwLayAction
// OD 14.04.2003 #106346# - new flag for content formatting on interrupt.
bool mbFormatContentOnInterrupt;
+ // for loop control by disabling in-row splitting within embedded tables
+ const SwPageFrame *m_pCurPage;
+ sal_uInt16 m_nTabLevel; // embedding level
+ sal_uInt32 m_nCallCount; // calling FormatLayoutTab on the same page
+
void PaintContent( const SwContentFrame *, const SwPageFrame *,
const SwRect &rOldRect, long nOldBottom );
bool PaintWithoutFlys( const SwRect &, const SwContentFrame *,
diff --git a/sw/source/core/inc/tabfrm.hxx b/sw/source/core/inc/tabfrm.hxx
index 176396c6667a..cc57d46d8492 100644
--- a/sw/source/core/inc/tabfrm.hxx
+++ b/sw/source/core/inc/tabfrm.hxx
@@ -84,6 +84,8 @@ class SwTabFrame: public SwLayoutFrame, public SwFlowFrame
bool m_bInRecalcLowerRow : 1;
+ bool m_bSplitRowDisabled : 1; // loop control
+
/**
* Split() splits the Frame at the specified position: a Follow is
* created and constructed and inserted directly after this.
@@ -173,6 +175,14 @@ public:
{
m_bInRecalcLowerRow = bNew;
}
+ bool IsSplitRowDisabled() const
+ {
+ return m_bSplitRowDisabled;
+ }
+ void SetSplitRowDisabled()
+ {
+ m_bSplitRowDisabled = true;
+ }
// #i26945#
bool IsConsiderObjsForMinCellHeight() const
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index 8e02e75e9362..c58261786a6b 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -258,7 +258,10 @@ SwLayAction::SwLayAction( SwRootFrame *pRt, SwViewShellImp *pI ) :
m_nStartTicks( std::clock() ),
m_nInputType( VclInputFlags::NONE ),
m_nEndPage( USHRT_MAX ),
- m_nCheckPageNum( USHRT_MAX )
+ m_nCheckPageNum( USHRT_MAX ),
+ m_pCurPage( nullptr ),
+ m_nTabLevel( 0 ),
+ m_nCallCount( 0 )
{
m_bPaintExtraData = ::IsExtraData( m_pImp->GetShell()->GetDoc() );
m_bPaint = m_bComplete = m_bWaitAllowed = m_bCheckPages = true;
@@ -286,6 +289,7 @@ void SwLayAction::Reset()
m_bPaint = m_bComplete = m_bWaitAllowed = m_bCheckPages = true;
m_bInput = m_bAgain = m_bNextCycle = m_bCalcLayout = m_bIdle = m_bReschedule =
m_bUpdateExpFields = m_bBrowseActionStop = false;
+ m_pCurPage = nullptr;
}
bool SwLayAction::RemoveEmptyBrowserPages()
@@ -1172,6 +1176,12 @@ bool SwLayAction::IsShortCut( SwPageFrame *&prPage )
// introduce support for vertical layout
bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLay, bool bAddRect )
{
+ // save page for loop control
+ if( pLay->IsPageFrame() && static_cast<SwPageFrame*>(pLay) != m_pCurPage )
+ {
+ m_nCallCount = 0;
+ m_pCurPage = static_cast<SwPageFrame*>(pLay);
+ }
OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
if ( IsAgain() )
return false;
@@ -1351,7 +1361,16 @@ bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLa
if ( pLow->IsLayoutFrame() )
{
if ( pLow->IsTabFrame() )
+ {
+ // loop control for embedded tables
+ if ( m_nTabLevel > 0 && ++m_nCallCount > 50 ) {
+ static_cast<SwTabFrame*>(pLow)->SetSplitRowDisabled();
+ }
+
+ ++m_nTabLevel;
bTabChanged |= FormatLayoutTab( static_cast<SwTabFrame*>(pLow), bAddRect );
+ --m_nTabLevel;
+ }
// Skip the ones already registered for deletion
else if( !pLow->IsSctFrame() || static_cast<SwSectionFrame*>(pLow)->GetSection() )
bChanged |= FormatLayout( pRenderContext, static_cast<SwLayoutFrame*>(pLow), bAddRect );
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 060a8dcf6de3..a9667a964308 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -80,6 +80,7 @@ SwTabFrame::SwTabFrame( SwTable &rTab, SwFrame* pSib )
, m_bConsiderObjsForMinCellHeight(true)
, m_bObjsDoesFit(true)
, m_bInRecalcLowerRow(false)
+ , m_bSplitRowDisabled(false)
{
mbFixSize = false; //Don't fall for import filter again.
mnFrameType = SwFrameType::Tab;
@@ -118,6 +119,7 @@ SwTabFrame::SwTabFrame( SwTabFrame &rTab )
, m_bConsiderObjsForMinCellHeight(true)
, m_bObjsDoesFit(true)
, m_bInRecalcLowerRow(false)
+ , m_bSplitRowDisabled(false)
{
mbFixSize = false; //Don't fall for import filter again.
mnFrameType = SwFrameType::Tab;
@@ -1018,7 +1020,7 @@ bool SwTabFrame::Split( const SwTwips nCutPos, bool bTryToSplit, bool bTableRowK
// table, or it will be set to false under certain
// conditions that are not suitable for splitting
// the row.
- bool bSplitRowAllowed = pRow->IsRowSplitAllowed();
+ bool bSplitRowAllowed = pRow->IsRowSplitAllowed() && !IsSplitRowDisabled();
// #i29438#
// #i26945# - Floating screen objects no longer forbid