summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedric.bosdonnat@free.fr>2012-11-23 17:51:16 +0100
committerAndras Timar <atimar@suse.com>2013-01-13 21:59:41 +0100
commit71c485a99640b366aa511b0b27f4b0207f2b1db5 (patch)
treeae5c24f4b4e1ab66870082dbffb8612633d75554
parentc46c8164c5ad8c8c2aee72f5ee3bd73eeef59e06 (diff)
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 <mstahl@redhat.com>
-rw-r--r--sw/source/core/doc/notxtfrm.cxx2
-rw-r--r--sw/source/core/inc/cellfrm.hxx2
-rw-r--r--sw/source/core/inc/flyfrm.hxx2
-rw-r--r--sw/source/core/inc/frame.hxx2
-rw-r--r--sw/source/core/inc/layfrm.hxx2
-rw-r--r--sw/source/core/inc/notxtfrm.hxx2
-rw-r--r--sw/source/core/inc/pagefrm.hxx2
-rw-r--r--sw/source/core/inc/rootfrm.hxx2
-rw-r--r--sw/source/core/inc/txtfrm.hxx2
-rw-r--r--sw/source/core/layout/trvlfrm.cxx96
-rw-r--r--sw/source/core/layout/unusedf.cxx2
-rw-r--r--sw/source/core/text/frmcrsr.cxx2
12 files changed, 77 insertions, 41 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index d3ca641ff1bf..f116e119801f 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -609,7 +609,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 0bc62ae8059a..958806efc869 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 170064e1b1c9..635451be726f 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 e2213cfecf0b..729d35819ca7 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -786,7 +786,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 4c4e4e68264a..a8d4bc408acc 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 17494b01a7ea..f8c10337f0fe 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 0091e240d067..688ab5b7f510 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 85c2a0718b9a..f71b2eb178ad 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 e8da527c89bc..6e03dda26089 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 ef9ec60c42fb..2ffc033f6b7f 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 d28eb5fedb7a..f12f19cb8fb6 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 1ca379458300..aad6a6decbcf 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 )