[Libreoffice-commits] core.git: Branch 'distro/collabora/co-2021' - 3 commits - oox/source sfx2/source sw/qa sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon Mar 29 09:30:34 UTC 2021
oox/source/drawingml/diagram/diagramlayoutatoms.cxx | 70 ++++++-----
oox/source/drawingml/diagram/diagramlayoutatoms.hxx | 10 +
sfx2/source/view/viewsh.cxx | 14 +-
sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt |binary
sw/qa/extras/tiledrendering/tiledrendering.cxx | 76 ++++++++++++
sw/source/uibase/docvw/edtwin.cxx | 10 +
sw/source/uibase/docvw/edtwin2.cxx | 11 +
7 files changed, 156 insertions(+), 35 deletions(-)
New commits:
commit b22578acf41e8f24248014560e288e17a3849c4c
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Jan 12 17:10:49 2021 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Mar 29 10:45:42 2021 +0200
sw edit win: fix read-only selections while handling ExtTextInput
When typing into a protected section (or other read-only area), the code
goes through SwEditWin::KeyInput(), which checks for HasReadonlySel(),
and calls into sw::DocumentContentOperationsManager::InsertString() in
the read-write case.
When typing via ExtTextInput (e.g. Online), then SwEditWin::Command()
called into sw::DocumentContentOperationsManager::InsertString() without
such a check.
The convention is to do a read-only check in the first Writer function
called by vcl, so handle this in SwEditWin::Command(), to have exactly 1
read-only popup on typing a character.
(cherry picked from commit 0c03a97fb8844ad0de1abea79b5265617a509460)
Conflicts:
sw/qa/extras/tiledrendering/tiledrendering.cxx
Change-Id: I7d002e7d76bffeb6f16750de735c5bbf13a7bba9
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index afb261b4d4bc..f8ee487ef788 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -17,6 +17,7 @@
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
#include <test/helper/transferable.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -145,6 +146,7 @@ public:
void testDropDownFormFieldButtonNoSelection();
void testDropDownFormFieldButtonNoItem();
void testTablePaintInvalidate();
+ void testExtTextInputReadOnly();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -217,6 +219,7 @@ public:
CPPUNIT_TEST(testDropDownFormFieldButtonNoSelection);
CPPUNIT_TEST(testDropDownFormFieldButtonNoItem);
CPPUNIT_TEST(testTablePaintInvalidate);
+ CPPUNIT_TEST(testExtTextInputReadOnly);
CPPUNIT_TEST_SUITE_END();
private:
@@ -2869,6 +2872,46 @@ void SwTiledRenderingTest::testTablePaintInvalidate()
CPPUNIT_ASSERT_EQUAL(0, m_nInvalidations);
}
+void SwTiledRenderingTest::testExtTextInputReadOnly()
+{
+ // Create a document with a protected section + a normal paragraph after it.
+ SwXTextDocument* pXTextDocument = createDoc();
+ uno::Reference<text::XTextViewCursorSupplier> xController(
+ pXTextDocument->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursor> xCursor = xController->getViewCursor();
+ uno::Reference<text::XText> xText = xCursor->getText();
+ uno::Reference<text::XTextContent> xSection(
+ pXTextDocument->createInstance("com.sun.star.text.TextSection"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSectionProps(xSection, uno::UNO_QUERY);
+ xSectionProps->setPropertyValue("IsProtected", uno::Any(true));
+ xText->insertTextContent(xCursor, xSection, /*bAbsorb=*/true);
+
+ // First paragraph is the protected section, is it empty?
+ VclPtr<vcl::Window> pEditWin = pXTextDocument->getDocWindow();
+ CPPUNIT_ASSERT(pEditWin);
+ CPPUNIT_ASSERT(getParagraph(1)->getString().isEmpty());
+
+ // Try to type into the protected section, is it still empty?
+ SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/true);
+ SfxLokHelper::postExtTextEventAsync(pEditWin, LOK_EXT_TEXTINPUT, "x");
+ SfxLokHelper::postExtTextEventAsync(pEditWin, LOK_EXT_TEXTINPUT_END, "x");
+ Scheduler::ProcessEventsToIdle();
+ // Without the accompanying fix in place, this test would have failed, as it was possible to
+ // type into the protected section.
+ CPPUNIT_ASSERT(getParagraph(1)->getString().isEmpty());
+
+ // Second paragraph is a normal paragraph, is it empty?
+ pWrtShell->Down(/*bSelect=*/false);
+ CPPUNIT_ASSERT(getParagraph(2)->getString().isEmpty());
+
+ // Try to type into the protected section, does it have the typed content?
+ SfxLokHelper::postExtTextEventAsync(pEditWin, LOK_EXT_TEXTINPUT, "x");
+ SfxLokHelper::postExtTextEventAsync(pEditWin, LOK_EXT_TEXTINPUT_END, "x");
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(OUString("x"), getParagraph(2)->getString());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 9ad8275b7b1b..535a9e1aaf79 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -5544,7 +5544,7 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
{
bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() &&
rSh.IsCursorReadonly();
- if(!bIsDocReadOnly)
+ if (!bIsDocReadOnly && !rSh.HasReadonlySel())
{
if( m_pQuickHlpData->m_bIsDisplayed )
m_pQuickHlpData->Stop( rSh );
@@ -5576,6 +5576,14 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
}
}
}
+
+ if (rSh.HasReadonlySel())
+ {
+ // Inform the user that the request has been ignored.
+ auto xInfo = std::make_shared<weld::GenericDialogController>(
+ GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog");
+ weld::DialogController::runAsync(xInfo, [](sal_Int32 /*nResult*/) {});
+ }
}
break;
case CommandEventId::CursorPos:
commit 009c6c8e10d6fe946ef4f9b8212f9c02c843fe85
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Jan 13 15:10:48 2021 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Mar 29 10:43:07 2021 +0200
oox smartart: extract pyra algo from AlgAtom::layoutShape()
AlgAtom::layoutShape() is more or less the single function where all
layouting happens for all algoritms. Extract the pyra algorithm part
from it to a separate PyraAlg::layoutShapeChildren() before that
function grows too large.
(cherry picked from commit 318438a680e6bf5c2c592d5e997f6f45a4ae8e5f)
Change-Id: I097ac9ed6110536bbeb8a26ab35a8ee8a79d5b33
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
index 122c8d3828db..2f086421f818 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.cxx
@@ -440,6 +440,43 @@ void SnakeAlg::layoutShapeChildren(const AlgAtom::ParamMap& rMap, const ShapePtr
}
}
+void PyraAlg::layoutShapeChildren(const ShapePtr& rShape)
+{
+ if (rShape->getChildren().empty() || rShape->getSize().Width == 0
+ || rShape->getSize().Height == 0)
+ return;
+
+ // const sal_Int32 nDir = maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromT;
+ // const sal_Int32 npyraAcctPos = maMap.count(XML_pyraAcctPos) ? maMap.find(XML_pyraAcctPos)->second : XML_bef;
+ // const sal_Int32 ntxDir = maMap.count(XML_txDir) ? maMap.find(XML_txDir)->second : XML_fromT;
+ // const sal_Int32 npyraLvlNode = maMap.count(XML_pyraLvlNode) ? maMap.find(XML_pyraLvlNode)->second : XML_level;
+ // uncomment when use in code.
+
+ sal_Int32 nCount = rShape->getChildren().size();
+ double fAspectRatio = 0.32;
+
+ awt::Size aChildSize = rShape->getSize();
+ aChildSize.Width /= nCount;
+ aChildSize.Height /= nCount;
+
+ awt::Point aCurrPos(0, 0);
+ aCurrPos.X = fAspectRatio * aChildSize.Width * (nCount - 1);
+ aCurrPos.Y = fAspectRatio * aChildSize.Height;
+
+ for (auto& aCurrShape : rShape->getChildren())
+ {
+ aCurrShape->setPosition(aCurrPos);
+ if (nCount > 1)
+ {
+ aCurrPos.X -= aChildSize.Height / (nCount - 1);
+ }
+ aChildSize.Width += aChildSize.Height;
+ aCurrShape->setSize(aChildSize);
+ aCurrShape->setChildSize(aChildSize);
+ aCurrPos.Y += (aChildSize.Height);
+ }
+}
+
IteratorAttr::IteratorAttr( )
: mnCnt( -1 )
, mbHideLastTrans( true )
@@ -1636,38 +1673,7 @@ void AlgAtom::layoutShape(const ShapePtr& rShape, const std::vector<Constraint>&
case XML_pyra:
{
- if (rShape->getChildren().empty() || rShape->getSize().Width == 0 || rShape->getSize().Height == 0)
- break;
-
- // const sal_Int32 nDir = maMap.count(XML_linDir) ? maMap.find(XML_linDir)->second : XML_fromT;
- // const sal_Int32 npyraAcctPos = maMap.count(XML_pyraAcctPos) ? maMap.find(XML_pyraAcctPos)->second : XML_bef;
- // const sal_Int32 ntxDir = maMap.count(XML_txDir) ? maMap.find(XML_txDir)->second : XML_fromT;
- // const sal_Int32 npyraLvlNode = maMap.count(XML_pyraLvlNode) ? maMap.find(XML_pyraLvlNode)->second : XML_level;
- // uncomment when use in code.
-
- sal_Int32 nCount = rShape->getChildren().size();
- double fAspectRatio = 0.32;
-
- awt::Size aChildSize = rShape->getSize();
- aChildSize.Width /= nCount;
- aChildSize.Height /= nCount;
-
- awt::Point aCurrPos(0, 0);
- aCurrPos.X = fAspectRatio*aChildSize.Width*(nCount-1);
- aCurrPos.Y = fAspectRatio*aChildSize.Height;
-
- for (auto & aCurrShape : rShape->getChildren())
- {
- aCurrShape->setPosition(aCurrPos);
- if (nCount > 1)
- {
- aCurrPos.X -= aChildSize.Height / (nCount - 1);
- }
- aChildSize.Width += aChildSize.Height;
- aCurrShape->setSize(aChildSize);
- aCurrShape->setChildSize(aChildSize);
- aCurrPos.Y += (aChildSize.Height);
- }
+ PyraAlg::layoutShapeChildren(rShape);
break;
}
diff --git a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
index bc59e3ab307a..149be2c97338 100644
--- a/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
+++ b/oox/source/drawingml/diagram/diagramlayoutatoms.hxx
@@ -209,6 +209,16 @@ public:
const std::vector<Constraint>& rConstraints);
};
+/**
+ * Lays out child layout nodes along a vertical path and works with the trapezoid shape to create a
+ * pyramid.
+ */
+class PyraAlg
+{
+public:
+ static void layoutShapeChildren(const ShapePtr& rShape);
+};
+
class ForEachAtom
: public LayoutAtom
{
commit 46bf8a82966ab0940d1f6d5393074d5b4243aa3f
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Nov 24 17:26:32 2020 +0100
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Mar 29 10:33:21 2021 +0200
sw tiled rendering: fix paint->invalidation loop when paint is started by vcl
SwViewShell::PaintTile() already calls
comphelper::LibreOfficeKit::setTiledPainting(), so by the time it would
rearch SwViewShell::Paint(), callbacks (e.g. invalidations) are ignored
during paint.
Do the same for SwEditWin::Paint(), where we processed invalidations
during paint, potentially leading to paint->invalidation loops.
(cherry picked from commit 0f65b4b6f33891a724bee5356aa5549c76fa0ce3)
Change-Id: I8280f5c2571beeae6c0f2986d275dde3c2d33161
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index d35253d1342a..2da4bc1e81bd 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1463,8 +1463,18 @@ void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) c
if (!comphelper::LibreOfficeKit::isActive())
return;
- if (comphelper::LibreOfficeKit::isTiledPainting() && nType != LOK_CALLBACK_FORM_FIELD_BUTTON)
- return;
+ if (comphelper::LibreOfficeKit::isTiledPainting())
+ {
+ switch (nType)
+ {
+ case LOK_CALLBACK_FORM_FIELD_BUTTON:
+ case LOK_CALLBACK_TEXT_SELECTION:
+ break;
+ default:
+ // Reject e.g. invalidate during paint.
+ return;
+ }
+ }
if (pImpl->m_bTiledSearching)
{
diff --git a/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt b/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt
new file mode 100644
index 000000000000..b42c5cc51588
Binary files /dev/null and b/sw/qa/extras/tiledrendering/data/table-paint-invalidate.odt differ
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index dc57ef1e451a..afb261b4d4bc 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -144,6 +144,7 @@ public:
void testDropDownFormFieldButtonEditing();
void testDropDownFormFieldButtonNoSelection();
void testDropDownFormFieldButtonNoItem();
+ void testTablePaintInvalidate();
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -215,6 +216,7 @@ public:
CPPUNIT_TEST(testDropDownFormFieldButtonEditing);
CPPUNIT_TEST(testDropDownFormFieldButtonNoSelection);
CPPUNIT_TEST(testDropDownFormFieldButtonNoItem);
+ CPPUNIT_TEST(testTablePaintInvalidate);
CPPUNIT_TEST_SUITE_END();
private:
@@ -2836,6 +2838,37 @@ void SwTiledRenderingTest::testDropDownFormFieldButtonNoItem()
}
}
+void SwTiledRenderingTest::testTablePaintInvalidate()
+{
+ // Load a document with a table in it.
+ SwXTextDocument* pXTextDocument = createDoc("table-paint-invalidate.odt");
+ SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
+ pWrtShell->GetSfxViewShell()->registerLibreOfficeKitViewCallback(&SwTiledRenderingTest::callback, this);
+ // Enter the table.
+ pWrtShell->Down(/*bSelect=*/false);
+ Scheduler::ProcessEventsToIdle();
+ m_nInvalidations = 0;
+
+ // Paint a tile.
+ size_t nCanvasWidth = 256;
+ size_t nCanvasHeight = 256;
+ std::vector<unsigned char> aPixmap(nCanvasWidth * nCanvasHeight * 4, 0);
+ ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::DEFAULT);
+ pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+ pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(nCanvasWidth, nCanvasHeight),
+ Fraction(1.0), Point(), aPixmap.data());
+ pXTextDocument->paintTile(*pDevice, nCanvasWidth, nCanvasHeight, m_aInvalidation.getX(),
+ m_aInvalidation.getY(), /*nTileWidth=*/1000,
+ /*nTileHeight=*/1000);
+ Scheduler::ProcessEventsToIdle();
+
+ // Without the accompanying fix in place, this test would have failed with
+ // - Expected: 0
+ // - Actual : 5
+ // i.e. paint generated an invalidation, which caused a loop.
+ CPPUNIT_ASSERT_EQUAL(0, m_nInvalidations);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx
index 18003f48bb99..ca1aec7faf7f 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -50,6 +50,7 @@
#include <txtfrm.hxx>
#include <ndtxt.hxx>
#include <FrameControlsManager.hxx>
+#include <comphelper/lok.hxx>
static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon )
{
@@ -431,7 +432,17 @@ void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle
else
{
pWrtShell->setOutputToWindow(true);
+ bool bTiledPainting = false;
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ bTiledPainting = comphelper::LibreOfficeKit::isTiledPainting();
+ comphelper::LibreOfficeKit::setTiledPainting(true);
+ }
pWrtShell->Paint(rRenderContext, rRect);
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ comphelper::LibreOfficeKit::setTiledPainting(bTiledPainting);
+ }
pWrtShell->setOutputToWindow(false);
}
More information about the Libreoffice-commits
mailing list