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 <ke...@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 <ke...@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 <ke...@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() _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits