sw/source/core/doc/notxtfrm.cxx | 2 sw/source/core/inc/cellfrm.hxx | 2 sw/source/core/inc/flyfrm.hxx | 2 sw/source/core/inc/frame.hxx | 2 sw/source/core/inc/layfrm.hxx | 2 sw/source/core/inc/notxtfrm.hxx | 2 sw/source/core/inc/pagefrm.hxx | 2 sw/source/core/inc/rootfrm.hxx | 2 sw/source/core/inc/txtfrm.hxx | 2 sw/source/core/layout/trvlfrm.cxx | 96 ++++++++++++++++++++++++++------------ sw/source/core/layout/unusedf.cxx | 2 sw/source/core/text/frmcrsr.cxx | 2 12 files changed, 77 insertions(+), 41 deletions(-)
New commits: commit d0a4a025855d78cdce194885c4df024c499bade6 Author: Cédric Bosdonnat <cedric.bosdon...@free.fr> Date: Fri Nov 23 17:51:16 2012 +0100 fdo#52182: Fixed click in frames located in header/footer Using a distance to click to select the best object to select between normal text and background object. (cherry picked from commit e8fbe97900f13305b17015d9044993bde4adab36) Conflicts: sw/source/ui/docvw/edtwin.cxx sw/source/ui/inc/edtwin.hxx Change-Id: Ib5b53161c7af2c16f4df379382f2e53fc6d8092b Signed-off-by: Michael Stahl <mst...@redhat.com> diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx index 83b2fa9..99a8ea4 100644 --- a/sw/source/core/doc/notxtfrm.cxx +++ b/sw/source/core/doc/notxtfrm.cxx @@ -598,7 +598,7 @@ sal_Bool SwNoTxtFrm::GetCharRect( SwRect &rRect, const SwPosition& rPos, sal_Bool SwNoTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& , - SwCrsrMoveState* ) const + SwCrsrMoveState*, bool ) const { SwCntntNode* pCNd = (SwCntntNode*)GetNode(); pPos->nNode = *pCNd; diff --git a/sw/source/core/inc/cellfrm.hxx b/sw/source/core/inc/cellfrm.hxx index 0bc62ae..958806e 100644 --- a/sw/source/core/inc/cellfrm.hxx +++ b/sw/source/core/inc/cellfrm.hxx @@ -48,7 +48,7 @@ public: SwCellFrm( const SwTableBox &, SwFrm*, bool bInsertContent = true ); ~SwCellFrm(); - virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, SwCrsrMoveState* = 0 ) const; + virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, SwCrsrMoveState* = 0, bool bTestBackground = false ) const; virtual void Paint( SwRect const&, SwPrintData const*const pPrintData = NULL ) const; virtual void CheckDirection( sal_Bool bVert ); diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx index 170064e..635451b 100644 --- a/sw/source/core/inc/flyfrm.hxx +++ b/sw/source/core/inc/flyfrm.hxx @@ -163,7 +163,7 @@ public: SwPrintData const*const pPrintData = NULL ) const; virtual Size ChgSize( const Size& aNewSize ); virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0 ) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; virtual void CheckDirection( sal_Bool bVert ); virtual void Cut(); diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 3812a29..15c34ef 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -785,7 +785,7 @@ public: virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const; virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0 ) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; virtual sal_Bool GetCharRect( SwRect &, const SwPosition&, SwCrsrMoveState* = 0 ) const; virtual void Paint( SwRect const&, diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx index 4c4e4e6..a8d4bc4 100644 --- a/sw/source/core/inc/layfrm.hxx +++ b/sw/source/core/inc/layfrm.hxx @@ -92,7 +92,7 @@ public: virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const; virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0 ) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; virtual void Cut(); virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 ); diff --git a/sw/source/core/inc/notxtfrm.hxx b/sw/source/core/inc/notxtfrm.hxx index 17494b0..f8c1033 100644 --- a/sw/source/core/inc/notxtfrm.hxx +++ b/sw/source/core/inc/notxtfrm.hxx @@ -61,7 +61,7 @@ public: virtual sal_Bool GetCharRect( SwRect &, const SwPosition&, SwCrsrMoveState* = 0) const; sal_Bool GetCrsrOfst(SwPosition* pPos, Point& aPoint, - SwCrsrMoveState* = 0) const; + SwCrsrMoveState* = 0, bool bTestBackground = false) const; const Size &GetGrfSize() const { return GetSize(); } void GetGrfArea( SwRect &rRect, SwRect * = 0, sal_Bool bMirror = sal_True ) const; diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx index 0091e24..688ab5b 100644 --- a/sw/source/core/inc/pagefrm.hxx +++ b/sw/source/core/inc/pagefrm.hxx @@ -183,7 +183,7 @@ public: void PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt ); virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0 ) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; // erfrage vom Client Informationen virtual sal_Bool GetInfo( SfxPoolItem& ) const; diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx index 85c2a07..f71b2eb 100644 --- a/sw/source/core/inc/rootfrm.hxx +++ b/sw/source/core/inc/rootfrm.hxx @@ -201,7 +201,7 @@ public: void SetDrawPage( SdrPage* pNew ){ pDrawPage = pNew; } virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0 ) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; virtual void Paint( SwRect const&, SwPrintData const*const pPrintData = NULL ) const; diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index e8da527..6e03dda 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -285,7 +285,7 @@ public: //naechsten ist. Wenn der SPoint ausserhalb der SSize liegt, //liefert die Funktion sal_False, sal_True sonst. virtual sal_Bool GetCrsrOfst( SwPosition *, Point&, - SwCrsrMoveState* = 0) const; + SwCrsrMoveState* = 0, bool bTestBackground = false ) const; // GetKeyCrsrOfst sorgt dafuer, dass der Frame nicht gewechselt wird // (z.B. Wechsel in den zeichengebundenen Frame). diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index ef9ec60..2ffc033 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -31,6 +31,7 @@ #include <hintids.hxx> #include <hints.hxx> #include <tools/bigint.hxx> +#include <tools/line.hxx> #include <editeng/opaqitem.hxx> #include <editeng/protitem.hxx> #include <vcl/settings.hxx> @@ -65,9 +66,11 @@ #include <cfloat> #include <swselectionlist.hxx> +#include <basegfx/numeric/ftools.hxx> + namespace { bool lcl_GetCrsrOfst_Objects( const SwPageFrm* pPageFrm, bool bSearchBackground, - SwPosition *pPos, Point& rPoint, SwCrsrMoveState* pCMS, long& rSurface ) + SwPosition *pPos, Point& rPoint, SwCrsrMoveState* pCMS ) { bool bRet = false; Point aPoint( rPoint ); @@ -91,7 +94,6 @@ namespace { !pFly->IsProtected() ) && pFly->GetCrsrOfst( pPos, aPoint, pCMS ) ) { - rSurface = pFly->Frm().Width() * pFly->Frm().Height(); bRet = true; break; } @@ -103,18 +105,19 @@ namespace { return bRet; } - long lcl_GetSurface( SwPosition* pPos ) + double lcl_getDistance( const SwRect& rRect, const Point& rPoint ) { - SwRect aArea; - - SwNode& rNode = pPos->nNode.GetNode(); - - if ( rNode.IsCntntNode() ) - aArea = rNode.GetCntntNode()->FindLayoutRect(); + double nDist = 0.0; - // FIXME Handle the other kinds of nodes? + // If the point is inside the rectangle, then distance is 0 + // Otherwise, compute the distance to the center of the rectangle. + if ( !rRect.IsInside( rPoint ) ) + { + Line aLine( rPoint, rRect.Center( ) ); + nDist = aLine.GetLength( ); + } - return aArea.Height() * aArea.Width(); + return nDist; } } @@ -166,7 +169,7 @@ static SwCrsrOszControl aOszCtrl = { 0, 0, 0 }; |* |*************************************************************************/ sal_Bool SwLayoutFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool ) const { sal_Bool bRet = sal_False; const SwFrm *pFrm = Lower(); @@ -201,7 +204,7 @@ sal_Bool SwLayoutFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, |*************************************************************************/ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool bTestBackground ) const { sal_Bool bRet = sal_False; Point aPoint( rPoint ); @@ -222,14 +225,11 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, //hineinsetzen, dadurch sollten alle Aenderungen unmoeglich sein. if ( GetSortedObjs() ) { - long nObjSurface = 0; // Unused - bRet = lcl_GetCrsrOfst_Objects( this, false, pPos, rPoint, pCMS, nObjSurface ); + bRet = lcl_GetCrsrOfst_Objects( this, false, pPos, rPoint, pCMS ); } if ( !bRet ) { - long nTextSurface = 0; - long nBackSurface = 0; SwPosition aBackPos( *pPos ); SwPosition aTextPos( *pPos ); @@ -238,7 +238,6 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, //aktuellen an. Mit Flys ist es dann allerdings vorbei. if ( SwLayoutFrm::GetCrsrOfst( &aTextPos, aPoint, pCMS ) ) { - nTextSurface = lcl_GetSurface( &aTextPos ); bTextRet = sal_True; } else @@ -252,8 +251,6 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, if ( pCMS && pCMS->bStop ) return sal_False; - nTextSurface = pCnt->Frm().Height() * pCnt->Frm().Width(); - OSL_ENSURE( pCnt, "Crsr is gone to a Black hole" ); if( pCMS && pCMS->pFill && pCnt->IsTxtFrm() ) bTextRet = pCnt->GetCrsrOfst( &aTextPos, rPoint, pCMS ); @@ -272,11 +269,10 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, // Check objects in the background if nothing else matched if ( GetSortedObjs() ) { - bBackRet = lcl_GetCrsrOfst_Objects( this, true, &aBackPos, rPoint, pCMS, nBackSurface ); + bBackRet = lcl_GetCrsrOfst_Objects( this, true, &aBackPos, rPoint, pCMS ); } - // TODO Pick up the best approaching selection - if ( bTextRet && bBackRet && ( nTextSurface > nBackSurface ) ) + if ( ( bTestBackground && bBackRet ) || !bTextRet ) { bRet = bBackRet; pPos->nNode = aBackPos.nNode; @@ -284,9 +280,49 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, } else { - bRet = bTextRet; - pPos->nNode = aTextPos.nNode; - pPos->nContent = aTextPos.nContent; + /* In order to provide a selection as accurable as possible when we have both + * text and brackground object, then we compute the distance between both + * would-be positions and the click point. The shortest distance wins. + */ + SwCntntNode* pTextNd = aTextPos.nNode.GetNode( ).GetCntntNode( ); + double nTextDistance = 0; + bool bValidTextDistance = false; + if ( pTextNd ) + { + SwCntntFrm* pTextFrm = pTextNd->getLayoutFrm( getRootFrm( ) ); + SwRect rTextRect; + pTextFrm->GetCharRect( rTextRect, aTextPos ); + + nTextDistance = lcl_getDistance( rTextRect, rPoint ); + bValidTextDistance = true; + } + + double nBackDistance = 0; + bool bValidBackDistance = false; + SwCntntNode* pBackNd = aBackPos.nNode.GetNode( ).GetCntntNode( ); + if ( pBackNd ) + { + // FIXME There are still cases were we don't have the proper node here. + SwCntntFrm* pBackFrm = pBackNd->getLayoutFrm( getRootFrm( ) ); + SwRect rBackRect; + pBackFrm->GetCharRect( rBackRect, aBackPos ); + + nBackDistance = lcl_getDistance( rBackRect, rPoint ); + bValidBackDistance = true; + } + + if ( bValidTextDistance && bValidBackDistance && basegfx::fTools::more( nTextDistance, nBackDistance ) ) + { + bRet = bBackRet; + pPos->nNode = aBackPos.nNode; + pPos->nContent = aBackPos.nContent; + } + else + { + bRet = bTextRet; + pPos->nNode = aTextPos.nNode; + pPos->nContent = aTextPos.nContent; + } } } @@ -362,7 +398,7 @@ bool SwRootFrm::FillSelection( SwSelectionList& aSelList, const SwRect& rRect) c |* |*************************************************************************/ sal_Bool SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool bTestBackground ) const { sal_Bool bOldAction = IsCallbackActionEnabled(); ((SwRootFrm*)this)->SetCallbackActionEnabled( sal_False ); @@ -389,7 +425,7 @@ sal_Bool SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, } if ( pPage ) { - pPage->SwPageFrm::GetCrsrOfst( pPos, rPoint, pCMS ); + pPage->SwPageFrm::GetCrsrOfst( pPos, rPoint, pCMS, bTestBackground ); } ((SwRootFrm*)this)->SetCallbackActionEnabled( bOldAction ); @@ -414,7 +450,7 @@ sal_Bool SwRootFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, |* |*************************************************************************/ sal_Bool SwCellFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool ) const { // cell frame does not necessarily have a lower (split table cell) if ( !Lower() ) @@ -491,7 +527,7 @@ sal_Bool SwCellFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, //am weitesten oben liegt. sal_Bool SwFlyFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool ) const { aOszCtrl.Entry( this ); diff --git a/sw/source/core/layout/unusedf.cxx b/sw/source/core/layout/unusedf.cxx index d28eb5f..f12f19c 100644 --- a/sw/source/core/layout/unusedf.cxx +++ b/sw/source/core/layout/unusedf.cxx @@ -54,7 +54,7 @@ bool SwFrm::FillSelection( SwSelectionList& , const SwRect& ) const return false; } -sal_Bool SwFrm::GetCrsrOfst( SwPosition *, Point&, SwCrsrMoveState* ) const +sal_Bool SwFrm::GetCrsrOfst( SwPosition *, Point&, SwCrsrMoveState*, bool ) const { OSL_FAIL( "GetCrsrOfst of the base class, hi!" ); return sal_False; diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx index 1ca3794..aad6a6d 100644 --- a/sw/source/core/text/frmcrsr.cxx +++ b/sw/source/core/text/frmcrsr.cxx @@ -684,7 +684,7 @@ sal_Bool SwTxtFrm::_GetCrsrOfst(SwPosition* pPos, const Point& rPoint, *************************************************************************/ sal_Bool SwTxtFrm::GetCrsrOfst(SwPosition* pPos, Point& rPoint, - SwCrsrMoveState* pCMS ) const + SwCrsrMoveState* pCMS, bool ) const { MSHORT nChgFrm = 2; if( pCMS )
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits