[Libreoffice-commits] core.git: Branch 'feature/editviewoverlay' - 82 commits - accessibility/inc accessibility/source basic/qa basic/source bin/update chart2/inc chart2/source compilerplugins/clang connectivity/source cui/source dbaccess/qa download.lst drawinglayer/source editeng/source external/expat extras/Package_tplofficorr.mk extras/source filter/source forms/source hwpfilter/source include/editeng include/filter include/oox include/rtl include/sfx2 include/svl include/svx include/unotools include/vbahelper include/vcl Makefile.gbuild officecfg/registry oox/source reportdesign/inc reportdesign/source sc/inc sc/qa sc/source sdext/source sd/inc sd/qa sd/source sd/uiconfig sd/UIConfig_sdraw.mk sd/UIConfig_simpress.mk sfx2/Library_sfx.mk sfx2/source starmath/inc starmath/source svl/source svtools/source svx/inc svx/source sw/inc sw/source sw/uiconfig uitest/uitest vcl/inc vcl/README.scheduler vcl/source vcl/unx wizards/source writerperfect/inc writerperfect/Library_wpftwriter.mk writerperfect/ source xmloff/source xmlsecurity/Library_xsec_xmlsec.mk xmlsecurity/source

Armin Le Grand Armin.Le.Grand at cib.de
Sun Aug 6 10:51:02 UTC 2017


Rebased ref, commits from common ancestor:
commit c91787f8f5db6848e9ea3f8ac0367c5adb83b21a
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Sun Aug 6 00:26:35 2017 +0200

    editviewoverlay: EditViewSelection reorganized
    
    The Selection visualization in EditVierw is organized
    to use XOR for visualization, thus DrawSelection is
    used e.g. before and after changes to the Selection.
    Ensured athat all changers of selection have to use
    SetEditSelection by making return of GetEditSelection
    const. This allows to use a central and safe
    SelectionChanged which is needed for alternatives of
    Selection visualization.
    
    Change-Id: I994553f3be6b58fd595aa500922d8d1d8ddd36d4

diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index 63fce03390de..024b66a91fda 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -637,7 +637,7 @@ ESelection EditEngine::GetWord( const ESelection& rSelection, sal_uInt16 nWordTy
     return pE->pImpEditEngine->CreateESel( aSel );
 }
 
-void EditEngine::CursorMoved(ContentNode* pPrevNode)
+void EditEngine::CursorMoved(const ContentNode* pPrevNode)
 {
     pImpEditEngine->CursorMoved(pPrevNode);
 }
@@ -1173,7 +1173,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
                         break;
                     }
 
-                    pEditView->pImpEditView->DrawSelection();
+                    pEditView->pImpEditView->DrawSelectionXOR();
                     pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
                     aCurSel = pImpEditEngine->DeleteLeftOrRight( aCurSel, nDel, nMode );
                     pImpEditEngine->UndoActionEnd();
@@ -1213,7 +1213,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
             {
                 if ( !bReadOnly )
                 {
-                    pEditView->pImpEditView->DrawSelection();
+                    pEditView->pImpEditView->DrawSelectionXOR();
                     if ( !rKeyEvent.GetKeyCode().IsMod1() && !rKeyEvent.GetKeyCode().IsMod2() )
                     {
                         pImpEditEngine->UndoActionStart( EDITUNDO_INSERT );
@@ -1268,7 +1268,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
                 if ( !bReadOnly && IsSimpleCharInput( rKeyEvent ) )
                 {
                     sal_Unicode nCharCode = rKeyEvent.GetCharCode();
-                    pEditView->pImpEditView->DrawSelection();
+                    pEditView->pImpEditView->DrawSelectionXOR();
                     // Autocorrection?
                     SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
                     if ( ( pImpEditEngine->GetStatus().DoAutoCorrect() ) &&
@@ -1363,7 +1363,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
     pEditView->pImpEditView->SetEditSelection( aCurSel );
     if (comphelper::LibreOfficeKit::isActive())
     {
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
     }
     pImpEditEngine->UpdateSelections();
 
diff --git a/editeng/source/editeng/editundo.cxx b/editeng/source/editeng/editundo.cxx
index ca074815d6d4..40ba68926516 100644
--- a/editeng/source/editeng/editundo.cxx
+++ b/editeng/source/editeng/editundo.cxx
@@ -66,7 +66,7 @@ bool EditUndoManager::Undo()
         }
     }
 
-    mpEditEngine->GetActiveView()->GetImpEditView()->DrawSelection(); // Remove the old selection
+    mpEditEngine->GetActiveView()->GetImpEditView()->DrawSelectionXOR(); // Remove the old selection
 
     mpEditEngine->SetUndoMode( true );
     bool bDone = SfxUndoManager::Undo();
@@ -101,7 +101,7 @@ bool EditUndoManager::Redo()
         }
     }
 
-    mpEditEngine->GetActiveView()->GetImpEditView()->DrawSelection(); // Remove the old selection
+    mpEditEngine->GetActiveView()->GetImpEditView()->DrawSelectionXOR(); // Remove the old selection
 
     mpEditEngine->SetUndoMode( true );
     bool bDone = SfxUndoManager::Redo();
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index db7ff1951767..b74f76e35001 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -256,7 +256,7 @@ void EditView::SetSelection( const ESelection& rESel )
     // manipulates the selection:
     if ( !pImpEditView->GetEditSelection().HasRange() )
     {
-        ContentNode* pNode = pImpEditView->GetEditSelection().Max().GetNode();
+        const ContentNode* pNode = pImpEditView->GetEditSelection().Max().GetNode();
         pImpEditView->pEditEngine->CursorMoved( pNode );
     }
     EditSelection aNewSelection( pImpEditView->pEditEngine->pImpEditEngine->ConvertSelection(
@@ -281,9 +281,9 @@ void EditView::SetSelection( const ESelection& rESel )
         aNewSelection.Max() = EditPaM( pNode, pNode->Len() );
     }
 
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->SetEditSelection( aNewSelection );
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     bool bGotoCursor = pImpEditView->DoAutoScroll();
     ShowCursor( bGotoCursor );
 }
@@ -318,7 +318,7 @@ SvtScriptType EditView::GetSelectedScriptType() const
 
 void EditView::GetSelectionRectangles(std::vector<tools::Rectangle>& rLogicRects) const
 {
-    return pImpEditView->GetSelectionRectangles(rLogicRects);
+    return pImpEditView->GetSelectionRectangles(pImpEditView->GetEditSelection(), rLogicRects);
 }
 
 void EditView::Paint( const tools::Rectangle& rRect, OutputDevice* pTargetDevice )
@@ -413,7 +413,7 @@ void EditView::InsertText( const OUString& rStr, bool bSelect )
 {
 
     EditEngine* pEE = pImpEditView->pEditEngine;
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
 
     EditPaM aPaM1;
     if ( bSelect )
@@ -512,7 +512,7 @@ void EditView::SetAttribs( const SfxItemSet& rSet )
 {
     DBG_ASSERT( !pImpEditView->aEditSelection.IsInvalid(), "Blind Selection in ...." );
 
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->pEditEngine->SetAttribs( pImpEditView->GetEditSelection(), rSet, SetAttribsMode::WholeWord );
     pImpEditView->pEditEngine->FormatAndUpdate( this );
 }
@@ -520,7 +520,7 @@ void EditView::SetAttribs( const SfxItemSet& rSet )
 void EditView::RemoveAttribsKeepLanguages( bool bRemoveParaAttribs )
 {
 
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS );
     EditSelection aSelection( pImpEditView->GetEditSelection() );
 
@@ -540,7 +540,7 @@ void EditView::RemoveAttribsKeepLanguages( bool bRemoveParaAttribs )
 void EditView::RemoveAttribs( bool bRemoveParaAttribs, sal_uInt16 nWhich )
 {
 
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_RESETATTRIBS );
     pImpEditView->pEditEngine->RemoveCharAttribs( pImpEditView->GetEditSelection(), bRemoveParaAttribs, nWhich  );
     pImpEditView->pEditEngine->UndoActionEnd();
@@ -574,7 +574,7 @@ void EditView::Redo()
 ErrCode EditView::Read( SvStream& rInput, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs )
 {
     EditSelection aOldSel( pImpEditView->GetEditSelection() );
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_READ );
     EditPaM aEndPaM = pImpEditView->pEditEngine->pImpEditEngine->Read( rInput, "", eFormat, aOldSel, pHTTPHeaderAttrs );
     pImpEditView->pEditEngine->pImpEditEngine->UndoActionEnd();
@@ -690,7 +690,7 @@ EditTextObject* EditView::CreateTextObject()
 
 void EditView::InsertText( const EditTextObject& rTextObject )
 {
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
 
     pImpEditView->pEditEngine->UndoActionStart( EDITUNDO_INSERT );
     EditSelection aTextSel( pImpEditView->pEditEngine->InsertText( rTextObject, pImpEditView->GetEditSelection() ) );
@@ -773,9 +773,9 @@ void EditView::TransliterateText( TransliterationFlags nTransliterationMode )
     EditSelection aNewSel = pImpEditView->pEditEngine->TransliterateText( pImpEditView->GetEditSelection(), nTransliterationMode );
     if ( aNewSel != aOldSel )
     {
-        pImpEditView->DrawSelection();
+        pImpEditView->DrawSelectionXOR();
         pImpEditView->SetEditSelection( aNewSel );
-        pImpEditView->DrawSelection();
+        pImpEditView->DrawSelectionXOR();
     }
 }
 
@@ -783,7 +783,7 @@ void EditView::CompleteAutoCorrect( vcl::Window const * pFrameWin )
 {
     if ( !pImpEditView->HasSelection() && pImpEditView->pEditEngine->pImpEditEngine->GetStatus().DoAutoCorrect() )
     {
-        pImpEditView->DrawSelection();
+        pImpEditView->DrawSelectionXOR();
         EditSelection aSel = pImpEditView->GetEditSelection();
         aSel = pImpEditView->pEditEngine->EndOfWord( aSel.Max() );
         aSel = pImpEditView->pEditEngine->pImpEditEngine->AutoCorrect( aSel, 0, !IsInsertMode(), pFrameWin );
@@ -1073,9 +1073,9 @@ void EditView::ExecuteSpellPopup( const Point& rPosPixel, Link<SpellCallbackInfo
             {
                 // Set Cursor before word...
                 EditPaM aCursor = pImpEditView->GetEditSelection().Min();
-                pImpEditView->DrawSelection();
+                pImpEditView->DrawSelectionXOR();
                 pImpEditView->SetEditSelection( EditSelection( aCursor, aCursor ) );
-                pImpEditView->DrawSelection();
+                pImpEditView->DrawSelectionXOR();
                 // Crashes when no SfxApp
                 pImpEditView->pEditEngine->pImpEditEngine->Spell( this, false );
             }
@@ -1144,17 +1144,17 @@ void EditView::ExecuteSpellPopup( const Point& rPosPixel, Link<SpellCallbackInfo
 void EditView::SelectCurrentWord( sal_Int16 nWordType )
 {
     EditSelection aCurSel( pImpEditView->GetEditSelection() );
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     aCurSel = pImpEditView->pEditEngine->SelectWord(aCurSel.Max(), nWordType);
     pImpEditView->SetEditSelection( aCurSel );
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     ShowCursor( true, false );
 }
 
 void EditView::InsertField( const SvxFieldItem& rFld )
 {
     EditEngine* pEE = pImpEditView->pEditEngine;
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pEE->UndoActionStart( EDITUNDO_INSERT );
     EditPaM aPaM( pEE->InsertField( pImpEditView->GetEditSelection(), rFld ) );
     pEE->UndoActionEnd();
@@ -1442,16 +1442,16 @@ void EditView::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool
 
     if (pImpEditView->GetEditSelection().Min() != aSelection.Min())
         pImpEditView->pEditEngine->CursorMoved(pImpEditView->GetEditSelection().Min().GetNode());
-    pImpEditView->DrawSelection(aSelection);
+    pImpEditView->DrawSelectionXOR(aSelection);
     if (pImpEditView->GetEditSelection() != aSelection)
         pImpEditView->SetEditSelection(aSelection);
     ShowCursor(/*bGotoCursor=*/false);
 }
 
-void EditView::DrawSelection(OutlinerViewShell* pOtherShell)
+void EditView::DrawSelectionXOR(OutlinerViewShell* pOtherShell)
 {
     pImpEditView->RegisterOtherShell(pOtherShell);
-    pImpEditView->DrawSelection();
+    pImpEditView->DrawSelectionXOR();
     pImpEditView->RegisterOtherShell(nullptr);
 }
 
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index fc8ee6745a3a..48a6f1397af3 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -91,6 +91,8 @@ ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, vcl::Window* pWindo
 
     aEditSelection.Min() = pEng->GetEditDoc().GetStartPaM();
     aEditSelection.Max() = pEng->GetEditDoc().GetEndPaM();
+
+    SelectionChanged();
 }
 
 ImpEditView::~ImpEditView()
@@ -131,6 +133,8 @@ void ImpEditView::SetEditSelection( const EditSelection& rEditSelection )
     // set state before notification
     aEditSelection = rEditSelection;
 
+    SelectionChanged();
+
     if (comphelper::LibreOfficeKit::isActive())
         // Tiled rendering: selections are only painted when we are in selection mode.
         pEditEngine->SetInSelectionMode(aEditSelection.HasRange());
@@ -184,19 +188,20 @@ void lcl_translateTwips(vcl::Window const & rParent, vcl::Window& rChild)
     }
 }
 
-void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, OutputDevice* pTargetDevice )
+// EditView never had a central/secure place to react on SelectionChange since
+// Selection was changed in many places, often by not using SetEditSelection()
+// but (mis)using GetEditSelection() and manipulating this non-const return
+// value. Sorted this out now to have such a place, this is needed for safely
+// change/update the Selection visualization for enhanced mechanisms
+void ImpEditView::SelectionChanged()
 {
-    if (hasEditViewCallbacks() && !pRegion)
+    if (hasEditViewCallbacks())
     {
-        // when we have an own mechanism for painting EditViews, collect the Selection
-        // in a basegfx::B2DRange vector and hand over. To do so, call GetSelectionRectangles
-        // which recursively calls ImpEditView::DrawSelection, but with nullptr != pRegion
         std::vector<tools::Rectangle> aLogicRects;
         std::vector<basegfx::B2DRange> aLogicRanges;
-        OutputDevice* pTarget = pTargetDevice ? pTargetDevice : pOutWin;
-        const Point aPixel(pTarget ? pTarget->LogicToPixel(Point(1, 1)) : Point(1, 1));
+        const Size aLogicPixel(pOutWin ? pOutWin->PixelToLogic(Size(1, 1)) : Size(1, 1));
 
-        GetSelectionRectangles(aLogicRects);
+        GetSelectionRectangles(GetEditSelection(), aLogicRects);
 
         for (const auto& aRect : aLogicRects)
         {
@@ -205,12 +210,27 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
             aLogicRanges.push_back(
                 basegfx::B2DRange(
                     aRect.Left(), aRect.Top(),
-                    aRect.Right() + aPixel.X(), aRect.Bottom() + aPixel.Y()));
+                    aRect.Right() + aLogicPixel.Width(), aRect.Bottom() + aLogicPixel.Height()));
         }
 
         // use callback to tell about change in selection visualisation
         mpEditViewCallbacks->EditViewSelectionChange(aLogicRanges);
+    }
+}
 
+// renamed from DrawSelection to DrawSelectionXOR to better reflect what this
+// method was used for: Paint Selection in XOR, change it and again paint it in XOR.
+// This can be safely assumed due to the EditView only being capable of painting the
+// selection in XOR until today.
+// This also means that all places calling DrawSelectionXOR are thoroughly weighted
+// and choosen to make this fragile XOR-paint water-proof and thus contain some
+// information in this sense.
+// Someone thankfully expanded it to collect the SelectionRectangles when called with
+// the Region*, see GetSelectionRectangles below.
+void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion, OutputDevice* pTargetDevice )
+{
+    if (hasEditViewCallbacks() && !pRegion)
+    {
         // we are done, do *not* visualize self
         return;
     }
@@ -262,7 +282,7 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
         pPolyPoly = new tools::PolyPolygon;
     }
 
-    DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelection: Not formatted!" );
+    DBG_ASSERT( !pEditEngine->IsIdleFormatterActive(), "DrawSelectionXOR: Not formatted!" );
     aTmpSel.Adjust( pEditEngine->GetEditDoc() );
 
     ContentNode* pStartNode = aTmpSel.Min().GetNode();
@@ -351,7 +371,7 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
                     if ( nTmpEndIndex > nEndIndex )
                         nTmpEndIndex = nEndIndex;
 
-                    DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelection, Start >= End?" );
+                    DBG_ASSERT( nTmpEndIndex > nTmpStartIndex, "DrawSelectionXOR, Start >= End?" );
 
                     long nX1 = pEditEngine->GetXPos(pTmpPortion, &rLine, nTmpStartIndex, true);
                     long nX2 = pEditEngine->GetXPos(pTmpPortion, &rLine, nTmpEndIndex);
@@ -477,10 +497,10 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
     }
 }
 
-void ImpEditView::GetSelectionRectangles(std::vector<tools::Rectangle>& rLogicRects)
+void ImpEditView::GetSelectionRectangles(EditSelection aTmpSel, std::vector<tools::Rectangle>& rLogicRects)
 {
     vcl::Region aRegion;
-    DrawSelection(aEditSelection, &aRegion);
+    DrawSelectionXOR(aTmpSel, &aRegion);
     aRegion.GetRegionRectangles(rLogicRects);
 }
 
@@ -627,9 +647,9 @@ void ImpEditView::SetSelectionMode( EESelectionMode eNewMode )
 {
     if ( eSelectionMode != eNewMode )
     {
-        DrawSelection();
+        DrawSelectionXOR();
         eSelectionMode = eNewMode;
-        DrawSelection();    // redraw
+        DrawSelectionXOR();    // redraw
     }
 }
 
@@ -1397,9 +1417,9 @@ bool ImpEditView::IsWrongSpelledWord( const EditPaM& rPaM, bool bMarkIfWrong )
         bIsWrong = rPaM.GetNode()->GetWrongList()->HasWrong( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
         if ( bIsWrong && bMarkIfWrong )
         {
-            DrawSelection();
+            DrawSelectionXOR();
             SetEditSelection( aSel );
-            DrawSelection();
+            DrawSelectionXOR();
         }
     }
     return bIsWrong;
@@ -1420,9 +1440,9 @@ OUString ImpEditView::SpellIgnoreWord()
         {
             aWord = pEditEngine->pImpEditEngine->GetSelected( GetEditSelection() );
             // And deselect
-            DrawSelection();
+            DrawSelectionXOR();
             SetEditSelection( EditSelection( aPaM, aPaM ) );
-            DrawSelection();
+            DrawSelectionXOR();
         }
 
         if ( !aWord.isEmpty() )
@@ -1446,7 +1466,7 @@ OUString ImpEditView::SpellIgnoreWord()
 
 void ImpEditView::DeleteSelected()
 {
-    DrawSelection();
+    DrawSelectionXOR();
 
     pEditEngine->pImpEditEngine->UndoActionStart( EDITUNDO_DELETE );
 
@@ -1585,7 +1605,7 @@ void ImpEditView::Paste( css::uno::Reference< css::datatransfer::clipboard::XCli
     EditSelection aSel( GetEditSelection() );
     if ( aSel.HasRange() )
     {
-        DrawSelection();
+        DrawSelectionXOR();
         aSel = pEditEngine->DeleteSelection(aSel);
     }
 
@@ -1669,18 +1689,20 @@ bool ImpEditView::IsInSelection( const EditPaM& rPaM )
 void ImpEditView::CreateAnchor()
 {
     pEditEngine->SetInSelectionMode(true);
-    GetEditSelection().Min() = GetEditSelection().Max();
+    EditSelection aNewSelection(GetEditSelection());
+    aNewSelection.Min() = aNewSelection.Max();
+    SetEditSelection(aNewSelection);
+    // const_cast<EditPaM&>(GetEditSelection().Min()) = GetEditSelection().Max();
 }
 
 void ImpEditView::DeselectAll()
 {
     pEditEngine->SetInSelectionMode(false);
-    DrawSelection();
-    GetEditSelection().Min() = GetEditSelection().Max();
-
-    // Selection is empty, still need to draw it due to new forward selection
-    // functionality. When without that, nothing will be drawn (since it's empty)
-    DrawSelection();
+    DrawSelectionXOR();
+    EditSelection aNewSelection(GetEditSelection());
+    aNewSelection.Min() = aNewSelection.Max();
+    SetEditSelection(aNewSelection);
+    // const_cast<EditPaM&>(GetEditSelection().Min()) = GetEditSelection().Max();
 }
 
 bool ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
@@ -1741,7 +1763,7 @@ bool ImpEditView::SetCursorAtPoint( const Point& rPointPixel )
     }
     else
     {
-        DrawSelection( aTmpNewSel );
+        DrawSelectionXOR( aTmpNewSel );
     }
 
     // set changed text selection
@@ -1849,8 +1871,8 @@ void ImpEditView::dragGestureRecognized(const css::datatransfer::dnd::DragGestur
             pDragAndDropInfo->pField = pField;
             ContentNode* pNode = pEditEngine->GetEditDoc().GetObject( nPara );
             aCopySel = EditSelection( EditPaM( pNode, nPos ), EditPaM( pNode, nPos+1 ) );
-            GetEditSelection() = aCopySel;
-            DrawSelection();
+            SetEditSelection(aCopySel);
+            DrawSelectionXOR();
             bool bGotoCursor = DoAutoScroll();
             ShowCursor( bGotoCursor, /*bForceCursor=*/false );
         }
@@ -1963,7 +1985,7 @@ void ImpEditView::dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent
                     }
                 }
 
-                DrawSelection();
+                DrawSelectionXOR();
                 EditSelection aDelSel( pEditEngine->pImpEditEngine->CreateSel( aToBeDelSel ) );
                 DBG_ASSERT( !aDelSel.DbgIsBuggy( pEditEngine->GetEditDoc() ), "ToBeDel is buggy!" );
                 pEditEngine->DeleteSelection(aDelSel);
@@ -1973,7 +1995,7 @@ void ImpEditView::dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent
                     SetEditSelection( pEditEngine->pImpEditEngine->CreateSel( aNewSel ) );
                 }
                 pEditEngine->pImpEditEngine->FormatAndUpdate( pEditEngine->pImpEditEngine->GetActiveView() );
-                DrawSelection();
+                DrawSelectionXOR();
             }
             else
             {
@@ -2024,7 +2046,7 @@ void ImpEditView::drop( const css::datatransfer::dnd::DropTargetDropEvent& rDTDE
             {
                 bChanges = true;
                 // remove Selection ...
-                DrawSelection();
+                DrawSelectionXOR();
                 EditPaM aPaM( pDragAndDropInfo->aDropDest );
 
                 PasteOrDropInfos aPasteOrDropInfos;
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index a41dc0a21032..502c4c791e8b 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -335,13 +335,14 @@ public:
     long            GetVisDocBottom() const { return aVisDocStartPos.Y() + ( !IsVertical() ? aOutArea.GetHeight() : aOutArea.GetWidth() ); }
     tools::Rectangle       GetVisDocArea() const;
 
-    EditSelection&  GetEditSelection()          { return aEditSelection; }
+    const EditSelection&  GetEditSelection()          { return aEditSelection; }
     void            SetEditSelection( const EditSelection& rEditSelection );
     bool            HasSelection() const { return aEditSelection.HasRange(); }
 
-    void            DrawSelection() { DrawSelection( aEditSelection ); }
-    void            DrawSelection( EditSelection, vcl::Region* pRegion = nullptr, OutputDevice* pTargetDevice = nullptr );
-    void GetSelectionRectangles(std::vector<tools::Rectangle>& rLogicRects);
+    void SelectionChanged();
+    void            DrawSelectionXOR() { DrawSelectionXOR( aEditSelection ); }
+    void            DrawSelectionXOR( EditSelection, vcl::Region* pRegion = nullptr, OutputDevice* pTargetDevice = nullptr );
+    void GetSelectionRectangles(EditSelection aTmpSel, std::vector<tools::Rectangle>& rLogicRects);
 
     vcl::Window*    GetWindow() const           { return pOutWin; }
 
@@ -541,7 +542,7 @@ private:
     // Methods...
 
 
-    void                CursorMoved( ContentNode* pPrevNode );
+    void                CursorMoved( const ContentNode* pPrevNode );
     void                ParaAttribsChanged( ContentNode const * pNode );
     void                TextModified();
     void                CalcHeight( ParaPortion* pPortion );
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index a90fe3152ee3..e7d739f31e53 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -329,9 +329,9 @@ bool ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView )
             aSelEngine.CursorPosChanging( true, false );
 
             EditSelection aNewSelection( SelectWord( aCurSel ) );
-            pView->pImpEditView->DrawSelection();
+            pView->pImpEditView->DrawSelectionXOR();
             pView->pImpEditView->SetEditSelection( aNewSelection );
-            pView->pImpEditView->DrawSelection();
+            pView->pImpEditView->DrawSelectionXOR();
             pView->ShowCursor();
         }
         else if ( rMEvt.GetClicks() == 3 )
@@ -342,9 +342,9 @@ bool ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView )
             EditSelection aNewSelection( aCurSel );
             aNewSelection.Min().SetIndex( 0 );
             aNewSelection.Max().SetIndex( aCurSel.Min().GetNode()->Len() );
-            pView->pImpEditView->DrawSelection();
+            pView->pImpEditView->DrawSelectionXOR();
             pView->pImpEditView->SetEditSelection( aNewSelection );
-            pView->pImpEditView->DrawSelection();
+            pView->pImpEditView->DrawSelectionXOR();
             pView->ShowCursor();
         }
     }
@@ -709,11 +709,13 @@ const SfxItemSet& ImpEditEngine::GetEmptyItemSet()
 
 //  MISC
 
-void ImpEditEngine::CursorMoved( ContentNode* pPrevNode )
+void ImpEditEngine::CursorMoved( const ContentNode* pPrevNode )
 {
     // Delete empty attributes, but only if paragraph is not empty!
-    if ( pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len() )
-        pPrevNode->GetCharAttribs().DeleteEmptyAttribs( aEditDoc.GetItemPool() );
+    if (pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len())
+    {
+        const_cast<ContentNode*>(pPrevNode)->GetCharAttribs().DeleteEmptyAttribs(aEditDoc.GetItemPool());
+    }
 }
 
 void ImpEditEngine::TextModified()
@@ -913,15 +915,27 @@ EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pE
     aSelEngine.SetCurView( pEditView );
     aSelEngine.CursorPosChanging( bKeyModifySelection, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
     EditPaM aOldEnd( pEditView->pImpEditView->GetEditSelection().Max() );
-    pEditView->pImpEditView->GetEditSelection().Max() = aPaM;
+
+    {
+        EditSelection aNewSelection(pEditView->pImpEditView->GetEditSelection());
+        aNewSelection.Max() = aPaM;
+        pEditView->pImpEditView->SetEditSelection(aNewSelection);
+        // const_cast<EditPaM&>(pEditView->pImpEditView->GetEditSelection().Max()) = aPaM;
+    }
+
     if ( bKeyModifySelection )
     {
         // Then the selection is expanded ... or the whole selection is painted in case of tiled rendering.
         EditSelection aTmpNewSel( comphelper::LibreOfficeKit::isActive() ? pEditView->pImpEditView->GetEditSelection().Min() : aOldEnd, aPaM );
-        pEditView->pImpEditView->DrawSelection( aTmpNewSel );
+        pEditView->pImpEditView->DrawSelectionXOR( aTmpNewSel );
     }
     else
-        pEditView->pImpEditView->GetEditSelection().Min() = aPaM;
+    {
+        EditSelection aNewSelection(pEditView->pImpEditView->GetEditSelection());
+        aNewSelection.Min() = aPaM;
+        pEditView->pImpEditView->SetEditSelection(aNewSelection);
+        // const_cast<EditPaM&>(pEditView->pImpEditView->GetEditSelection().Min()) = aPaM;
+    }
 
     return pEditView->pImpEditView->GetEditSelection();
 }
@@ -3428,12 +3442,12 @@ void ImpEditEngine::SetActiveView( EditView* pView )
         return;
 
     if ( pActiveView && pActiveView->HasSelection() )
-        pActiveView->pImpEditView->DrawSelection();
+        pActiveView->pImpEditView->DrawSelectionXOR();
 
     pActiveView = pView;
 
     if ( pActiveView && pActiveView->HasSelection() )
-        pActiveView->pImpEditView->DrawSelection();
+        pActiveView->pImpEditView->DrawSelectionXOR();
 
     //  NN: Quick fix for #78668#:
     //  When editing of a cell in Calc is ended, the edit engine is not deleted,
@@ -4325,7 +4339,7 @@ void ImpEditEngine::IndentBlock( EditView* pEditView, bool bRight )
             aNewSel.nEndPos = 0;
         }
 
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->pImpEditView->SetEditSelection(
                         pEditView->pImpEditView->GetEditSelection().Max() );
         UndoActionStart( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
@@ -4361,7 +4375,7 @@ void ImpEditEngine::IndentBlock( EditView* pEditView, bool bRight )
         if ( pLastNode->Len() < aNewSel.nEndPos )
             aNewSel.nEndPos = pLastNode->Len();
         pEditView->pImpEditView->SetEditSelection( CreateSel( aNewSel ) );
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->pImpEditView->ShowCursor( false, true );
     }
 }
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index e07312e4aa05..f46e14e0f0dd 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -3848,10 +3848,10 @@ void ImpEditEngine::Paint( ImpEditView* pView, const tools::Rectangle& rRect, Ou
     else
         pTarget->SetClipRegion();
 
-    // In case of tiled rendering pass a region to DrawSelection(), so that
+    // In case of tiled rendering pass a region to DrawSelectionXOR(), so that
     // selection callbacks are not emitted during every repaint.
     vcl::Region aRegion;
-    pView->DrawSelection(pView->GetEditSelection(), comphelper::LibreOfficeKit::isActive() ? &aRegion : nullptr, pTarget);
+    pView->DrawSelectionXOR(pView->GetEditSelection(), comphelper::LibreOfficeKit::isActive() ? &aRegion : nullptr, pTarget);
 }
 
 void ImpEditEngine::InsertContent( ContentNode* pNode, sal_Int32 nPos )
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index 7e6d2c769952..e0e9840d5bd7 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -1500,12 +1500,12 @@ EESpellState ImpEditEngine::Spell( EditView* pEditView, bool bMultipleDoc )
 
     if ( !bMultipleDoc )
     {
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
             aCurSel.Max().SetIndex( aCurSel.Max().GetNode()->Len() );
         aCurSel.Min() = aCurSel.Max();
         pEditView->pImpEditView->SetEditSelection( aCurSel );
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->ShowCursor( true, false );
     }
     EESpellState eState = pSpellInfo->eState;
@@ -1623,12 +1623,12 @@ void ImpEditEngine::Convert( EditView* pEditView,
 
     if ( !bMultipleDoc )
     {
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
             aCurSel.Max().SetIndex( aCurSel.Max().GetNode()->Len() );
         aCurSel.Min() = aCurSel.Max();
         pEditView->pImpEditView->SetEditSelection( aCurSel );
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->ShowCursor( true, false );
     }
     delete pConvInfo;
@@ -1826,9 +1826,9 @@ void ImpEditEngine::ImpConvert( OUString &rConvTxt, LanguageType &rConvTxtLang,
         pConvInfo->aConvContinue = CreateEPaM( aCurSel.Max() );
     }
 
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     pEditView->pImpEditView->SetEditSelection( aCurSel );
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     pEditView->ShowCursor( true, false );
 
     rConvTxt = aRes;
@@ -1896,9 +1896,9 @@ Reference< XSpellAlternatives > ImpEditEngine::ImpSpell( EditView* pEditView )
             pSpellInfo->eState = EESpellState::ErrorFound;
     }
 
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     pEditView->pImpEditView->SetEditSelection( aCurSel );
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     pEditView->ShowCursor( true, false );
     return xSpellAlt;
 }
@@ -2488,9 +2488,9 @@ EESpellState ImpEditEngine::StartThesaurus( EditView* pEditView )
     if (xDlg->Execute() == RET_OK)
     {
         // Replace Word...
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->pImpEditView->SetEditSelection( aCurSel );
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
         pEditView->InsertText(xDlg->GetWord());
         pEditView->ShowCursor(true, false);
     }
@@ -2530,7 +2530,7 @@ sal_Int32 ImpEditEngine::StartSearchAndReplace( EditView* pEditView, const SvxSe
         SvxSearchItem aTmpItem( rSearchItem );
         aTmpItem.SetBackward( false );
 
-        pEditView->pImpEditView->DrawSelection();
+        pEditView->pImpEditView->DrawSelectionXOR();
 
         aCurSel.Adjust( aEditDoc );
         EditPaM aStartPaM = aTmpItem.GetSelection() ? aCurSel.Min() : aEditDoc.GetStartPaM();
@@ -2555,7 +2555,7 @@ sal_Int32 ImpEditEngine::StartSearchAndReplace( EditView* pEditView, const SvxSe
         }
         else
         {
-            pEditView->pImpEditView->DrawSelection();
+            pEditView->pImpEditView->DrawSelectionXOR();
             pEditView->ShowCursor( true, false );
         }
     }
@@ -2578,7 +2578,7 @@ bool ImpEditEngine::Search( const SvxSearchItem& rSearchItem, EditView* pEditVie
         bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
     }
 
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     if ( bFound )
     {
         // First, set the minimum, so the whole word is in the visible range.
@@ -2589,7 +2589,7 @@ bool ImpEditEngine::Search( const SvxSearchItem& rSearchItem, EditView* pEditVie
     else
         pEditView->pImpEditView->SetEditSelection( aSel.Max() );
 
-    pEditView->pImpEditView->DrawSelection();
+    pEditView->pImpEditView->DrawSelectionXOR();
     pEditView->ShowCursor( true, false );
     return bFound;
 }
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 54e92ffc6b10..55fe8dc174af 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -162,7 +162,7 @@ private:
                        EditEngine&     operator=( const EditEngine& ) = delete;
     EDITENG_DLLPRIVATE bool            PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pView, vcl::Window const * pFrameWin );
 
-    EDITENG_DLLPRIVATE void CursorMoved(ContentNode* pPrevNode);
+    EDITENG_DLLPRIVATE void CursorMoved(const ContentNode* pPrevNode);
     EDITENG_DLLPRIVATE void CheckIdleFormatter();
     EDITENG_DLLPRIVATE bool IsIdleFormatterActive() const;
     EDITENG_DLLPRIVATE ParaPortion* FindParaPortion(ContentNode const * pNode);
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index ac6ffc5433d1..9bb09f8d2d8a 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -293,7 +293,7 @@ public:
     /// Allows adjusting the point or mark of the selection to a document coordinate.
     void SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark);
     /// Trigger selection drawing callback in pOtherShell based on our shell's selection state.
-    void DrawSelection(OutlinerViewShell* pOtherShell);
+    void DrawSelectionXOR(OutlinerViewShell* pOtherShell);
 };
 
 #endif // INCLUDED_EDITENG_EDITVIEW_HXX
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index a2df0116562f..9e0f2b0220bd 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -533,7 +533,7 @@ void ScTabViewShell::NotifyCursor(SfxViewShell* pOtherShell) const
             rEditView.ShowCursor();
             rEditView.RegisterOtherShell(nullptr);
             // Text selection, if any.
-            rEditView.DrawSelection(pOtherShell);
+            rEditView.DrawSelectionXOR(pOtherShell);
         }
         else
         {
diff --git a/sd/source/ui/view/ViewShellBase.cxx b/sd/source/ui/view/ViewShellBase.cxx
index 9899c6f0314a..7ec564cc24b2 100644
--- a/sd/source/ui/view/ViewShellBase.cxx
+++ b/sd/source/ui/view/ViewShellBase.cxx
@@ -996,7 +996,7 @@ void ViewShellBase::NotifyCursor(SfxViewShell* pOtherShell) const
         rEditView.ShowCursor();
         rEditView.RegisterOtherShell(nullptr);
         // Text selection, if any.
-        rEditView.DrawSelection(pOtherShell);
+        rEditView.DrawSelectionXOR(pOtherShell);
 
         // Shape text lock.
         if (OutlinerView* pOutlinerView = pDrawView->GetTextEditOutlinerView())
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 6f1029e0564f..18abfe6ae3f4 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -1187,7 +1187,7 @@ void SwCursorShell::NotifyCursor(SfxViewShell* pOtherShell) const
         rEditView.ShowCursor();
         rEditView.RegisterOtherShell(nullptr);
         // Text selection, if any.
-        rEditView.DrawSelection(pOtherShell);
+        rEditView.DrawSelectionXOR(pOtherShell);
 
         // Shape text lock.
         if (OutlinerView* pOutlinerView = pView->GetTextEditOutlinerView())
commit 1c77763ae77c1c48443f3b5cce27b2287503b473
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Sat Aug 5 09:23:23 2017 +0200

    editviewoverlay: Linux build corrections
    
    Change-Id: If842f392a668e007bacf66d9fa750464e5f7b99f

diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 4d83a0613e19..ac6ffc5433d1 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -72,6 +72,7 @@ namespace linguistic2 {
     class XLanguageGuessing;
 }
 }}}
+namespace basegfx { class B2DRange; }
 
 enum class ScrollRangeCheck
 {
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index f0c430f4426f..8348988b2ca1 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -66,6 +66,8 @@
 #include <sfx2/viewsh.hxx>
 #include <svx/svdviter.hxx>
 #include <svx/sdr/overlay/overlayselection.hxx>
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdrpagewindow.hxx>
 
 #include <memory>
 
@@ -445,8 +447,8 @@ namespace
         const Color& rColor,
         OutlinerView& rOutlinerView,
         bool bVisualizeSurroundingFrame)
-    :   mpOverlaySelection(pOverlaySelection),
-        OverlayObject(rColor),
+    :   OverlayObject(rColor),
+        mpOverlaySelection(pOverlaySelection),
         mrOutlinerView(rOutlinerView),
         maLastRange(),
         maRange(),
diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx
index 82c7c96ea7cf..580dee39b174 100644
--- a/svx/source/svdraw/svdoutl.cxx
+++ b/svx/source/svdraw/svdoutl.cxx
@@ -24,6 +24,7 @@
 #include <svx/svdmodel.hxx>
 #include <editeng/eeitem.hxx>
 #include <svl/itempool.hxx>
+#include <editeng/editview.hxx>
 
 
 SdrOutliner::SdrOutliner( SfxItemPool* pItemPool, OutlinerMode nMode )
commit 4ec0545b5adcda14bafd82919078258dd042c5b5
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri Aug 4 18:56:43 2017 +0200

    editviewoverlay: Allow EditView to run in Overlay
    
    This is the first basic functionality to get the active
    EditView with EditEngine work in the Overlay which all
    Apps support. Reason is that the current EditEngine 'plugs'
    into the Window and uses Invalidate() calls to repaint
    deeply everything under a text change. While this is
    acceptable for simple cases it can get very slow when
    there are excessive, expensive to paint objects in the
    background, e.g. MasterPages in Draw/Impress with gradients
    and other stuff. This was avoided in older versions (LO51)
    by 'guessing' a good BackgrundColor by the EditEngine,
    not invalidating but painting actively using that guess
    (with better or worse results) which someone removed.
    For the future it is anyways the better way to get the
    EditEngine functionality to Overlay and using Primitives,
    this will be a first step. This may enable Text Editing
    without repainting the Background (fast), using a non-XOR
    selection paint and more. It will need thorough testing
    and further experimenting due to EditEngine being used in
    many places (DrawObjects, Calc Cells, Formular Fields,
    Controls, ...)
    
    Change-Id: Ib9eb0f3999fd61a82ddf7a60ab1ea6ccda3a60da

diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index 4bcc257fc0e4..db7ff1951767 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -153,8 +153,12 @@ LanguageType EditView::CheckLanguage(
     return nLang;
 }
 
-// class EditView
+// class EditViewCallbacks
+EditViewCallbacks::~EditViewCallbacks()
+{
+}
 
+// class EditView
 EditView::EditView( EditEngine* pEng, vcl::Window* pWindow )
 {
     pImpEditView.reset( new ImpEditView( this, pEng, pWindow ) );
@@ -164,6 +168,16 @@ EditView::~EditView()
 {
 }
 
+void EditView::setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks)
+{
+    pImpEditView->setEditViewCallbacks(pEditViewCallbacks);
+}
+
+bool EditView::hasEditViewCallbacks() const
+{
+    return pImpEditView->hasEditViewCallbacks();
+}
+
 ImpEditEngine* EditView::GetImpEditEngine() const
 {
     return pImpEditView->pEditEngine->pImpEditEngine.get();
@@ -190,6 +204,23 @@ tools::Rectangle EditView::GetInvalidateRect() const
     }
 }
 
+void EditView::InvalidateWindow(const tools::Rectangle& rClipRect)
+{
+    if (pImpEditView->hasEditViewCallbacks())
+    {
+        // do not invalidate and trigger a global repaint, but forward
+        // the need for change to the applied EditViewCallback, can e.g.
+        // be used to visualize the active edit text in an OverlayObject
+        pImpEditView->mpEditViewCallbacks->EditViewInvalidate();
+    }
+    else
+    {
+        // classic mode: invalidate and trigger full repaint
+        // of the changed area
+        GetWindow()->Invalidate(rClipRect);
+    }
+}
+
 void EditView::InvalidateOtherViewWindows( const tools::Rectangle& rInvRect )
 {
     if (comphelper::LibreOfficeKit::isActive())
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index 22efd056dbee..fc8ee6745a3a 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -83,6 +83,7 @@ ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, vcl::Window* pWindo
     bClickedInSelection = false;
     eSelectionMode      = EESelectionMode::TxtOnly;
     eAnchorMode         = EEAnchorMode::TopLeft;
+    mpEditViewCallbacks = nullptr;
     nInvMore            = 1;
     nTravelXPos         = TRAVEL_X_DONTKNOW;
     nControl            = EVControlBits::AUTOSCROLL | EVControlBits::ENABLEPASTE;
@@ -185,6 +186,35 @@ void lcl_translateTwips(vcl::Window const & rParent, vcl::Window& rChild)
 
 void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, OutputDevice* pTargetDevice )
 {
+    if (hasEditViewCallbacks() && !pRegion)
+    {
+        // when we have an own mechanism for painting EditViews, collect the Selection
+        // in a basegfx::B2DRange vector and hand over. To do so, call GetSelectionRectangles
+        // which recursively calls ImpEditView::DrawSelection, but with nullptr != pRegion
+        std::vector<tools::Rectangle> aLogicRects;
+        std::vector<basegfx::B2DRange> aLogicRanges;
+        OutputDevice* pTarget = pTargetDevice ? pTargetDevice : pOutWin;
+        const Point aPixel(pTarget ? pTarget->LogicToPixel(Point(1, 1)) : Point(1, 1));
+
+        GetSelectionRectangles(aLogicRects);
+
+        for (const auto& aRect : aLogicRects)
+        {
+            // convert from logic Rectangles to logic Ranges, do not forget to add
+            // one Unit (in this case logical unit, thus calculate first)
+            aLogicRanges.push_back(
+                basegfx::B2DRange(
+                    aRect.Left(), aRect.Top(),
+                    aRect.Right() + aPixel.X(), aRect.Bottom() + aPixel.Y()));
+        }
+
+        // use callback to tell about change in selection visualisation
+        mpEditViewCallbacks->EditViewSelectionChange(aLogicRanges);
+
+        // we are done, do *not* visualize self
+        return;
+    }
+
     if ( eSelectionMode == EESelectionMode::Hidden )
         return;
 
@@ -449,16 +479,9 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
 
 void ImpEditView::GetSelectionRectangles(std::vector<tools::Rectangle>& rLogicRects)
 {
-    bool bMm100ToTwip = pOutWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM;
     vcl::Region aRegion;
     DrawSelection(aEditSelection, &aRegion);
     aRegion.GetRegionRectangles(rLogicRects);
-
-    for (tools::Rectangle& rRectangle : rLogicRects)
-    {
-        if (bMm100ToTwip)
-            rRectangle = OutputDevice::LogicToLogic(rRectangle, MapUnit::Map100thMM, MapUnit::MapTwip);
-    }
 }
 
 void ImpEditView::ImplDrawHighlightRect( OutputDevice* _pTarget, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, tools::PolyPolygon* pPolyPoly )
@@ -627,6 +650,23 @@ void ImpEditView::SetOutputArea( const tools::Rectangle& rRect )
         SetScrollDiffX( (sal_uInt16)aOutArea.GetWidth() * 2 / 10 );
 }
 
+void ImpEditView::InvalidateAtWindow(const tools::Rectangle& rRect)
+{
+    if (hasEditViewCallbacks())
+    {
+        // do not invalidate and trigger a global repaint, but forward
+        // the need for change to the applied EditViewCallback, can e.g.
+        // be used to visualize the active edit text in an OverlayObject
+        mpEditViewCallbacks->EditViewInvalidate();
+    }
+    else
+    {
+        // classic mode: invalidate and trigger full repaint
+        // of the changed area
+        GetWindow()->Invalidate(rRect);
+    }
+}
+
 void ImpEditView::ResetOutputArea( const tools::Rectangle& rRect )
 {
     // remember old out area
@@ -643,38 +683,46 @@ void ImpEditView::ResetOutputArea( const tools::Rectangle& rRect )
 
         if(aOldArea.Left() > aOutArea.Left())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOutArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Left(), aOldArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOutArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Left(), aOldArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
         else if(aOldArea.Left() < aOutArea.Left())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOutArea.Left(), aOldArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOutArea.Left(), aOldArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
 
         if(aOldArea.Right() > aOutArea.Right())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOutArea.Right(), aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOutArea.Right(), aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
         else if(aOldArea.Right() < aOutArea.Right())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Right(), aOldArea.Top() - nMore, aOutArea.Right() + nMore, aOldArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOldArea.Right(), aOldArea.Top() - nMore, aOutArea.Right() + nMore, aOldArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
 
         if(aOldArea.Top() > aOutArea.Top())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Left() - nMore, aOutArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Top()));
+            const tools::Rectangle aRect(aOldArea.Left() - nMore, aOutArea.Top() - nMore, aOldArea.Right() + nMore, aOldArea.Top());
+            InvalidateAtWindow(aRect);
         }
         else if(aOldArea.Top() < aOutArea.Top())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOutArea.Top()));
+            const tools::Rectangle aRect(aOldArea.Left() - nMore, aOldArea.Top() - nMore, aOldArea.Right() + nMore, aOutArea.Top());
+            InvalidateAtWindow(aRect);
         }
 
         if(aOldArea.Bottom() > aOutArea.Bottom())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Left() - nMore, aOutArea.Bottom(), aOldArea.Right() + nMore, aOldArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOldArea.Left() - nMore, aOutArea.Bottom(), aOldArea.Right() + nMore, aOldArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
         else if(aOldArea.Bottom() < aOutArea.Bottom())
         {
-            GetWindow()->Invalidate(tools::Rectangle(aOldArea.Left() - nMore, aOldArea.Bottom(), aOldArea.Right() + nMore, aOutArea.Bottom() + nMore));
+            const tools::Rectangle aRect(aOldArea.Left() - nMore, aOldArea.Bottom(), aOldArea.Right() + nMore, aOutArea.Bottom() + nMore);
+            InvalidateAtWindow(aRect);
         }
     }
 }
@@ -1629,6 +1677,10 @@ void ImpEditView::DeselectAll()
     pEditEngine->SetInSelectionMode(false);
     DrawSelection();
     GetEditSelection().Min() = GetEditSelection().Max();
+
+    // Selection is empty, still need to draw it due to new forward selection
+    // functionality. When without that, nothing will be drawn (since it's empty)
+    DrawSelection();
 }
 
 bool ImpEditView::IsSelectionAtPoint( const Point& rPosPixel )
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index ee05c3e176d6..a41dc0a21032 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -257,6 +257,27 @@ private:
     EditSelection       aEditSelection;
     EEAnchorMode        eAnchorMode;
 
+    /// mechanism to change from the classic refresh mode that simply
+    // invalidates the area where text was changed. When set, the invalidate
+    // and the direct repaint of the Window-plugged EditView will be suppressed.
+    // Instead, a consumer that has registered using a EditViewCallbacks
+    // incarnation has to handle that. Used e.g. to represent the edited text
+    // in Draw/Impres in an OverlayObject which avoids evtl. expensive full
+    // repaints of the EditView(s)
+    const EditViewCallbacks* mpEditViewCallbacks;
+
+    bool hasEditViewCallbacks() const
+    {
+        return nullptr != mpEditViewCallbacks;
+    }
+
+    void setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks)
+    {
+        mpEditViewCallbacks = pEditViewCallbacks;
+    }
+
+    void InvalidateAtWindow(const tools::Rectangle& rRect);
+
 protected:
 
     // DragAndDropClient
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 372e0993723f..e07312e4aa05 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -287,7 +287,10 @@ void ImpEditEngine::UpdateViews( EditView* pCurView )
         {
             // convert to window coordinates ....
             aClipRect = pView->pImpEditView->GetWindowPos( aClipRect );
-            pView->GetWindow()->Invalidate( aClipRect );
+
+            // moved to one executing method to allow finer control
+            pView->InvalidateWindow(aClipRect);
+
             pView->InvalidateOtherViewWindows( aClipRect );
         }
     }
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 07333c75fe93..4d83a0613e19 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -79,6 +79,21 @@ enum class ScrollRangeCheck
     PaperWidthTextSize = 2,   // VisArea must be within paper width, Text Size
 };
 
+// Helper class that allows to set a callback at the EditView. When
+// set, Invalidates and repains are suppressed at the EditView, but
+// EditViewInvalidate() will be triggered to allow the consumer to
+// react itself as needed.
+// Also Selection visualization is suppressed and EditViewSelectionChange
+// is triggered when Selection changes and needs reaction.
+class EDITENG_DLLPUBLIC EditViewCallbacks
+{
+public:
+    EditViewCallbacks() {}
+    virtual ~EditViewCallbacks();
+
+    virtual void EditViewInvalidate() const = 0;
+    virtual void EditViewSelectionChange(const std::vector<basegfx::B2DRange>& rLogicRanges) const = 0;
+};
 
 class EDITENG_DLLPUBLIC EditView final
 {
@@ -105,6 +120,10 @@ public:
                     EditView( EditEngine* pEng, vcl::Window* pWindow );
                     ~EditView();
 
+    // set EditViewCallbacks for external handling of Repaints/Visualization
+    void setEditViewCallbacks(const EditViewCallbacks* pEditViewCallbacks);
+    bool hasEditViewCallbacks() const;
+
     void            SetEditEngine( EditEngine* pEditEngine );
     EditEngine*     GetEditEngine() const;
 
@@ -117,6 +136,7 @@ public:
 
     void            Paint( const tools::Rectangle& rRect, OutputDevice* pTargetDevice = nullptr );
     tools::Rectangle       GetInvalidateRect() const;
+    void            InvalidateWindow(const tools::Rectangle& rClipRect);
     void            InvalidateOtherViewWindows( const tools::Rectangle& rInvRect );
     void            Invalidate();
     Pair            Scroll( long nHorzScroll, long nVertScroll, ScrollRangeCheck nRangeCheck = ScrollRangeCheck::NoNegative );
diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 8dd62ff0b3ec..8bdae7fb0ee4 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -25,6 +25,7 @@
 #include <svx/svxdllapi.h>
 #include <svx/svdglev.hxx>
 #include <svx/selectioncontroller.hxx>
+#include <editeng/editview.hxx>
 #include <memory>
 
 class SdrOutliner;
@@ -57,11 +58,20 @@ enum class SdrEndTextEditKind
 // - macromod
 
 
-class SVX_DLLPUBLIC SdrObjEditView: public SdrGlueEditView
+class SVX_DLLPUBLIC SdrObjEditView: public SdrGlueEditView, public EditViewCallbacks
 {
     friend class                SdrPageView;
     friend class                ImpSdrEditPara;
 
+    // Now derived from EditViewCallbacks and overriding these callbacks to
+    // allow own EditText visualization
+    virtual void EditViewInvalidate() const override;
+    virtual void EditViewSelectionChange(const std::vector<basegfx::B2DRange>& rLogicRanges) const override;
+
+    // The OverlayObjects used for visualizing active TextEdit (currently
+    // using TextEditOverlayObject, but not limitied to it
+    sdr::overlay::OverlayObjectList           maTEOverlayGroup;
+
 protected:
     // TextEdit
     SdrObjectWeakRef            mxTextEditObj;         // current object in TextEdit
diff --git a/include/svx/svdotext.hxx b/include/svx/svdotext.hxx
index 0269c88e5d39..33fa54a321fa 100644
--- a/include/svx/svdotext.hxx
+++ b/include/svx/svdotext.hxx
@@ -598,11 +598,19 @@ public:
         const drawinglayer::geometry::ViewInformation2D& aViewInformation) const;
     void impHandleChainingEventsDuringDecomposition(SdrOutliner &rOutliner) const;
 
-
     // timing generators
     void impGetBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const;
     void impGetScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const;
 
+    // Direct decomposer for text visualization when you already have a prepared
+    // Outliner containing all the needed information
+    static void impDecomposeBlockTextPrimitiveDirect(
+        drawinglayer::primitive2d::Primitive2DContainer& rTarget,
+        SdrOutliner& rOutliner,
+        const basegfx::B2DHomMatrix& rNewTransformA,
+        const basegfx::B2DHomMatrix& rNewTransformB,
+        const basegfx::B2DRange& rClipRange);
+
     /** returns false if the given pointer is NULL
         or if the given SdrOutliner contains no text.
         Also checks for one empty paragraph.
diff --git a/include/svx/svdoutl.hxx b/include/svx/svdoutl.hxx
index a9a885f68fac..5d1f9e842593 100644
--- a/include/svx/svdoutl.hxx
+++ b/include/svx/svdoutl.hxx
@@ -45,6 +45,8 @@ public:
     const SdrPage* getVisualizedPage() const { return mpVisualizedPage; }
 
     virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, Color*& rpTxtColor, Color*& rpFldColor) override;
+
+    bool hasEditViewCallbacks() const;
 };
 
 #endif // INCLUDED_SVX_SVDOUTL_HXX
diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx
index 9b2619ae4e14..c70bb15cd1f8 100644
--- a/sd/source/ui/view/Outliner.cxx
+++ b/sd/source/ui/view/Outliner.cxx
@@ -797,6 +797,17 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti
         std::vector<::tools::Rectangle> aLogicRects;
         pOutlinerView->GetSelectionRectangles(aLogicRects);
 
+        // convert to twips if in 100thmm (seems as if LibreOfficeKit is based on twips?). Do this
+        // here where we have the only place needing this, *not* in ImpEditView::GetSelectionRectangles
+        // which makes that method unusable for others
+        if (pOutlinerView->GetWindow() && MapUnit::Map100thMM == pOutlinerView->GetWindow()->GetMapMode().GetMapUnit())
+        {
+            for (tools::Rectangle& rRectangle : aLogicRects)
+            {
+                rRectangle = OutputDevice::LogicToLogic(rRectangle, MapUnit::Map100thMM, MapUnit::MapTwip);
+            }
+        }
+
         std::vector<OString> aLogicRectStrings;
         std::transform(aLogicRects.begin(), aLogicRects.end(), std::back_inserter(aLogicRectStrings), [](const ::tools::Rectangle& rRectangle) { return rRectangle.toString(); });
         OString sRectangles = comphelper::string::join("; ", aLogicRectStrings);
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 65dede8abcb1..f0c430f4426f 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -65,6 +65,7 @@
 #include <comphelper/lok.hxx>
 #include <sfx2/viewsh.hxx>
 #include <svx/svdviter.hxx>
+#include <svx/sdr/overlay/overlayselection.hxx>
 
 #include <memory>
 
@@ -103,7 +104,6 @@ SdrObjEditView::~SdrObjEditView()
     assert(nullptr == mpOldTextEditUndoManager); // should have been reset
 }
 
-
 bool SdrObjEditView::IsAction() const
 {
     return IsMacroObj() || SdrGlueEditView::IsAction();
@@ -353,39 +353,298 @@ void SdrObjEditView::ModelHasChanged()
     }
 }
 
+namespace
+{
+    /**
+        Helper class to visualize the content of an active EditView as an
+        OverlayObject. These objects work with Primitives and are handled
+        from the OverlayManager(s) in place as needed.
+
+        It allows complete visualization of the content of the active
+        EditView without the need of Invalidates triggered by the EditView
+        and thus avoiding potentially expensive repaints by using the
+        automatically buffered Overlay mechanism.
+
+        It buffers as amuch as possible locally and *only* triggers a real
+        change (see call to objectChange()) when really needed.
+     */
+    class TextEditOverlayObject : public sdr::overlay::OverlayObject
+    {
+    protected:
+        /// local access to associated sdr::overlay::OverlaySelection
+        sdr::overlay::OverlaySelection*     mpOverlaySelection;
+
+        /// local definition depends on active OutlinerView
+        OutlinerView&                       mrOutlinerView;
+
+        /// geometry definitions with buffering
+        basegfx::B2DRange                   maLastRange;
+        basegfx::B2DRange                   maRange;
+
+        /// text content definitions with buffering
+        drawinglayer::primitive2d::Primitive2DContainer     maTextPrimitives;
+        drawinglayer::primitive2d::Primitive2DContainer     maLastTextPrimitives;
+
+        /// bitfield
+        bool                    mbVisualizeSurroundingFrame : 1;
+
+        // geometry creation for OverlayObject, can use local *Last* values
+        virtual drawinglayer::primitive2d::Primitive2DContainer createOverlayObjectPrimitive2DSequence() override;
+
+    public:
+        TextEditOverlayObject(
+            sdr::overlay::OverlaySelection* pOverlaySelection,
+            const Color& rColor,
+            OutlinerView& rOutlinerView,
+            bool bVisualizeSurroundingFrame);
+        virtual ~TextEditOverlayObject() override;
+
+        // data read access
+        const sdr::overlay::OverlaySelection* getOverlaySelection() const { return mpOverlaySelection; }
+        const OutlinerView& getOutlinerView() const { return mrOutlinerView; }
+        bool getVisualizeSurroundingFrame() const { return mbVisualizeSurroundingFrame; }
+
+        /// override to check conditions for last createOverlayObjectPrimitive2DSequence
+        virtual drawinglayer::primitive2d::Primitive2DContainer getOverlayObjectPrimitive2DSequence() const override;
+
+        // data write access. In this OverlayObject we only have the
+        // callback that triggers detecting if something *has* changed
+        void checkDataChange(const basegfx::B2DRange& rMinTextEditArea);
+        void checkSelectionChange(const std::vector<basegfx::B2DRange>& rLogicRanges);
+    };
+
+    drawinglayer::primitive2d::Primitive2DContainer TextEditOverlayObject::createOverlayObjectPrimitive2DSequence()
+    {
+        drawinglayer::primitive2d::Primitive2DContainer aRetval;
+
+        /// outer frame visualization
+        if (getVisualizeSurroundingFrame())
+        {
+            const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+            const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
+            const sal_uInt16 nPixSiz(getOutlinerView().GetInvalidateMore() - 1);
+
+            aRetval.push_back(
+                new drawinglayer::primitive2d::OverlayRectanglePrimitive(
+                    maRange,
+                    getBaseColor().getBColor(),
+                    fTransparence,
+                    std::max(6, nPixSiz - 2), // grow
+                    0.0, // shrink
+                    0.0));
+        }
+
+        // add buffered TextPrimitives
+        aRetval.append(maTextPrimitives);
+
+        return aRetval;
+    }
+
+    TextEditOverlayObject::TextEditOverlayObject(
+        sdr::overlay::OverlaySelection* pOverlaySelection,
+        const Color& rColor,
+        OutlinerView& rOutlinerView,
+        bool bVisualizeSurroundingFrame)
+    :   mpOverlaySelection(pOverlaySelection),
+        OverlayObject(rColor),
+        mrOutlinerView(rOutlinerView),
+        maLastRange(),
+        maRange(),
+        maTextPrimitives(),
+        maLastTextPrimitives(),
+        mbVisualizeSurroundingFrame(bVisualizeSurroundingFrame)
+    {
+        // no AA for TextEdit overlay
+        allowAntiAliase(false);
+    }
+
+    TextEditOverlayObject::~TextEditOverlayObject()
+    {
+        if (getOverlaySelection())
+        {
+            delete mpOverlaySelection;
+            mpOverlaySelection = nullptr;
+        }
+
+        if (getOverlayManager())
+        {
+            getOverlayManager()->remove(*this);
+        }
+    }
+
+    drawinglayer::primitive2d::Primitive2DContainer TextEditOverlayObject::getOverlayObjectPrimitive2DSequence() const
+    {
+        if (!getPrimitive2DSequence().empty())
+        {
+            if (!maRange.equal(maLastRange) || maLastTextPrimitives != maTextPrimitives)
+            {
+                // conditions of last local decomposition have changed, delete to force new evaluation
+                const_cast<TextEditOverlayObject*>(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer());
+            }
+        }
+
+        if (getPrimitive2DSequence().empty())
+        {
+            // remember new buffered values
+            const_cast<TextEditOverlayObject*>(this)->maLastRange = maRange;
+            const_cast<TextEditOverlayObject*>(this)->maLastTextPrimitives = maTextPrimitives;
+        }
+
+        // call base implementation
+        return OverlayObject::getOverlayObjectPrimitive2DSequence();
+    }
+
+    void TextEditOverlayObject::checkDataChange(const basegfx::B2DRange& rMinTextEditArea)
+    {
+        bool bObjectChange(false);
+
+        // check current range
+        const tools::Rectangle aOutArea(mrOutlinerView.GetOutputArea());
+        basegfx::B2DRange aNewRange(aOutArea.Left(), aOutArea.Top(), aOutArea.Right(), aOutArea.Bottom());
+        aNewRange.expand(rMinTextEditArea);
+
+        if (aNewRange != maRange)
+        {
+            maRange = aNewRange;
+            bObjectChange = true;
+        }
+
+        // check if text primitives did change
+        SdrOutliner* pSdrOutliner = dynamic_cast<SdrOutliner*>(getOutlinerView().GetOutliner());
+
+        if (pSdrOutliner)
+        {
+            // get TextPrimitives directly from active Outliner
+            basegfx::B2DHomMatrix aNewTransformA;
+            basegfx::B2DHomMatrix aNewTransformB;
+            basegfx::B2DRange aClipRange;
+            drawinglayer::primitive2d::Primitive2DContainer aNewTextPrimitives;
+
+            // active Outliner is always in unified oriented coordinate system (currently)
+            // so just translate to TopLeft of visible Range
+            tools::Rectangle aVisArea(mrOutlinerView.GetVisArea());
+
+            aNewTransformB.translate(
+                aOutArea.Left() - aVisArea.Left(),
+                aOutArea.Top() - aVisArea.Top());
+
+            // get the current TextPrimitives. This is the most expensive part
+            // of this mechanism, it *may* be possible to buffer layouted
+            // primitives per ParaPortion with/in/dependent on the EditEngine
+            // content if needed. For now, get and compare
+            SdrTextObj::impDecomposeBlockTextPrimitiveDirect(
+                aNewTextPrimitives,
+                *pSdrOutliner,
+                aNewTransformA,
+                aNewTransformB,
+                aClipRange);
+
+            if (aNewTextPrimitives != maTextPrimitives)
+            {
+                maTextPrimitives = aNewTextPrimitives;
+                bObjectChange = true;
+            }
+        }
+
+        if (bObjectChange)
+        {
+            // if there really *was* a change signal the OverlayManager to
+            // refresh this object's visualization
+            objectChange();
+        }
+    }
+
+    void TextEditOverlayObject::checkSelectionChange(const std::vector<basegfx::B2DRange>& rLogicRanges)
+    {
+        if (getOverlaySelection())
+        {
+            mpOverlaySelection->setRanges(rLogicRanges);
+        }
+    }
+} // end of anonymous namespace
 
 // TextEdit
 
+// file-local static bool to control old/new behaviour of active TextEdit visualization
+static bool bAllowTextEditVisualizatkionOnOverlay(true);
 
-void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow) const
+// callback from the active EditView, forward to evtl. existing instances of the
+// TextEditOverlayObject(s)
+void SdrObjEditView::EditViewInvalidate() const
 {
-    // draw old text edit stuff
-    if(IsTextEdit())
+    if (IsTextEdit())
     {
-        const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
+        // MinTextRange may have changed. Forward it, too
+        const basegfx::B2DRange aMinTextRange(
+            aMinTextEditArea.Left(), aMinTextEditArea.Top(),
+            aMinTextEditArea.Right(), aMinTextEditArea.Bottom());
+
+        for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
+        {
+            TextEditOverlayObject* pCandidate = dynamic_cast< TextEditOverlayObject* >(&maTEOverlayGroup.getOverlayObject(a));
+
+            if (pCandidate)
+            {
+                pCandidate->checkDataChange(aMinTextRange);
+            }
+        }
+    }
+}
 
-        if(pActiveOutliner)
+void SdrObjEditView::EditViewSelectionChange(const std::vector<basegfx::B2DRange>& rLogicRanges) const
+{
+    if (IsTextEdit())
+    {
+        for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
         {
-            const sal_uInt32 nViewCount(pActiveOutliner->GetViewCount());
+            TextEditOverlayObject* pCandidate = dynamic_cast< TextEditOverlayObject* >(&maTEOverlayGroup.getOverlayObject(a));
 
-            if(nViewCount)
+            if (pCandidate)
             {
-                const vcl::Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
-                const tools::Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
+                pCandidate->checkSelectionChange(rLogicRanges);
+            }
+        }
+    }
+}
 
-                for(sal_uInt32 i(0); i < nViewCount; i++)
+void SdrObjEditView::TextEditDrawing(SdrPaintWindow& rPaintWindow) const
+{
+    if (bAllowTextEditVisualizatkionOnOverlay)
+    {
+        // adapt TextEditOverlayObject(s). Need also to do this here to
+        // update the current values accordingly
+        EditViewInvalidate();
+    }
+    else
+    {
+        // draw old text edit stuff
+        if (IsTextEdit())
+        {
+            const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
+
+            if (pActiveOutliner)
+            {
+                const sal_uInt32 nViewCount(pActiveOutliner->GetViewCount());
+
+                if (nViewCount)
                 {
-                    OutlinerView* pOLV = pActiveOutliner->GetView(i);
-
-                    // If rPaintWindow knows that the output device is a render
-                    // context and is aware of the underlying vcl::Window,
-                    // compare against that; that's how double-buffering can
-                    // still find the matching OutlinerView.
-                    OutputDevice* pOutputDevice = rPaintWindow.GetWindow() ? rPaintWindow.GetWindow() : &rPaintWindow.GetOutputDevice();
-                    if(pOLV->GetWindow() == pOutputDevice || comphelper::LibreOfficeKit::isActive())
+                    const vcl::Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
+                    const tools::Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
+
+                    for (sal_uInt32 i(0); i < nViewCount; i++)
                     {
-                        ImpPaintOutlinerView(*pOLV, aCheckRect, rPaintWindow.GetTargetOutputDevice());
-                        return;
+                        OutlinerView* pOLV = pActiveOutliner->GetView(i);
+
+                        // If rPaintWindow knows that the output device is a render
+                        // context and is aware of the underlying vcl::Window,
+                        // compare against that; that's how double-buffering can
+                        // still find the matching OutlinerView.
+                        OutputDevice* pOutputDevice = rPaintWindow.GetWindow() ? rPaintWindow.GetWindow() : &rPaintWindow.GetOutputDevice();
+                        if (pOLV->GetWindow() == pOutputDevice || comphelper::LibreOfficeKit::isActive())
+                        {
+                            ImpPaintOutlinerView(*pOLV, aCheckRect, rPaintWindow.GetTargetOutputDevice());
+                            return;
+                        }
                     }
                 }
             }
@@ -513,8 +772,16 @@ OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, OutlinerVie
     // create OutlinerView
     OutlinerView* pOutlView=pGivenView;
     pTextEditOutliner->SetUpdateMode(false);
-    if (pOutlView==nullptr) pOutlView = new OutlinerView(pTextEditOutliner,pWin);
-    else pOutlView->SetWindow(pWin);
+
+    if (pOutlView == nullptr)
+    {
+        pOutlView = new OutlinerView(pTextEditOutliner, pWin);
+    }
+    else
+    {
+        pOutlView->SetWindow(pWin);
+    }
+
     // disallow scrolling
     EVControlBits nStat=pOutlView->GetControlWord();
     nStat&=~EVControlBits::AUTOSCROLL;
@@ -859,6 +1126,57 @@ bool SdrObjEditView::SdrBeginTextEdit(
 
             pTextEditOutlinerView=ImpMakeOutlinerView(pWin,pGivenOutlinerView);
 
+            if (bAllowTextEditVisualizatkionOnOverlay && pTextEditOutlinerView)
+            {
+                // activate visualization of EditView on Overlay
+                pTextEditOutlinerView->GetEditView().setEditViewCallbacks(this);
+
+                const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+                const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
+                const SdrTextObj* pText = dynamic_cast<SdrTextObj*>(GetTextEditObject());
+                const bool bTextFrame(pText && pText->IsTextFrame());
+                const bool bFitToSize(pTextEditOutliner->GetControlWord() & EEControlBits::STRETCHING);
+                const bool bVisualizeSurroundingFrame(bTextFrame && !bFitToSize);
+                SdrPageView* pPageView = GetSdrPageView();
+
+                if (pPageView)
+                {
+                    for (sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
+                    {
+                        const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+                        if (rPageWindow.GetPaintWindow().OutputToWindow())
+                        {
+                            rtl::Reference< sdr::overlay::OverlayManager > xManager = rPageWindow.GetOverlayManager();
+                            if (xManager.is())
+                            {
+                                const basegfx::B2DRange aMinTEArea(
+                                    aMinTextEditArea.Left(), aMinTextEditArea.Top(),
+                                    aMinTextEditArea.Right(), aMinTextEditArea.Bottom());
+                                const std::vector< basegfx::B2DRange > aEmptySelection;
+
+                                sdr::overlay::OverlaySelection* pNewOverlaySelection = new sdr::overlay::OverlaySelection(
+                                    sdr::overlay::OverlayType::Transparent,
+                                    aHilightColor,
+                                    aEmptySelection,
+                                    true);
+
+                                sdr::overlay::OverlayObject* pNewTextEditOverlayObject = new TextEditOverlayObject(
+                                    pNewOverlaySelection,
+                                    aHilightColor,
+                                    *pTextEditOutlinerView,
+                                    bVisualizeSurroundingFrame);
+
+                                xManager->add(*pNewTextEditOverlayObject);
+                                xManager->add(*pNewOverlaySelection);
+
+                                maTEOverlayGroup.append(pNewTextEditOverlayObject);
+                            }
+                        }
+                    }
+                }
+            }
+
             // check if this view is already inserted
             sal_uIntPtr i2,nCount = pTextEditOutliner->GetViewCount();
             for( i2 = 0; i2 < nCount; i2++ )
@@ -1067,6 +1385,13 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
         GetModel()->Broadcast(aHint);
     }
 
+    // if new mechanism was used, clean it up
+    if (bAllowTextEditVisualizatkionOnOverlay && pTextEditOutlinerView)
+    {
+        pTextEditOutlinerView->GetEditView().setEditViewCallbacks(nullptr);
+        maTEOverlayGroup.clear();
+    }
+
     mxTextEditObj.reset(nullptr);
     pTextEditPV=nullptr;
     pTextEditWin=nullptr;
diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx
index 83078bb72216..76ff4f398612 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -1639,5 +1639,18 @@ void SdrTextObj::impDecomposeChainedTextPrimitive(
     rTarget = aConverter.getPrimitive2DSequence();
 }
 
+// Direct decomposer for text visualization when you already have a prepared
+// Outliner containing all the needed information
+void SdrTextObj::impDecomposeBlockTextPrimitiveDirect(
+    drawinglayer::primitive2d::Primitive2DContainer& rTarget,
+    SdrOutliner& rOutliner,
+    const basegfx::B2DHomMatrix& rNewTransformA,
+    const basegfx::B2DHomMatrix& rNewTransformB,
+    const basegfx::B2DRange& rClipRange)
+{
+    impTextBreakupHandler aConverter(rOutliner);
+    aConverter.decomposeBlockTextPrimitive(rNewTransformA, rNewTransformB, rClipRange);
+    rTarget.append(aConverter.getPrimitive2DSequence());
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdotxat.cxx b/svx/source/svdraw/svdotxat.cxx
index 20325165a172..b25ead77cc87 100644
--- a/svx/source/svdraw/svdotxat.cxx
+++ b/svx/source/svdraw/svdotxat.cxx
@@ -287,8 +287,24 @@ bool SdrTextObj::AdjustTextFrameWidthAndHeight()
         if (dynamic_cast<const SdrCaptionObj *>(this) != nullptr) { // this is a hack
             static_cast<SdrCaptionObj*>(this)->ImpRecalcTail();
         }
-        SetChanged();
-        BroadcastObjectChange();
+
+        // to not slow down EditView visualization on Overlay (see
+        // TextEditOverlayObject) it is necessary to suppress the
+        // Invalidates for the deep repaint when the size of the
+        // TextFrame changed (AdjustTextFrameWidthAndHeight returned
+        // true). The ObjectChanges are valid, invalidate will be
+        // done on EndTextEdit anyways
+        const bool bSuppressChangeWhenEditOnOverlay(
+            IsInEditMode() &&
+            GetTextEditOutliner() &&
+            GetTextEditOutliner()->hasEditViewCallbacks());
+
+        if (!bSuppressChangeWhenEditOnOverlay)
+        {
+            SetChanged();
+            BroadcastObjectChange();
+        }
+
         SendUserCall(SdrUserCallType::Resize,aBoundRect0);
     }
     return bRet;
diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx
index 1e3ea5e2e150..82c7c96ea7cf 100644
--- a/svx/source/svdraw/svdoutl.cxx
+++ b/svx/source/svdraw/svdoutl.cxx
@@ -94,4 +94,19 @@ const SdrTextObj* SdrOutliner::GetTextObj() const
         return nullptr;
 }
 
+bool SdrOutliner::hasEditViewCallbacks() const
+{
+    for (size_t a(0); a < GetViewCount(); a++)
+    {
+        OutlinerView* pOutlinerView = GetView(a);
+
+        if (pOutlinerView && pOutlinerView->GetEditView().hasEditViewCallbacks())
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 386fcf9be786b302cd2c6f85ff6d8d97a6777926
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
Date:   Sun Aug 6 02:10:37 2017 +0200

    Avoid warning about invalid alignment value
    
    Default should be left, which equals 1 as an integer.
    
    Change-Id: Ib0498b12d4356bf786ebf8b6fd04d591ac84af6b
    Reviewed-on: https://gerrit.libreoffice.org/40799
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/oox/source/ole/axfontdata.cxx b/oox/source/ole/axfontdata.cxx
index b3da64439a04..1f44be937a26 100644
--- a/oox/source/ole/axfontdata.cxx
+++ b/oox/source/ole/axfontdata.cxx
@@ -58,7 +58,7 @@ bool AxFontData::importBinaryModel( BinaryInputStream& rInStrm )
     aReader.skipIntProperty< sal_Int32 >(); // font offset
     aReader.readIntProperty< sal_uInt8 >( mnFontCharSet );
     aReader.skipIntProperty< sal_uInt8 >(); // font pitch/family
-    sal_uInt8 nTmp = 0;
+    sal_uInt8 nTmp = static_cast<sal_uInt8>(AxHorizontalAlign::Left);
     aReader.readIntProperty< sal_uInt8 >( nTmp );
     mnHorAlign = static_cast<AxHorizontalAlign>(nTmp);
     aReader.skipIntProperty< sal_uInt16 >(); // font weight
commit 8fe86fb89b00b31c73fccbb9bf343818a0a1f537
Author: heiko tietze <tietze.heiko at gmail.com>
Date:   Thu Jul 27 14:43:56 2017 +0200

    tdf#87592 Consistent terminology for Master Slides
    
    All occurences of Slide Master and Master Pages are renamed to
    Master Slide(s).
    
    Change-Id: Idd75089f6c402b3d5e30a812b4c86aacc2f5d9bc
    Reviewed-on: https://gerrit.libreoffice.org/40485
    Reviewed-by: Yousuf Philips <philipz85 at hotmail.com>
    Tested-by: Yousuf Philips <philipz85 at hotmail.com>
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
index fab5d1945cc7..317ef71a3505 100644
--- a/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/PresentationMinimizer.xcu
@@ -119,7 +119,7 @@ The current presentation contains no OLE objects.</value>
             <value xml:lang="en-US">Choose which slides to delete</value>
         </prop>
         <prop oor:name="STR_DELETE_MASTER_PAGES">
-            <value xml:lang="en-US">Delete unused ~master pages</value>
+            <value xml:lang="en-US">Delete unused ~master slides</value>
         </prop>
         <prop oor:name="STR_DELETE_NOTES_PAGES">
             <value xml:lang="en-US">~Clear notes</value>
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
index 73a35e41ceb6..300c9b43da28 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu
@@ -453,7 +453,7 @@
       </node>
       <node oor:name=".uno:SlideMasterPage" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Slide ~Master</value>
+          <value xml:lang="en-US">~Master Slide</value>
         </prop>
         <prop oor:name="Properties" oor:type="xs:int">
           <value>1</value>
@@ -461,7 +461,7 @@
       </node>
       <node oor:name=".uno:NotesMasterPage" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Notes M~aster</value>
+          <value xml:lang="en-US">M~aster Notes</value>
         </prop>
       </node>
       <node oor:name=".uno:InsertPageQuick" oor:op="replace">
@@ -901,7 +901,7 @@
       </node>
       <node oor:name=".uno:PresentationLayout" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Slide Master D~esign...</value>
+          <value xml:lang="en-US">Master Slide D~esign...</value>
         </prop>
         <prop oor:name="Properties" oor:type="xs:int">
           <value>1</value>
@@ -941,7 +941,7 @@
       </node>
       <node oor:name=".uno:HandoutMode" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Hando~ut Master</value>
+          <value xml:lang="en-US">Master Hando~ut</value>
         </prop>
       </node>
       <node oor:name=".uno:DeletePage" oor:op="replace">
@@ -1582,12 +1582,12 @@
       </node>
       <node oor:name=".uno:MasterLayoutsNotes" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Notes Master Layout...</value>
+          <value xml:lang="en-US">Master Notes Layout...</value>
         </prop>
       </node>
       <node oor:name=".uno:MasterLayoutsHandouts" oor:op="replace">
         <prop oor:name="Label" oor:type="xs:string">
-          <value xml:lang="en-US">Handout Master Layout...</value>
+          <value xml:lang="en-US">Master Handout Layout...</value>
         </prop>
       </node>
       <node oor:name=".uno:HeaderAndFooter" oor:op="replace">
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/ImpressWindowState.xcu b/officecfg/registry/data/org/openoffice/Office/UI/ImpressWindowState.xcu
index 9cef881c7c83..3c566c194ea7 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/ImpressWindowState.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/ImpressWindowState.xcu
@@ -132,12 +132,12 @@
       </node>
       <node oor:name="private:resource/popupmenu/pagepanemaster" oor:op="replace">
         <prop oor:name="UIName" oor:type="xs:string">
-          <value xml:lang="en-US">Slide Master Sorter/Pane</value>
+          <value xml:lang="en-US">Master Slide Sorter/Pane</value>
         </prop>
       </node>
       <node oor:name="private:resource/popupmenu/pagepanenoselmaster" oor:op="replace">
         <prop oor:name="UIName" oor:type="xs:string">
-          <value xml:lang="en-US">Slide Master Sorter/Pane (no selection)</value>
+          <value xml:lang="en-US">Master Slide Sorter/Pane (no selection)</value>
         </prop>
       </node>
       <node oor:name="private:resource/popupmenu/table" oor:op="replace">
diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
index 5787aeff01ae..0d7c4bf2d848 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
@@ -107,7 +107,7 @@
 
       <node oor:name="SdMasterPagesDeck" oor:op="replace">
         <prop oor:name="Title" oor:type="xs:string">
-          <value xml:lang="en-US">Master Pages</value>
+          <value xml:lang="en-US">Master Slides</value>
         </prop>
         <prop oor:name="Id" oor:type="xs:string">
           <value>SdMasterPagesDeck</value>
diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc
index e4feaa27a0ae..e3d350063c0a 100644
--- a/sd/inc/strings.hrc
+++ b/sd/inc/strings.hrc
@@ -34,10 +34,10 @@
 #define STR_UNDO_BEZCLOSE                               NC_("STR_UNDO_BEZCLOSE", "Close Polygon")
 #define STR_SLIDE_SORTER_MODE                           NC_("STR_SLIDE_SORTER_MODE", "Slide Sorter")
 #define STR_NORMAL_MODE                                 NC_("STR_NORMAL_MODE", "Normal")
-#define STR_SLIDE_MASTER_MODE                           NC_("STR_SLIDE_MASTER_MODE", "Slide Master")
+#define STR_SLIDE_MASTER_MODE                           NC_("STR_SLIDE_MASTER_MODE", "Master Slide")
 #define STR_OUTLINE_MODE                                NC_("STR_OUTLINE_MODE", "Outline")
 #define STR_NOTES_MODE                                  NC_("STR_NOTES_MODE", "Notes")
-#define STR_NOTES_MASTER_MODE                           NC_("STR_NOTES_MASTER_MODE", "Notes Master")
+#define STR_NOTES_MASTER_MODE                           NC_("STR_NOTES_MASTER_MODE", "Master Notes")
 #define STR_HANDOUT_MASTER_MODE                         NC_("STR_HANDOUT_MASTER_MODE", "Handout")
 #define STR_AUTOLAYOUT_NONE                             NC_("STR_AUTOLAYOUT_NONE", "Blank Slide")
 #define STR_AUTOLAYOUT_ONLY_TITLE                       NC_("STR_AUTOLAYOUT_ONLY_TITLE", "Title Only")
diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx
index 392be76b07ed..d32fc57375ce 100644
--- a/sd/source/core/sdpage.cxx
+++ b/sd/source/core/sdpage.cxx
@@ -1011,7 +1011,7 @@ SdrObject* SdPage::CreateDefaultPresObj(PresObjKind eObjKind)
 
             if(eObjKind == PRESOBJ_HEADER )
             {
-                OSL_FAIL( "SdPage::CreateDefaultPresObj() - can't create a header placeholder for a slide master" );
+                OSL_FAIL( "SdPage::CreateDefaultPresObj() - can't create a header placeholder for a master slide" );
                 return nullptr;
             }
             else
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index 338da53bb7a1..43e0056eb5ac 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -1703,7 +1703,7 @@ void PowerPointExport::AddLayoutIdAndRelation( const FSHelperPtr& pFS, sal_Int32
 
 void PowerPointExport::ImplWriteSlideMaster( sal_uInt32 nPageNum, Reference< XPropertySet > const & aXBackgroundPropSet )
 {
-    SAL_INFO("sd.eppt", "write slide master: " << nPageNum << "\n--------------");
+    SAL_INFO("sd.eppt", "write master slide: " << nPageNum << "\n--------------");
 
     // slides list
     if( nPageNum == 0 )
diff --git a/xmloff/source/draw/ximpbody.cxx b/xmloff/source/draw/ximpbody.cxx
index 3560d8818197..be23c0725876 100644
--- a/xmloff/source/draw/ximpbody.cxx
+++ b/xmloff/source/draw/ximpbody.cxx
@@ -177,7 +177,7 @@ SdXMLDrawPageContext::SdXMLDrawPageContext( SdXMLImport& rImport,
                 }
             }
 
-            SAL_WARN_IF( !bDone, "xmloff", "xmloff::SdXMLDrawPageContext::SdXMLDrawPageContext(), could not find a slide master!" );
+            SAL_WARN_IF( !bDone, "xmloff", "xmloff::SdXMLDrawPageContext::SdXMLDrawPageContext(), could not find a master slide!" );
         }
     }
 
commit e2c14a6caabbb6413ae7b1e631a0a89f7b2ba4c7
Author: Arnaud Versini <Arnaud.Versini at libreoffice.org>
Date:   Sun Jul 23 16:25:20 2017 +0200

    accessibility: remove useless calls to getAccessibleActionCount.
    
    This also removes a lot of useless recursive locks.
    
    Change-Id: Ie7f337683146bb5738f11b8f9194e73437312f03
    Reviewed-on: https://gerrit.libreoffice.org/40325
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/accessibility/inc/standard/vclxaccessiblemenuitem.hxx b/accessibility/inc/standard/vclxaccessiblemenuitem.hxx
index ee0ccd5589e8..5e54ecb595e3 100644
--- a/accessibility/inc/standard/vclxaccessiblemenuitem.hxx
+++ b/accessibility/inc/standard/vclxaccessiblemenuitem.hxx
@@ -92,7 +92,7 @@ public:
     virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override;
 
     // XAccessibleAction
-    virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) override;
+    virtual sal_Int32 SAL_CALL getAccessibleActionCount( ) final override;
     virtual sal_Bool SAL_CALL doAccessibleAction ( sal_Int32 nIndex ) override;
     virtual OUString SAL_CALL getAccessibleActionDescription ( sal_Int32 nIndex ) override;
     virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL getAccessibleActionKeyBinding( sal_Int32 nIndex ) override;
diff --git a/accessibility/source/standard/vclxaccessiblebutton.cxx b/accessibility/source/standard/vclxaccessiblebutton.cxx
index c95004327f86..df67584bdccc 100644
--- a/accessibility/source/standard/vclxaccessiblebutton.cxx
+++ b/accessibility/source/standard/vclxaccessiblebutton.cxx
@@ -187,7 +187,7 @@ sal_Bool VCLXAccessibleButton::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     VclPtr< PushButton > pButton = GetAs< PushButton >();
@@ -202,7 +202,7 @@ OUString VCLXAccessibleButton::getAccessibleActionDescription ( sal_Int32 nIndex
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     return OUString(RID_STR_ACC_ACTION_CLICK);
@@ -213,7 +213,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleButton::getAccessibleActionKeyB
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
diff --git a/accessibility/source/standard/vclxaccessiblecheckbox.cxx b/accessibility/source/standard/vclxaccessiblecheckbox.cxx
index f8243bfc7254..d411c8ca54a2 100644
--- a/accessibility/source/standard/vclxaccessiblecheckbox.cxx
+++ b/accessibility/source/standard/vclxaccessiblecheckbox.cxx
@@ -184,7 +184,7 @@ sal_Bool VCLXAccessibleCheckBox::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     VclPtr< CheckBox > pCheckBox = GetAs< CheckBox >();
@@ -214,7 +214,7 @@ OUString VCLXAccessibleCheckBox::getAccessibleActionDescription ( sal_Int32 nInd
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     if(IsChecked())
@@ -228,7 +228,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleCheckBox::getAccessibleActionKe
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
diff --git a/accessibility/source/standard/vclxaccessiblemenu.cxx b/accessibility/source/standard/vclxaccessiblemenu.cxx
index fd709766618c..def909c40758 100644
--- a/accessibility/source/standard/vclxaccessiblemenu.cxx
+++ b/accessibility/source/standard/vclxaccessiblemenu.cxx
@@ -231,7 +231,7 @@ OUString VCLXAccessibleMenu::getAccessibleActionDescription ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex < 0 || nIndex >= GetChildCount() )
         throw IndexOutOfBoundsException();
 
     return OUString(  );
diff --git a/accessibility/source/standard/vclxaccessiblemenuitem.cxx b/accessibility/source/standard/vclxaccessiblemenuitem.cxx
index 60de73778696..259501bfe4dd 100644
--- a/accessibility/source/standard/vclxaccessiblemenuitem.cxx
+++ b/accessibility/source/standard/vclxaccessiblemenuitem.cxx
@@ -405,7 +405,7 @@ sal_Bool VCLXAccessibleMenuItem::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     Click();
@@ -418,7 +418,7 @@ OUString VCLXAccessibleMenuItem::getAccessibleActionDescription ( sal_Int32 nInd
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     return OUString(RID_STR_ACC_ACTION_SELECT);
@@ -429,7 +429,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleMenuItem::getAccessibleActionKe
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
diff --git a/accessibility/source/standard/vclxaccessibleradiobutton.cxx b/accessibility/source/standard/vclxaccessibleradiobutton.cxx
index 9606092e92f4..bff33c10647c 100644
--- a/accessibility/source/standard/vclxaccessibleradiobutton.cxx
+++ b/accessibility/source/standard/vclxaccessibleradiobutton.cxx
@@ -162,7 +162,7 @@ sal_Bool VCLXAccessibleRadioButton::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     VCLXRadioButton* pVCLXRadioButton = static_cast< VCLXRadioButton* >( GetVCLXWindow() );
@@ -176,7 +176,7 @@ OUString VCLXAccessibleRadioButton::getAccessibleActionDescription ( sal_Int32 n
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     return OUString(RID_STR_ACC_ACTION_SELECT);
@@ -186,7 +186,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleRadioButton::getAccessibleActio
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     OAccessibleKeyBindingHelper* pKeyBindingHelper = new OAccessibleKeyBindingHelper();
diff --git a/accessibility/source/standard/vclxaccessiblescrollbar.cxx b/accessibility/source/standard/vclxaccessiblescrollbar.cxx
index bb83d7ac832d..242f09f69a27 100644
--- a/accessibility/source/standard/vclxaccessiblescrollbar.cxx
+++ b/accessibility/source/standard/vclxaccessiblescrollbar.cxx
@@ -117,12 +117,13 @@ Sequence< OUString > VCLXAccessibleScrollBar::getSupportedServiceNames()
 
 // XAccessibleAction
 
+static constexpr sal_Int32 ACCESSIBLE_ACTION_COUNT=4;
 
 sal_Int32 VCLXAccessibleScrollBar::getAccessibleActionCount( )
 {
     OExternalLockGuard aGuard( this );
 
-    return 4;
+    return ACCESSIBLE_ACTION_COUNT;
 }
 
 
@@ -130,7 +131,7 @@ sal_Bool VCLXAccessibleScrollBar::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT )
         throw IndexOutOfBoundsException();
 
     bool bReturn = false;
@@ -158,7 +159,7 @@ OUString VCLXAccessibleScrollBar::getAccessibleActionDescription ( sal_Int32 nIn
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT )
         throw IndexOutOfBoundsException();
 
     OUString sDescription;
@@ -180,7 +181,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleScrollBar::getAccessibleActionK
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex < 0 || nIndex >= ACCESSIBLE_ACTION_COUNT )
         throw IndexOutOfBoundsException();
 
     return Reference< XAccessibleKeyBinding >();
diff --git a/accessibility/source/standard/vclxaccessibletoolboxitem.cxx b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx
index 5dbc3b4d1050..79dba98565ff 100644
--- a/accessibility/source/standard/vclxaccessibletoolboxitem.cxx
+++ b/accessibility/source/standard/vclxaccessibletoolboxitem.cxx
@@ -621,7 +621,7 @@ sal_Bool VCLXAccessibleToolBoxItem::doAccessibleAction ( sal_Int32 nIndex )
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     if ( m_pToolBox )
@@ -634,7 +634,7 @@ OUString VCLXAccessibleToolBoxItem::getAccessibleActionDescription ( sal_Int32 n
 {
     OExternalLockGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     return OUString(RID_STR_ACC_ACTION_CLICK);
@@ -644,7 +644,7 @@ Reference< XAccessibleKeyBinding > VCLXAccessibleToolBoxItem::getAccessibleActio
 {
     OContextEntryGuard aGuard( this );
 
-    if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
+    if ( nIndex != 0 )
         throw IndexOutOfBoundsException();
 
     return Reference< XAccessibleKeyBinding >();
commit 42b894f80a6d0c39bb0f7092eb204a15c22c4f38
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Sat Aug 5 19:15:36 2017 +0100

    ofz#2867 null deref
    
    Change-Id: If856473683685d79d88b024f7fafa2920b403bb7
    Reviewed-on: https://gerrit.libreoffice.org/40792
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/qa/unit/data/slk/pass/numfmt-2.slk b/sc/qa/unit/data/slk/pass/numfmt-2.slk
new file mode 100644
index 000000000000..5989cdc3e64e
--- /dev/null
+++ b/sc/qa/unit/data/slk/pass/numfmt-2.slk
@@ -0,0 +1 @@
+P;Pÿ                                                               ÿ  ÿ                    ÿ  ÿ  dÿ Sÿ0
\ No newline at end of file
diff --git a/svl/source/numbers/zforscan.cxx b/svl/source/numbers/zforscan.cxx

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list