Kaydet (Commit) 3f04bfef authored tarafından Jan Holesovsky's avatar Jan Holesovsky

sc tiled editing: Implement long-touch to select word in overflowing text.

Normally, the text overflowing from other cells is completely ignored by Calc,
and the user always works with the underlying cells.

On Android / mobile, it is though more natural to be able to select the text
directly; so implement a compromise:

* tap places the text cursor, so that the user can write into the
  cells hidden by the text too
* long-tap selects the word in the text, even if the text 'just' overflows
  from another cell

Change-Id: Ibe8666301ff1df0414c0206c1f3336842485433b
üst 41c8aeab
...@@ -278,6 +278,14 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou ...@@ -278,6 +278,14 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou
sal_uInt16 HitPageBreak( const Point& rMouse, ScRange* pSource = NULL, sal_uInt16 HitPageBreak( const Point& rMouse, ScRange* pSource = NULL,
SCCOLROW* pBreak = NULL, SCCOLROW* pPrev = NULL ); SCCOLROW* pBreak = NULL, SCCOLROW* pPrev = NULL );
/** The cell may be covered by text that overflows from a previous cell.
@return if true, the given cell is covered by (overflowing) text and
rTextStartPosX returns the column where the text that overflows
starts.
*/
bool IsCellCoveredByText(SCsCOL nPosX, SCsROW nPosY, SCTAB nTab, SCsCOL &rTextStartPosX);
void PasteSelection( const Point& rPosPixel ); void PasteSelection( const Point& rPosPixel );
void SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ); void SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY );
......
...@@ -1657,6 +1657,72 @@ void ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt ) ...@@ -1657,6 +1657,72 @@ void ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
nNestedButtonState = SC_NESTEDBUTTON_NONE; nNestedButtonState = SC_NESTEDBUTTON_NONE;
} }
bool ScGridWindow::IsCellCoveredByText(SCsCOL nPosX, SCsROW nPosY, SCTAB nTab, SCsCOL &rTextStartPosX)
{
ScDocument* pDoc = pViewData->GetDocument();
// find the first non-empty cell (this, or to the left)
ScRefCellValue aCell;
SCsCOL nNonEmptyX = nPosX;
for (; nNonEmptyX >= 0; --nNonEmptyX)
{
aCell.assign(*pDoc, ScAddress(nNonEmptyX, nPosY, nTab));
if (!aCell.isEmpty())
break;
}
// the inital cell already contains text
if (nNonEmptyX == nPosX)
{
rTextStartPosX = nNonEmptyX;
return true;
}
// to the left, there is no cell that would contain (potentially
// overrunning) text
if (nNonEmptyX < 0 || pDoc->HasAttrib(nNonEmptyX, nPosY, nTab, nPosX, nPosY, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED))
return false;
double nPPTX = pViewData->GetPPTX();
double nPPTY = pViewData->GetPPTY();
ScTableInfo aTabInfo;
pDoc->FillInfo(aTabInfo, 0, nPosY, nPosX, nPosY, nTab, nPPTX, nPPTY, false, false);
Fraction aZoomX = pViewData->GetZoomX();
Fraction aZoomY = pViewData->GetZoomY();
ScOutputData aOutputData(this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab,
0, 0, 0, nPosY, nPosX, nPosY, nPPTX, nPPTY,
&aZoomX, &aZoomY);
MapMode aCurrentMapMode(GetMapMode());
SetMapMode(MAP_PIXEL);
// obtain the bounding box of the text in first non-empty cell
// to the left
Rectangle aRect(aOutputData.LayoutStrings(false, false, ScAddress(nNonEmptyX, nPosY, nTab)));
SetMapMode(aCurrentMapMode);
// the text does not overrun from the cell
if (aRect.IsEmpty())
return false;
SCsCOL nTextEndX;
SCsROW nTextEndY;
// test the rightmost position of the text bounding box
long nMiddle = (aRect.Top() + aRect.Bottom()) / 2;
pViewData->GetPosFromPixel(aRect.Right(), nMiddle, eWhich, nTextEndX, nTextEndY);
if (nTextEndX >= nPosX)
{
rTextStartPosX = nNonEmptyX;
return true;
}
return false;
}
void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventState& rState ) void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventState& rState )
{ {
// We have to check if a context menu is shown and we have an UI // We have to check if a context menu is shown and we have an UI
...@@ -1694,7 +1760,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta ...@@ -1694,7 +1760,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE
bool bDouble = (rMEvt.GetClicks() == 2); bool bDouble = (rMEvt.GetClicks() == 2);
bool bIsTiledRendering = pViewData->GetDocument()->GetDrawLayer()->isTiledRendering(); ScDocument* pDoc = pViewData->GetDocument();
bool bIsTiledRendering = pDoc->GetDrawLayer()->isTiledRendering();
// DeactivateIP passiert nur noch bei MarkListHasChanged // DeactivateIP passiert nur noch bei MarkListHasChanged
...@@ -1704,20 +1771,44 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta ...@@ -1704,20 +1771,44 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
if ( !nButtonDown || !bDouble ) // single (first) click is always valid if ( !nButtonDown || !bDouble ) // single (first) click is always valid
nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works
// special handling of empty cells with tiled rendering - with double // special handling of empty cells with tiled rendering
// click, the entire cell is selected if (bIsTiledRendering)
if (bIsTiledRendering && bEditMode && bDouble)
{ {
Point aPos = rMEvt.GetPosPixel(); Point aPos(rMEvt.GetPosPixel());
SCsCOL nPosX; SCsCOL nPosX, nNonEmptyX;
SCsROW nPosY; SCsROW nPosY;
SCTAB nTab = pViewData->GetTabNo(); SCTAB nTab = pViewData->GetTabNo();
pViewData->GetPosFromPixel(aPos.X(), aPos.Y(), eWhich, nPosX, nPosY); pViewData->GetPosFromPixel(aPos.X(), aPos.Y(), eWhich, nPosX, nPosY);
ScRefCellValue aCell; ScRefCellValue aCell;
aCell.assign(*pViewData->GetDocument(), ScAddress(nPosX, nPosY, nTab)); aCell.assign(*pDoc, ScAddress(nPosX, nPosY, nTab));
if (aCell.isEmpty()) bool bIsEmpty = aCell.isEmpty();
bool bIsCoveredByText = bIsEmpty && IsCellCoveredByText(nPosX, nPosY, nTab, nNonEmptyX);
if (bIsCoveredByText)
{
// if there's any text flowing to this cell, activate the
// editengine, so that the text actually gets the events
if (bDouble)
{
ScViewFunc* pView = pViewData->GetView();
pView->SetCursor(nNonEmptyX, nPosY);
SC_MOD()->SetInputMode(SC_INPUT_TABLE);
bEditMode = pViewData->HasEditView(eWhich);
assert(bEditMode);
// synthesize the 1st click
EditView* pEditView = pViewData->GetEditView(eWhich);
MouseEvent aEditEvt(rMEvt.GetPosPixel(), 1, MouseEventModifiers::SYNTHETIC, MOUSE_LEFT, 0);
pEditView->MouseButtonDown(aEditEvt);
pEditView->MouseButtonUp(aEditEvt);
}
}
else if (bIsEmpty && bEditMode && bDouble)
{ {
// double-click in an empty cell: the entire cell is selected
SetCellSelectionPixel(LOK_SETTEXTSELECTION_START, aPos.X(), aPos.Y()); SetCellSelectionPixel(LOK_SETTEXTSELECTION_START, aPos.X(), aPos.Y());
SetCellSelectionPixel(LOK_SETTEXTSELECTION_END, aPos.X(), aPos.Y()); SetCellSelectionPixel(LOK_SETTEXTSELECTION_END, aPos.X(), aPos.Y());
return; return;
...@@ -1865,7 +1956,6 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta ...@@ -1865,7 +1956,6 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
SCsROW nPosY; SCsROW nPosY;
pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
SCTAB nTab = pViewData->GetTabNo(); SCTAB nTab = pViewData->GetTabNo();
ScDocument* pDoc = pViewData->GetDocument();
// Auto filter / pivot table / data select popup. This shouldn't activate the part. // Auto filter / pivot table / data select popup. This shouldn't activate the part.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment