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,
|
||||
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,
|
||||
SCsCOL* pAddX = NULL, SCsROW* pAddY = NULL );
|
||||
|
||||
|
@@ -136,6 +136,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
using namespace com::sun::star;
|
||||
using ::com::sun::star::uno::Sequence;
|
||||
@@ -2940,6 +2941,10 @@ void ScGridWindow::Command( const CommandEvent& rCEvt )
|
||||
SCsROW nCellY = -1;
|
||||
pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY);
|
||||
|
||||
bool bSpellError = false;
|
||||
SCCOL nColSpellError = nCellX;
|
||||
ScRefCellValue aSpellCheckCell;
|
||||
|
||||
if ( bMouse )
|
||||
{
|
||||
ScDocument* pDoc = pViewData->GetDocument();
|
||||
@@ -2962,14 +2967,39 @@ void ScGridWindow::Command( const CommandEvent& rCEvt )
|
||||
// Selecting this cell is not allowed, neither is context menu.
|
||||
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.
|
||||
// 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;
|
||||
sal_Bool bEdit = pViewData->HasEditView(eWhich);
|
||||
bool bSpellError = (mpSpellCheckCxt && mpSpellCheckCxt->isMisspelled(nCellX, nCellY));
|
||||
bool bDone = false;
|
||||
bool bEdit = pViewData->HasEditView(eWhich);
|
||||
|
||||
if ( !bEdit )
|
||||
{
|
||||
@@ -5091,6 +5121,54 @@ void ScGridWindow::RFMouseMove( const MouseEvent& rMEvt, bool bUp )
|
||||
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,
|
||||
OUString* pName, OUString* pUrl, OUString* pTarget )
|
||||
{
|
||||
@@ -5127,32 +5205,7 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
||||
|
||||
// EditEngine
|
||||
|
||||
ScFieldEditEngine aEngine(pDoc, pDoc->GetEditPool());
|
||||
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 );
|
||||
boost::shared_ptr<ScFieldEditEngine> pEngine = createEditEngine(pDocSh, *pPattern);
|
||||
|
||||
MapMode aEditMode = pViewData->GetLogicMode(eWhich); // ohne Drawing-Skalierung
|
||||
Rectangle aLogicEdit = PixelToLogic( aEditRect, aEditMode );
|
||||
@@ -5169,13 +5222,13 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
||||
|
||||
if (bBreak)
|
||||
aPaperSize.Width() = nThisColLogic;
|
||||
aEngine.SetPaperSize( aPaperSize );
|
||||
pEngine->SetPaperSize( aPaperSize );
|
||||
|
||||
boost::scoped_ptr<EditTextObject> pTextObj;
|
||||
if (aCell.meType == CELLTYPE_EDIT)
|
||||
{
|
||||
if (aCell.mpEditText)
|
||||
aEngine.SetText(*aCell.mpEditText);
|
||||
pEngine->SetText(*aCell.mpEditText);
|
||||
}
|
||||
else // Not an Edit cell and is a formula cell with 'Hyperlink'
|
||||
// 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));
|
||||
|
||||
if (pTextObj.get())
|
||||
aEngine.SetText(*pTextObj);
|
||||
pEngine->SetText(*pTextObj);
|
||||
}
|
||||
|
||||
long nStartX = aLogicEdit.Left();
|
||||
|
||||
long nTextWidth = aEngine.CalcTextWidth();
|
||||
long nTextHeight = aEngine.GetTextHeight();
|
||||
long nTextWidth = pEngine->CalcTextWidth();
|
||||
long nTextHeight = pEngine->GetTextHeight();
|
||||
if ( nTextWidth < nThisColLogic )
|
||||
{
|
||||
if (eHorJust == SVX_HOR_JUSTIFY_RIGHT)
|
||||
@@ -5221,7 +5274,7 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
||||
Point aLogicClick = PixelToLogic(rPos,aEditMode);
|
||||
if ( aLogicEdit.IsInside(aLogicClick) )
|
||||
{
|
||||
EditView aTempView( &aEngine, this );
|
||||
EditView aTempView(pEngine.get(), this);
|
||||
aTempView.SetOutputArea( aLogicEdit );
|
||||
|
||||
sal_Bool bRet = false;
|
||||
@@ -5255,6 +5308,61 @@ bool ScGridWindow::GetEditUrl( const Point& rPos,
|
||||
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 )
|
||||
{
|
||||
ScDocument* pDoc = pViewData->GetDocument();
|
||||
|
Reference in New Issue
Block a user