Just like DOC import does, DOCX should ignore requests
for column breaks when inside of a table.
Based on a 2025 commit to allow page breaks during RTF import,
I assume that the same exception is needed for column breaks.
I tried to round-trip my example document into RTF,
but LO doesn't seem to have imported the column break anyway
(or perhaps it treated it as a page break since there are no columns).
make CppunitTest_sw_ooxmlexport27 \
CPPUNIT_TEST_NAME=testTdf163178_columnbreakInTable
Change-Id: I9796c08b28d9a11730915c5bed0828cd5df300dd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209473
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
Headless mode, when enabled, uses cairo. Thus we must also use
the test's cairo codepath otherwise the test fails on Mac.
Change-Id: I8a307a63c4358f73eaf4ab5ad6e6635b348ae44c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209036
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
After commit db92d0be756305ec0b1e122a1d00333477c17ba5 (dbase: apply
one consistent key-per-page limit in the .ndx index, 2026-08-19) a
local CODA-W build failed with:
C:/lo/online/engine/connectivity/source/drivers/dbase/dindexnode.cxx(518): error C2220: the following warning is treated as an error
C:/lo/online/engine/connectivity/source/drivers/dbase/dindexnode.cxx(518): warning C4018: '<': signed/unsigned mismatch
C:/lo/online/engine/connectivity/source/drivers/dbase/dindexnode.cxx(599): warning C4018: '<': signed/unsigned mismatch
The problem was the change of type of nNewCount from sal_uInt16 to
sal_uInt32, which made the following comparison warn:
if (nNewCount < (nMaxNodes_2 * 2))
nMaxNodes_2 is sal_uInt16, but multiplication gives int; before the
change, nNewCount was promoted from sal_uInt16 to int as well; but
now it isn't promoted, hence the problem.
Fix it by making sure that multiplication produces an unsigned value.
Change-Id: I056fa7517834b64706be27b4318bb21c42ecfebb
Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9581
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
(cherry picked from commit d68d84af021b67ceaf9f94294722c2e97ee9e963)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209455
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
db_maxkeys came from the index header, the key count of a page came from the
page itself, and node access used neither. Now the header value is capped to
the number of keys a DINDEX_PAGE_SIZE page can hold for the given key length,
each page keeps its own capacity and caps its key count to it, and node
positions are clamped to the same bound, so all three agree.
ODbaseIndex::CreateImpl worked out db_maxkeys from a four byte page header
while the reader counts eight bytes of page header, so use eight here too and
write an index the reader agrees with.
ONDXPage::Remove asserted on a position past the key count and then carried on
regardless, so return early instead.
ONDXPage::Merge added the key counts of two pages together in a sal_uInt16, so
widen the sum to sal_uInt32.
nValue was a file-level static shared by the page read and write operators for
no reason, so make it a local in the reader and write rPage.nCount directly.
The two GetChild overloads would load a child page that is already on the chain
of parents the descent came down, so leave such a page unread rather than
descending into a page we are inside. ONDXPage::Merge and ONDXPage::PrintPage
can then be handed a page that was left unread, so both check for one with
nothing loaded.
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: Id51bf8368099447df41aaacbaebba7783c5769e2
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9518
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit db92d0be756305ec0b1e122a1d00333477c17ba5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209449
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Repeat last change (Ctrl-Shift-Y) does work for numbering, but NOT
for repeating the first time, when the NumRule is first created.
That action was considered not repeatable, and thus it blocked
the entire request.
Well, nicely enough an attempt to repeat NUMRULE_CREATE
already does nothing at all, so don't invalidate CanRepeat.
I just reused the first existing unit test that I found with
nice-looking paragraphs that I could turn into numbering.
make CppunitTest_sw_uiwriter CPPUNIT_TEST_NAME=testFdo70807
Change-Id: If85fbe68dec934b0d76e8d4c70b925cf6ace78a7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119201
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
When adding buttons to a QMessageBox, use the QMessageBox API
(QMessageBox::addButton) instead of using the QDialogButtonBox
API of the button box inside of the message box.
While both should have the same effect in general, that is not
necessarily true in practice when a native platform implementation gets
used, like the one newly introduced for KDE Plasma in [1]
commit e95889873fb03efbc1cea4d41b330f9243f5f626
Author: Tobias Fella <fella@posteo.de>
Date: Tue Apr 28 15:02:17 2026 +0000
Add QMessageBox backend for MessageDialog
Make the Platform theme provide a native implementation of MessageDialog. For widgets apps, this effectively shouldn't change anything, since the implementation uses the same component; for QML apps using `MessageDialog`, the QMessageBox widget is now used as implementation instead of a qt-provided qml fallback, which is a significant visual improvement:
[...]
QMessageDialogOptions::customButtons() used in the
KDEPlatformMessageDialogHelper (which subclasses
QPlatformMessageDialogHelper) implementation doesn't
return/take into account buttons directly added to the button
box, but takes into account those added using
QMessageBox::addButton.
Use the latter to add the buttons to avoid the problem
of message dialogs (like the "Save Document?" one)
missing buttons when using the qt6 or kf6 vcl plugin
with SAL_VCL_QT_USE_WELDED_WIDGETS=1 in a KDE Plasma
session new enough to make use of the native message dialog
introduced in the above plasma-integration commit.
(Issue seen e.g. with plasma-integration 6.7.4-1 on
Debian testing when the system Qt is used, but not
a self-compiled Qt dev, where the platform integration
wasn't used.)
[1] https://invent.kde.org/plasma/plasma-integration/-/commit/e95889873fb03efbc1cea4d41b330f9243f5f626
Change-Id: Ied541e76e119493be3288ea899e00d5fbd560ec2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209456
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Allocate and fill in the mpaMemberSlimArray.
In the eager init case, where everything is initially allocated
as Slim results, it uses less memory just to create a simple
linear array rather than storing a pointer for each one.
Fixup the promotion code to move between the arrays rather
than change the pointer in the MemberArray.
On tdf#126710 this saves ~11.5GB (maxresident)
tdf#100244 (full case) this saves about 6.3GB (max resident)
In tdf#126710's case, the 'virt' column in top appeared to save
even more; possibly due to large reallocations in the vector that's
been removed?
Change-Id: I7681304310e060da191edc1fb243900ce59193a7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209101
Tested-by: Jenkins
Reviewed-by: David Gilbert <freedesktop@treblig.org>
Convert lcl_SearchMember to use a templated core since
we're soon going to have two different types to iterate over
(One of which is a pointer, the other an object, hence
needing to parameterise the get function as well).
Change-Id: I4df6a011015ca917f5ad015393ff0f65b2a32ca9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209099
Reviewed-by: David Gilbert <freedesktop@treblig.org>
Tested-by: Jenkins
Define mpaMemberSlimArray as a span of ScDPResultMemberSlim's,
we'll use this in future instead of the Vector that might
hold pointers to any subclass of ScDPResultMember.
Make GetMember and GetMemberCount reference it.
The actual allocation of the array comes later.
Change-Id: Id2abf23e72a92fee0dc3e4326370692a3567dafd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209098
Tested-by: Jenkins
Reviewed-by: David Gilbert <freedesktop@treblig.org>
Use GetMember() for most cases rather than directly
accessing the member array, since soon we'll have
two member arrays.
Change-Id: I76eca012af6743b29de1e53e96a2ff46187f8a8a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209097
Tested-by: Jenkins
Reviewed-by: David Gilbert <freedesktop@treblig.org>
Use GetMemberCount() rather than accessing maMemberArray.size()
directly in most cases, since we're going to have two different
arrays.
Change-Id: I35541b84e3e1704c9725491444b076c05197aa27
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209096
Tested-by: Jenkins
Reviewed-by: David Gilbert <freedesktop@treblig.org>
The hand coded linear array search in FindMember can be replaced with
std::ranges::find_if.
Note: A few months ago I added a comment saying I thought the 'IsNamedItem' check
above wass probably always true - it turns out it's not - which causes the linear
array to be used!
(I can't say I understand the case IsNamedItem is false, here, it
triggers in the tdf#126710 test)
Change-Id: Ia87998f910d1bbf9f120d70acf096d17d4ce4211
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209095
Reviewed-by: David Gilbert <freedesktop@treblig.org>
Tested-by: Jenkins
The patch adds a color interpolation in the HSL color model to the
BColor tools and extends the 'Duplicate' dialog to include these new
color interpolations.
This patch also solves bug tdf#173142.
Change-Id: Ie7f15d65f20b6a8d116c2ac03a57540e6be25ae1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209366
Tested-by: Jenkins
Reviewed-by: Jonathan Clark <jonathan@libreoffice.org>
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
The test checked the "symbol" attribute for an exact match against
"19SwDoubleLinePortion". This string comes from typeid().name(),
which looks different depending on the compiler. GCC/Clang add a
number prefix like "19...", but MSVC (Windows) writes it differently,
like "class SwDoubleLinePortion". So the exact match never worked on
Windows, and the test failed.
Fixed it by checking if the symbol just contains "SwDoubleLinePortion"
instead of matching it exactly. This works no matter which compiler
is used.
Change-Id: Id4ebf1e38b684746a12e93daf80faeb4eda49d26
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208901
Tested-by: Jenkins
Reviewed-by: Jonathan Clark <jonathan@libreoffice.org>
The block frames of the pivot table output used a 1pt line inside
the table and a 2pt line on the outer edges of the table, and the
field cell frames used the 1pt line. Draw all of them with the
thin line width (0.75pt) instead, which is close to the line width
that the default OOXML pivot table style uses, so the whole table
uses one slim border.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Iec99b6890ffa5c8dfc699a30e2fc58d452e5d9ff
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/8255
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 411cfdb91ee02a10361c3d72e13bd64161bba4d5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209432
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
The pivot table output set pivot table specific cell styles on its
cells ("Pivot Table Value", "Pivot Table Result", ...) and created
them in the document on first use. Remove this, so adding a pivot
table no longer adds any cell styles.
The attributes that these styles carried are applied as direct
formatting instead. The member cells are aligned to the left, and
the subtotal and grand total labels and results are bold. The left
alignment is also what makes the member indents visible, an indent
has no effect in a centered cell. The style name mapping in
stylehelper.cxx stays, so documents that already contain these
styles keep working.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Ib33d170d2da38a60c0739eda8fa79ce4f1fcf745
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/8254
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit fee8a092ac3388c873d2b0763f7ce3d8cd032b76)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209431
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
The formatting of the pivot table output was spread across
ScDPOutput: cell styles and frames were applied inline while the
table content was written, and ScDPOutputImpl drew the block
frames.
Add sc::pivot::StyleOutput, which handles all the drawing. ScDPOutput
now only records the sections of the table (layout geometry, field
cells, member spans, subtotal and grand total rows and columns,
indents and expand or collapse buttons). The cell styles are applied
while the sections are recorded, at the same points where they were
applied before, so they always come before any direct formatting
(number formats, pivot table format attributes) reaches the cells.
The block frames, the indents and the expander buttons are then drawn
by apply() in one pass over the collected sections. The drawn output
stays the same as before, and a different look, like the OOXML pivot
table styles, can later be drawn from the same sections.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Ia628de6badf511d299f36bf474194ecad17a9c56
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/8253
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 9f5a36c822b170835c55143716be9eca28ac3e91)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209430
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
The tableColumn "name" attribute is an ST_Xstring, so read it with
getXString (like uniqueName next to it) to decode escapes such as
_x000a_ — an Alt+Enter line break in the header. Read with getString it
kept the literal _x000a_, so a defined name referencing the column via a
structured reference (Table[Col]) no longer matched the real newline and
resolved to #NAME?, breaking a data validation list built on that name.
On export the OOXML serializer already escapes the newline ( ), so
the round-trip stays consistent.
Change-Id: I6c51e2259393fafc38f823fb40ce14d28673d8b1
Signed-off-by: Balazs Varga <balazs.varga@collabora.com>
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9120
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Stephan Bergmann <stephan.bergmann@collabora.com>
(cherry picked from commit f7816a048112157dd603ba9a98dc4f9bf379db97)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209428
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
saving fdo66811-1.odt back to odt writes its one paragraph-anchored
text frame twice into content.xml. on a dbgutil build the save
asserts in XMLTextParagraphExport::RecordNodeIndex with:
xmloff/source/text/txtparae.cxx:1826: Assertion `it == maDocumentNodeOrder.end() || isInShapesTextFrame(xTextContent)' failed.
a problem since:
commit 98ae340307
Date: Fri Apr 22 19:26:47 2022 +0200
tdf#135978 sw_redlinehide: recreate fly frames anchored to subsequent nodes
which recreates the flys of nodes merged under a redline frame on the
assumption that each node's own frame was deleted. here the anchor
node survived a join with its fly frame still attached, so the export's
redline flag flip made AppendObj create a second SwFlyAtContentFrame
on the same anchor frame, and the UNO layer reported the text frame
twice.
so check for an already attached fly before creating another one.
SwFlyFrameFormat::MakeFrames already does this before it creates a
fly, so factor its check out into FindFlyFrameOfFormat and call that
from both places.
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I8fb148288844ee44c0318b8c760130ee2da488da
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/9280
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Michael Stahl <michael.stahl@collabora.com>
(cherry picked from commit f095944cb1dfc278e726859bcb792f84c67a6adb)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209394
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
lcl_GetMaxRowHeight returned the current height of the page body. That
height is smaller when the page has footnotes. SwTabFrame::Split
compares a row that must not split with it. When the row does not fit,
Split treats the row as not fitting the whole page, and splits it so
that no text is hidden. So a row of 4150 twips was compared with 3950,
not with the 4535 that the body has when the page has no footnotes. It
was split, 25 twips short of fitting. SetForceRowSplitAllowed is never
reset, so the row stayed splittable and keep-together was ignored from
then on.
Measure the body as if the page had no footnotes: the print height of
the page, without the header and the footer. The footnotes give that
space back when the row needs it. A footnote of an earlier row stays on
the page that the row leaves. A footnote of the row itself moves with
the row.
This is not enough on its own, because the row can now stay on a page
that is too small for it. Split does not give the first row of a table
to a follow: that would leave the table with no rows, and MakeAll uses
Lower() right after it without a check. So the row stayed, and the text
that did not fit was drawn below the table border, or was not drawn at
all. Split now says what to do about it, and MakeAll does it. Which of
the two ways it is depends on the footnote that took the space.
A footnote of content on an earlier page cannot move, so the table has
to: SwFootnoteRescue::MoveTable. The move needs bMoveAlways, because a
table at the top of a page has no frame before it, and that normally
stops the move. The page still has that footnote, so it is not left
blank; and the next page has no such footnote, so the table does not
move again.
A footnote of the row itself can move, and then the row can stay:
SwFootnoteRescue::MoveOwnFootnote. MakeAll asks the page to put the
footnotes below the table. What has no room left there goes to the next
page, and the body gets that space back. So the row keeps the page, like
in Word. MakeAll asks only once, so a footnote that cannot move does not
make a loop.
This improves on commit 229964ac93
(tdf#163285: consider page body frame height to allow the split,
2024-10-05), which made the rule of commit
b271cc4685 (tdf#123116 sw layout: allow
rows larger than page to split anyway, 2020-03-12) use the body height.
Signed-off-by: Mike Kaganski <mike.kaganski@collabora.com>
Change-Id: Id3177c20df7ba1d9e10d607d98980849f32a843f
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/8954
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 99ad6a1867dc06b9acc386c85373db746e531829)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/209429
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>