[Libreoffice-commits] core.git: 3 commits - editeng/source sc/source
Jan Holesovsky
kendy at collabora.com
Tue Apr 14 03:18:15 PDT 2015
editeng/source/editeng/impedit2.cxx | 10 +++
sc/source/ui/inc/gridwin.hxx | 8 ++
sc/source/ui/inc/output.hxx | 4 +
sc/source/ui/view/gridwin.cxx | 108 +++++++++++++++++++++++++++++++++---
sc/source/ui/view/output2.cxx | 33 +++++++++--
5 files changed, 147 insertions(+), 16 deletions(-)
New commits:
commit 771bb58c1c547a874c80d05be59f73cbf68343df
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Apr 14 12:08:39 2015 +0200
editeng tiled editing: Don't overwrite bInSelection.
Setting bInSelection in MouseButtonUp() feels wrong, and against of its other
handling elsewhere. Also it breaks the selection handling in the tiled
rendering case - on further redraw, selections may disappear.
But it has been so since the initial check-in of the OOo code, so I have no
idea what corner case I might break by deleting this, so let's guard the
behavior by isTiledReneding() for now.
Change-Id: I7f7b237f9f0f427e317266e05481bac439c3c8ad
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 7fc5c43..7d4f1c8 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -567,7 +567,15 @@ bool ImpEditEngine::MouseButtonUp( const MouseEvent& rMEvt, EditView* pView )
{
GetSelEngine().SetCurView( pView );
GetSelEngine().SelMouseButtonUp( rMEvt );
- bInSelection = false;
+
+ // in the tiled rendering case, setting bInSelection here has unexpected
+ // consequences - further tiles painting removes the selection
+ // FIXME I believe resetting bInSelection should not be here even in the
+ // non-tiled-rendering case, but it has been here since 2000 (and before)
+ // so who knows what corner case it was supposed to solve back then
+ if (!pView->pImpEditView->isTiledRendering())
+ bInSelection = false;
+
// Special treatments
EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
if ( !aCurSel.HasRange() )
commit 3f04bfef9e12e947f336aaa441d784f6c77f8e6a
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Apr 14 12:05:00 2015 +0200
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
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 259844e..0221e60 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -278,6 +278,14 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou
sal_uInt16 HitPageBreak( const Point& rMouse, ScRange* pSource = 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 SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY );
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 2b0ca4c..838318e 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -1657,6 +1657,72 @@ void ScGridWindow::MouseButtonDown( const MouseEvent& rMEvt )
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 )
{
// 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
bool bFormulaMode = pScMod->IsFormulaMode(); // naechster Klick -> Referenz
bool bEditMode = pViewData->HasEditView(eWhich); // auch bei Mode==SC_INPUT_TYPE
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
@@ -1704,20 +1771,44 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
if ( !nButtonDown || !bDouble ) // single (first) click is always valid
nButtonDown = rMEvt.GetButtons(); // set nButtonDown first, so StopMarking works
- // special handling of empty cells with tiled rendering - with double
- // click, the entire cell is selected
- if (bIsTiledRendering && bEditMode && bDouble)
+ // special handling of empty cells with tiled rendering
+ if (bIsTiledRendering)
{
- Point aPos = rMEvt.GetPosPixel();
- SCsCOL nPosX;
+ Point aPos(rMEvt.GetPosPixel());
+ SCsCOL nPosX, nNonEmptyX;
SCsROW nPosY;
SCTAB nTab = pViewData->GetTabNo();
pViewData->GetPosFromPixel(aPos.X(), aPos.Y(), eWhich, nPosX, nPosY);
ScRefCellValue aCell;
- aCell.assign(*pViewData->GetDocument(), ScAddress(nPosX, nPosY, nTab));
- if (aCell.isEmpty())
+ aCell.assign(*pDoc, ScAddress(nPosX, nPosY, nTab));
+ 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_END, aPos.X(), aPos.Y());
return;
@@ -1865,7 +1956,6 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt, MouseEventSta
SCsROW nPosY;
pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY );
SCTAB nTab = pViewData->GetTabNo();
- ScDocument* pDoc = pViewData->GetDocument();
// Auto filter / pivot table / data select popup. This shouldn't activate the part.
commit 41c8aeabd2537df879e6f1b5c0b57255fd07e2fa
Author: Jan Holesovsky <kendy at collabora.com>
Date: Tue Apr 14 11:59:56 2015 +0200
sc tiled editing: Re-purposed DrawStrings().
Calc has no real understanding whether there is a text overflowing to the
other cells or not, it is sorted out when drawing in DrawStrings().
Re-purpose it so that it has a mode where the caller can ask for actual region
of text that covers the given cell.
Change-Id: Id0caa3972727bafdaeb148f8bbabb412f771a67d
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index d9e1a46..7d8ef81 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -299,6 +299,10 @@ public:
void DrawGrid( bool bGrid, bool bPage );
void DrawStrings( bool bPixelToLogic = false );
+
+ /// Draw all strings, or provide Rectangle where the text (defined by rAddress) would be drawn.
+ Rectangle LayoutStrings(bool bPixelToLogic = false, bool bPaint = true, const ScAddress &rAddress = ScAddress());
+
void DrawDocumentBackground();
void DrawBackground();
void DrawShadow();
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index e33a747..6ffe033 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1426,9 +1426,14 @@ static SvxCellHorJustify getAlignmentFromContext( SvxCellHorJustify eInHorJust,
void ScOutputData::DrawStrings( bool bPixelToLogic )
{
+ LayoutStrings(bPixelToLogic, true);
+}
+
+Rectangle ScOutputData::LayoutStrings(bool bPixelToLogic, bool bPaint, const ScAddress &rAddress)
+{
OSL_ENSURE( mpDev == mpRefDevice ||
mpDev->GetMapMode().GetMapUnit() == mpRefDevice->GetMapMode().GetMapUnit(),
- "DrawStrings: unterschiedliche MapUnits ?!?!" );
+ "LayoutStrings: unterschiedliche MapUnits ?!?!" );
vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, mpDev->GetExtOutDevData() );
@@ -1469,9 +1474,9 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++)
{
RowInfo* pThisRowInfo = &pRowInfo[nArrY];
- if ( pThisRowInfo->bChanged )
+ SCROW nY = pThisRowInfo->nRowNo;
+ if ((bPaint && pThisRowInfo->bChanged) || (!bPaint && rAddress.Row() == nY))
{
- SCROW nY = pThisRowInfo->nRowNo;
long nPosX = nInitPosX;
if ( nLoopStartX < nX1 )
nPosX -= pRowInfo[0].pCellInfo[nLoopStartX+1].nWidth * nLayoutSign;
@@ -2041,6 +2046,16 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
}
}
+ // if we are not painting, it means we are interested in
+ // the area of the text that covers the specified cell
+ if (!bPaint && rAddress.Col() == nX)
+ {
+ Rectangle aRect;
+ mpDev->GetTextBoundRect(aRect, aShort);
+ aRect += aDrawTextPos;
+ return aRect;
+ }
+
if (bMetaFile || pFmtDevice != mpDev || aZoomX != aZoomY)
{
size_t nLen = aShort.getLength();
@@ -2057,10 +2072,14 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
aDX[i] = static_cast<sal_Int32>(aDX[i] / fMul + 0.5);
}
- mpDev->DrawTextArray(aDrawTextPos, aShort, &aDX[0]);
+ if (bPaint)
+ mpDev->DrawTextArray(aDrawTextPos, aShort, &aDX[0]);
}
else
- mpDev->DrawText(aDrawTextPos, aShort);
+ {
+ if (bPaint)
+ mpDev->DrawText(aDrawTextPos, aShort);
+ }
}
if ( bHClip || bVClip )
@@ -2073,7 +2092,7 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
// PDF: whole-cell hyperlink from formula?
bool bHasURL = pPDFData && aCell.meType == CELLTYPE_FORMULA && aCell.mpFormula->IsHyperLinkCell();
- if ( bHasURL )
+ if (bPaint && bHasURL)
{
Rectangle aURLRect( aURLStart, aVars.GetTextSize() );
lcl_DoHyperlinkResult(mpDev, aURLRect, aCell);
@@ -2087,6 +2106,8 @@ void ScOutputData::DrawStrings( bool bPixelToLogic )
}
if ( bProgress )
ScProgress::DeleteInterpretProgress();
+
+ return Rectangle();
}
ScFieldEditEngine* ScOutputData::CreateOutputEditEngine()
More information about the Libreoffice-commits
mailing list