fdo#74087: Inspect if a mis-spelled word is at cursor position...
then decide whether to launch a spell candidate menu or a regular context menu. Change-Id: Ib121e9c6729e068c70ff216391f863639aa01951
This commit is contained in:
@@ -271,6 +271,8 @@ class ScGridWindow : public Window, public DropTargetHelper, public DragSourceHe
|
|||||||
bool GetEditUrl( const Point& rPos,
|
bool GetEditUrl( const Point& rPos,
|
||||||
OUString* pName=0, OUString* pUrl=0, OUString* pTarget=0 );
|
OUString* pName=0, OUString* pUrl=0, OUString* pTarget=0 );
|
||||||
|
|
||||||
|
bool IsSpellErrorAtPos( const Point& rPos, SCCOL nCol1, SCCOL nCol2, SCROW nRow );
|
||||||
|
|
||||||
bool HitRangeFinder( const Point& rMouse, RfCorner& rCorner, sal_uInt16* pIndex = NULL,
|
bool HitRangeFinder( const Point& rMouse, RfCorner& rCorner, sal_uInt16* pIndex = NULL,
|
||||||
SCsCOL* pAddX = NULL, SCsROW* pAddY = NULL );
|
SCsCOL* pAddX = NULL, SCsROW* pAddY = NULL );
|
||||||
|
|
||||||
|
@@ -136,6 +136,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
using namespace com::sun::star;
|
using namespace com::sun::star;
|
||||||
using ::com::sun::star::uno::Sequence;
|
using ::com::sun::star::uno::Sequence;
|
||||||
@@ -2940,6 +2941,10 @@ void ScGridWindow::Command( const CommandEvent& rCEvt )
|
|||||||
SCsROW nCellY = -1;
|
SCsROW nCellY = -1;
|
||||||
pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
|
pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
|
||||||
|
|
||||||
|
bool bSpellError = false;
|
||||||
|
SCCOL nColSpellError = nCellX;
|
||||||
|
ScRefCellValue aSpellCheckCell;
|
||||||
|
|
||||||
if ( bMouse )
|
if ( bMouse )
|
||||||
{
|
{
|
||||||
ScDocument* pDoc = pViewData->GetDocument();
|
ScDocument* pDoc = pViewData->GetDocument();
|
||||||
@@ -2962,14 +2967,39 @@ void ScGridWindow::Command( const CommandEvent& rCEvt )
|
|||||||
// Selecting this cell is not allowed, neither is context menu.
|
// Selecting this cell is not allowed, neither is context menu.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (mpSpellCheckCxt)
|
||||||
|
{
|
||||||
|
// Find the first string to the left for spell checking in case the current cell is empty.
|
||||||
|
ScAddress aPos(nCellX, nCellY, nTab);
|
||||||
|
aSpellCheckCell.assign(*pDoc, aPos);
|
||||||
|
while (aSpellCheckCell.meType == CELLTYPE_NONE)
|
||||||
|
{
|
||||||
|
// Loop until we get the first non-empty cell in the row.
|
||||||
|
aPos.IncCol(-1);
|
||||||
|
if (aPos.Col() < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
aSpellCheckCell.assign(*pDoc, aPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aPos.Col() >= 0 && (aSpellCheckCell.meType == CELLTYPE_STRING || aSpellCheckCell.meType == CELLTYPE_EDIT))
|
||||||
|
nColSpellError = aPos.Col();
|
||||||
|
|
||||||
|
bSpellError = (mpSpellCheckCxt->isMisspelled(nColSpellError, nCellY));
|
||||||
|
if (bSpellError)
|
||||||
|
{
|
||||||
|
// Check and see if a misspelled word is under the mouse pointer.
|
||||||
|
bSpellError = IsSpellErrorAtPos(aPosPixel, nColSpellError, nCellX, nCellY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #i18735# First select the item under the mouse pointer.
|
// #i18735# First select the item under the mouse pointer.
|
||||||
// This can change the selection, and the view state (edit mode, etc).
|
// This can change the selection, and the view state (edit mode, etc).
|
||||||
SelectForContextMenu( aPosPixel, nCellX, nCellY );
|
SelectForContextMenu(aPosPixel, bSpellError ? nColSpellError : nCellX, nCellY);
|
||||||
}
|
}
|
||||||
|
|
||||||
sal_Bool bDone = false;
|
bool bDone = false;
|
||||||
sal_Bool bEdit = pViewData->HasEditView(eWhich);
|
bool bEdit = pViewData->HasEditView(eWhich);
|
||||||
bool bSpellError = (mpSpellCheckCxt && mpSpellCheckCxt->isMisspelled(nCellX, nCellY));
|
|
||||||
|
|
||||||
if ( !bEdit )
|
if ( !bEdit )
|
||||||
{
|
{
|
||||||
@@ -5091,6 +5121,54 @@ void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, bool bUp )
|
|||||||
pViewData->GetView()->ResetTimer();
|
pViewData->GetView()->ResetTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
SvxAdjust toSvxAdjust( const ScPatternAttr& rPat )
|
||||||
|
{
|
||||||
|
SvxCellHorJustify eHorJust =
|
||||||
|
static_cast<SvxCellHorJustify>(
|
||||||
|
static_cast<const SvxHorJustifyItem&>(rPat.GetItem(ATTR_HOR_JUSTIFY)).GetValue());
|
||||||
|
|
||||||
|
SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
|
||||||
|
switch (eHorJust)
|
||||||
|
{
|
||||||
|
case SVX_HOR_JUSTIFY_LEFT:
|
||||||
|
case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
|
||||||
|
case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type
|
||||||
|
eSvxAdjust = SVX_ADJUST_LEFT;
|
||||||
|
break;
|
||||||
|
case SVX_HOR_JUSTIFY_RIGHT:
|
||||||
|
eSvxAdjust = SVX_ADJUST_RIGHT;
|
||||||
|
break;
|
||||||
|
case SVX_HOR_JUSTIFY_CENTER:
|
||||||
|
eSvxAdjust = SVX_ADJUST_CENTER;
|
||||||
|
break;
|
||||||
|
case SVX_HOR_JUSTIFY_BLOCK:
|
||||||
|
eSvxAdjust = SVX_ADJUST_BLOCK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return eSvxAdjust;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<ScFieldEditEngine> createEditEngine( ScDocShell* pDocSh, const ScPatternAttr& rPat )
|
||||||
|
{
|
||||||
|
ScDocument* pDoc = pDocSh->GetDocument();
|
||||||
|
|
||||||
|
boost::shared_ptr<ScFieldEditEngine> pEngine(new ScFieldEditEngine(pDoc, pDoc->GetEditPool()));
|
||||||
|
ScSizeDeviceProvider aProv(pDocSh);
|
||||||
|
pEngine->SetRefDevice(aProv.GetDevice());
|
||||||
|
pEngine->SetRefMapMode(MAP_100TH_MM);
|
||||||
|
SfxItemSet aDefault = pEngine->GetEmptyItemSet();
|
||||||
|
rPat.FillEditItemSet(&aDefault);
|
||||||
|
aDefault.Put( SvxAdjustItem(toSvxAdjust(rPat), EE_PARA_JUST) );
|
||||||
|
pEngine->SetDefaults(aDefault);
|
||||||
|
|
||||||
|
return pEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool ScGridWindow::GetEditUrl( const Point& rPos,
|
bool ScGridWindow::GetEditUrl( const Point& rPos,
|
||||||
OUString* pName, OUString* pUrl, OUString* pTarget )
|
OUString* pName, OUString* pUrl, OUString* pTarget )
|
||||||
{
|
{
|
||||||
@@ -5127,32 +5205,7 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
|||||||
|
|
||||||
// EditEngine
|
// EditEngine
|
||||||
|
|
||||||
ScFieldEditEngine aEngine(pDoc, pDoc->GetEditPool());
|
boost::shared_ptr<ScFieldEditEngine> pEngine = createEditEngine(pDocSh, *pPattern);
|
||||||
ScSizeDeviceProvider aProv(pDocSh);
|
|
||||||
aEngine.SetRefDevice( aProv.GetDevice() );
|
|
||||||
aEngine.SetRefMapMode( MAP_100TH_MM );
|
|
||||||
SfxItemSet aDefault( aEngine.GetEmptyItemSet() );
|
|
||||||
pPattern->FillEditItemSet( &aDefault );
|
|
||||||
SvxAdjust eSvxAdjust = SVX_ADJUST_LEFT;
|
|
||||||
switch (eHorJust)
|
|
||||||
{
|
|
||||||
case SVX_HOR_JUSTIFY_LEFT:
|
|
||||||
case SVX_HOR_JUSTIFY_REPEAT: // nicht implementiert
|
|
||||||
case SVX_HOR_JUSTIFY_STANDARD: // always Text if an EditCell type
|
|
||||||
eSvxAdjust = SVX_ADJUST_LEFT;
|
|
||||||
break;
|
|
||||||
case SVX_HOR_JUSTIFY_RIGHT:
|
|
||||||
eSvxAdjust = SVX_ADJUST_RIGHT;
|
|
||||||
break;
|
|
||||||
case SVX_HOR_JUSTIFY_CENTER:
|
|
||||||
eSvxAdjust = SVX_ADJUST_CENTER;
|
|
||||||
break;
|
|
||||||
case SVX_HOR_JUSTIFY_BLOCK:
|
|
||||||
eSvxAdjust = SVX_ADJUST_BLOCK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
aDefault.Put( SvxAdjustItem( eSvxAdjust, EE_PARA_JUST ) );
|
|
||||||
aEngine.SetDefaults( aDefault );
|
|
||||||
|
|
||||||
MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
|
MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
|
||||||
Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
|
Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
|
||||||
@@ -5169,13 +5222,13 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
|||||||
|
|
||||||
if (bBreak)
|
if (bBreak)
|
||||||
aPaperSize.Width() = nThisColLogic;
|
aPaperSize.Width() = nThisColLogic;
|
||||||
aEngine.SetPaperSize( aPaperSize );
|
pEngine->SetPaperSize( aPaperSize );
|
||||||
|
|
||||||
boost::scoped_ptr<EditTextObject> pTextObj;
|
boost::scoped_ptr<EditTextObject> pTextObj;
|
||||||
if (aCell.meType == CELLTYPE_EDIT)
|
if (aCell.meType == CELLTYPE_EDIT)
|
||||||
{
|
{
|
||||||
if (aCell.mpEditText)
|
if (aCell.mpEditText)
|
||||||
aEngine.SetText(*aCell.mpEditText);
|
pEngine->SetText(*aCell.mpEditText);
|
||||||
}
|
}
|
||||||
else // Not an Edit cell and is a formula cell with 'Hyperlink'
|
else // Not an Edit cell and is a formula cell with 'Hyperlink'
|
||||||
// function if we have no URL, otherwise it could be a formula
|
// function if we have no URL, otherwise it could be a formula
|
||||||
@@ -5187,13 +5240,13 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
|||||||
pTextObj.reset(ScEditUtil::CreateURLObjectFromURL(*pDoc, sURL, sURL));
|
pTextObj.reset(ScEditUtil::CreateURLObjectFromURL(*pDoc, sURL, sURL));
|
||||||
|
|
||||||
if (pTextObj.get())
|
if (pTextObj.get())
|
||||||
aEngine.SetText(*pTextObj);
|
pEngine->SetText(*pTextObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
long nStartX = aLogicEdit.Left();
|
long nStartX = aLogicEdit.Left();
|
||||||
|
|
||||||
long nTextWidth = aEngine.CalcTextWidth();
|
long nTextWidth = pEngine->CalcTextWidth();
|
||||||
long nTextHeight = aEngine.GetTextHeight();
|
long nTextHeight = pEngine->GetTextHeight();
|
||||||
if ( nTextWidth < nThisColLogic )
|
if ( nTextWidth < nThisColLogic )
|
||||||
{
|
{
|
||||||
if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
|
if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
|
||||||
@@ -5221,7 +5274,7 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
|||||||
Point aLogicClick = PixelToLogic(rPos,aEditMode);
|
Point aLogicClick = PixelToLogic(rPos,aEditMode);
|
||||||
if ( aLogicEdit.IsInside(aLogicClick) )
|
if ( aLogicEdit.IsInside(aLogicClick) )
|
||||||
{
|
{
|
||||||
EditView aTempView( &aEngine, this );
|
EditView aTempView(pEngine.get(), this);
|
||||||
aTempView.SetOutputArea( aLogicEdit );
|
aTempView.SetOutputArea( aLogicEdit );
|
||||||
|
|
||||||
sal_Bool bRet = false;
|
sal_Bool bRet = false;
|
||||||
@@ -5255,6 +5308,61 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScGridWindow::IsSpellErrorAtPos( const Point& rPos, SCCOL nCol1, SCCOL nCol2, SCROW nRow )
|
||||||
|
{
|
||||||
|
if (!mpSpellCheckCxt)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SCTAB nTab = pViewData->GetTabNo();
|
||||||
|
ScDocShell* pDocSh = pViewData->GetDocShell();
|
||||||
|
ScDocument* pDoc = pDocSh->GetDocument();
|
||||||
|
|
||||||
|
ScAddress aCellPos(nCol1, nRow, nTab);
|
||||||
|
ScRefCellValue aCell;
|
||||||
|
aCell.assign(*pDoc, aCellPos);
|
||||||
|
if (aCell.meType != CELLTYPE_STRING && aCell.meType != CELLTYPE_EDIT)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const std::vector<editeng::MisspellRanges>* pRanges = mpSpellCheckCxt->getMisspellRanges(nCol1, nRow);
|
||||||
|
if (!pRanges)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const ScPatternAttr* pPattern = pDoc->GetPattern(nCol1, nRow, nTab);
|
||||||
|
|
||||||
|
Rectangle aEditRect = pViewData->GetEditArea(eWhich, nCol1, nRow, this, pPattern, false);
|
||||||
|
if (rPos.Y() < aEditRect.Top())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Rectangle aEditRect2 = pViewData->GetEditArea(eWhich, nCol2, nRow, this, pPattern, false);
|
||||||
|
long nExt = aEditRect2.Left() - aEditRect.Right() + aEditRect2.GetWidth();
|
||||||
|
aEditRect.setWidth(aEditRect.getWidth() + nExt);
|
||||||
|
|
||||||
|
MapMode aEditMode = pViewData->GetLogicMode(eWhich);
|
||||||
|
Rectangle aLogicEdit = PixelToLogic(aEditRect, aEditMode);
|
||||||
|
Point aLogicClick = PixelToLogic(rPos, aEditMode);
|
||||||
|
|
||||||
|
if (!aLogicEdit.IsInside(aLogicClick))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boost::shared_ptr<ScFieldEditEngine> pEngine = createEditEngine(pDocSh, *pPattern);
|
||||||
|
|
||||||
|
Size aPaperSize = Size(1000000, 1000000);
|
||||||
|
pEngine->SetPaperSize(aPaperSize);
|
||||||
|
|
||||||
|
if (aCell.meType == CELLTYPE_EDIT)
|
||||||
|
pEngine->SetText(*aCell.mpEditText);
|
||||||
|
else
|
||||||
|
pEngine->SetText(aCell.mpString->getString());
|
||||||
|
|
||||||
|
pEngine->SetControlWord(pEngine->GetControlWord() | EE_CNTRL_ONLINESPELLING);
|
||||||
|
pEngine->SetAllMisspellRanges(*pRanges);
|
||||||
|
|
||||||
|
EditView aTempView(pEngine.get(), this);
|
||||||
|
aTempView.SetOutputArea(aLogicEdit);
|
||||||
|
|
||||||
|
return aTempView.IsWrongSpelledWordAtPos(rPos);
|
||||||
|
}
|
||||||
|
|
||||||
bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
|
bool ScGridWindow::HasScenarioButton( const Point& rPosPixel, ScRange& rScenRange )
|
||||||
{
|
{
|
||||||
ScDocument* pDoc = pViewData->GetDocument();
|
ScDocument* pDoc = pViewData->GetDocument();
|
||||||
|
Reference in New Issue
Block a user