These cover the formula behaviour that first-class callables add, and
guard the regressions found while bringing the feature in.
The tests check that:
- an unknown name reports a name error and keeps its text in the stored
formula expression
- a LET whose bound parameters use the ODFF _xlpm. prefix resolves those
parameters and evaluates to the right value
- a built-in used as a value and then called returns the same result as
calling it directly, with no arguments, with one argument, and with
several
- a built-in chosen by IF and then called returns the chosen function's
value
- a call used as an argument to another call evaluates the inner call
first and feeds its result to the outer one
- a callable used where a number is expected reports an illegal
parameter error instead of crashing
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Ic7150f32b7db613811669fbc1f1bbe83520f9ae8
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5585
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 941f444ac8267c266ab6ce3d63212ce62b09ff39)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207820
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
Add BYCOL(tdf#164508), BYROW(tdf#164509), MAKEARRAY(tdf#164511),
MAP(tdf#164512), REDUCE(tdf#164513), SCAN(tdf#161428) formula
functions, which are usually used together with LAMBDA and are
important for interoperability with other Office suites.
Change-Id: I7eb5a992a113638fdadf0cf61592c082094fb44f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205979
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
The OOXML spec writes =@(expr) as =_xlfn.SINGLE(expr). Calc
emitted the bare @ glyph on save and dropped the wrapper on
load, so =@(F3:F5+0) fell back to a non-array context after a
round trip and lost the authored value.
Map "_xlfn.SINGLE" to ocSingleValue in the OOXML symbol
table. The regular exporter walk now spells ocSingleValue as
"_xlfn.SINGLE" and the import compiler recognises the
wrapper, so a parenthesised operand round-trips with no
further work. A small exporter branch wraps bare and
function-call operands in the wrapper's own parentheses.
OOXML files in the wild put the @ operand inside a redundant
parenthesis pair, _xlfn.SINGLE((expr)). A post-compile pass
on import drops the inner pair so the cell reads back as
=@(expr). The helper takes a trigger-opcode list for reuse.
testSingleOperatorXlsxRoundTrip covers the export path,
testIntersectionOperatorXlsxRoundTrip covers the import strip
from a fixture file.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I2648da125945295fd8548842aba9c82978d96aa9
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5573
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 5ac9db1f563bbde01f9e24fc9bbb8c3599eb0c06)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207789
Tested-by: Jenkins
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
The mbAutoDynamicArrayEligible bit marks a cell as allowed to
auto-promote to a dynamic-array master on its first interpret.
The copy constructor propagated the bit, so a paste or fill
clone of a still-eligible source inherited the eligibility and
could auto-promote at the destination position.
Clear the bit on copy and move the explicit set onto the cell
after the local-to-document copy in the UI entry path. The
clone starts non-eligible, and only the freshly typed cell
handed to the document keeps the bit. A paste no longer leaks
into auto-promotion.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I164cdf2411bb4d31148c3a73e1e70440c5f604dc
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5194
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 8b46008b1f709f06cc88040d674659e15ea6f53b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207788
Tested-by: Jenkins
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
The undo object for an EnterMatrix command stored the cell
range and the formula but not the dynamic-array flag. The Redo
path then rebuilt the cell with the default flag value, so a
dynamic-array master entered through the UI came back as a
static Ctrl+Shift+Enter array after a Redo.
Store the flag on the undo object and thread it through the
Redo path. The redone cell keeps the dynamic-array master
status it had before the Undo.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Iee9881fff3b0acb1a5ab6c71e02222a4a4d7d7a0
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5193
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 4c1bc56498cc7200eb7e72b251a73c7dba9e5bbc)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207787
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
XLS-imported cells arrive without an RPN, so the @-restore path
compiles the parse to RPN on demand. That on-demand compile
used to run with the implicit-intersection optimisation on, and
multi-cell range pushes were rewritten to single-cell picks
before the array-intent walk could see them. A plain =A1:A4+10
reloaded from an XLS file then walked as a scalar expression
and never got the @ marker restored.
Disable the optimisation on the on-demand compile. The walk
now sees range pushes as ranges, the binary + with a range
operand walks as array, and the @ marker is restored. Shapes
like =@TRANSPOSE(B1:B4) keep working through the matrix-
function branch.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I92879aa6604864dfc5a5b41999177dbfcffce21a
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5192
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 196cf615e544e62add27fd5eeb42b1cc5f47fbc2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207786
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Otherwise, cutting/copying the entire sheet operates only on the
selected draw object rather than on the entire sheet.
Change-Id: Ie7b1a1c4fb54743c32bd130a9e308f0b6f68fc43
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207745
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
The pre-Interpret walk that decides whether a freshly typed
formula should auto-promote to a dynamic-array master treats
the @ implicit-intersection operator as a transparent unary.
A formula whose every operand carries an @ then walks as
array-and-array and the cell promotes to a master, even though
the interpreter evaluates each @ operand as a scalar. The
displayed value is correct, but the saved file carries the
master flag on a cell that should stay plain.
Treat ocSingleValue as forcing scalar in the walk. The result
of @ is scalar, so the array-ness of its operand no longer
propagates through it.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Ifa2a676bc62a2733b17b728773e6693669ad7717
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5106
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit fbc6b948f675f7787cbe48e55c5f55302eef5e32)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207785
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
The pre-Interpret walk that decides whether a freshly typed
formula should auto-promote to a dynamic-array master used to
bail on every jump command. An IF whose branches are multi-
cell ranges then stayed a plain single-cell formula and only
the upper-left of the chosen branch showed in the cell.
The walk now descends into the branches of IF, IFERROR and
IFNA, reading the branch offsets off the jump token. The
formula promotes to a dynamic-array master and spills when any
branch produces an array.
CHOOSE and LET still bail. Their jump-offset layouts differ
from the IF family and need dedicated handling.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I75a76a2af3634588d76c410e5487b4a87571f3ba
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5105
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit c1fa705be1b53ff677d70040e002bd5d9d7b84c2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207784
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
When the user types a formula that returns an array (UNIQUE,
TRANSPOSE, a range plus a range, ...) and presses Enter, the
cell now becomes a dynamic-array master. The array result
spills into the empty cells to the right and below the typed
cell. The user no longer has to press Ctrl+Shift+Enter to get
array behaviour.
Formulas loaded from a file and formulas created from a macro
keep their old single-value behaviour, so existing documents
are not affected.
A new per-cell bit, mbAutoDynamicArrayEligible, marks a cell
as allowed to promote. The view code sets it on freshly typed
formulas. The importers and the macro entry path leave it off.
When such a cell first calculates, the formula tokens are
walked in execution order to ask the question: does this
formula produce an array result? If yes, the cell switches to
dynamic-array master mode before the calculation runs, so the
array result is kept and the cells to the right and below get
filled in.
The walk tracks whether the value sitting on the stack at each
step is an array or a scalar:
- Pushing a multi-cell range or an inline matrix puts an
array on the stack.
- An operator like + or * keeps the result an array if any
operand was an array.
- A function known to return an array (UNIQUE, TRANSPOSE,
MMULT, SEQUENCE, ...) puts an array on the stack. Other
functions reduce to a scalar.
- Branching functions like IF, CHOOSE, IFERROR and LET do
not fit this simple model, so the walk gives up and the
cell stays a plain single-cell formula.
A formula that begins with the @ implicit-intersection
operator (=@UNIQUE(...)) opts out of promotion. Cells that
are part of a formula group share a single compiled formula
and stay single-cell so the group is not broken.
Ctrl+Shift+Enter still produces a classic static array master.
The shortcut now routes straight to the matrix-entry code, so
the auto-detect described above does not interfere.
The formula compiler has an optimization that rewrites a
multi-cell range as a single-cell pick when the formula sits
in a single-cell context. For example =A1:A4 typed in row 2
becomes =A2 before evaluation. That is the long-standing
implicit-intersection rule.
For typed input the optimization has to be off, otherwise the
multi-cell range disappears from the formula before the walk
can see it. The optimization stays in place everywhere else,
and the engine still applies implicit intersection at run
time when the cell remains a plain single-cell formula.
XLSX export
XLSX marks a dynamic-array master with cm="1" on the cell.
The exporter used to fall back to "matrix master plus a
dynamic-array function" when the explicit flag was missing.
The fallback is now removed. Every cell that should export as
dynamic carries the flag explicitly, set by the importer or
by the UI entry path.
One trade-off: a Ctrl+Shift+Enter (CSE) array of a dynamic-
array function imported from an XLSX file that has no cm="1"
marker no longer round-trips as dynamic. The cell flag is now
the single source of truth.
Tests
Tests cover the array-intent walk for =MINVERSE(...), ={1;2},
={1;2}+3, ={1;2}+{3;4}, ={1;2}+A1, =ABS({-1;-2}), =A1:A2,
=A2:A5+B2:B5, a long chain of binary additions over the same
range, a range times a scalar, =IF(...) with array branches,
and =SUM(...) over a range as the scalar case.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: Icb4b5e108634cd1529ac829cb34865c56ed8ec02
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4684
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
(cherry picked from commit c3d67d3ec81621c385744fac7fd7a722084a122f)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207219
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
ScTokenArray::Clone and CloneValue have always allocated the parse-token array
pCode to hold exactly nLen entries, but unlike Assign they left mbFinalized at
false. And FormulaTokenArray::Add assumes that a non-finalized pCode has room
for at least MAX_FAST_TOKENS entries. Which now started to break with
a21f6a3a0eae72fef90576d249d96dc00beeb2c5 "sc: round-trip dynamic-array masters
and @ through ODF",
> ==611420==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7befc900e420 at pc 0x7b8f762c6d53 bp 0x7ffdf0776f90 sp 0x7ffdf0776f88
> WRITE of size 8 at 0x7befc900e420 thread T0
> #0 in formula::FormulaTokenArray::Add(formula::FormulaToken*) at engine/formula/source/core/api/token.cxx:772:25
> #1 in ScTokenArray::AddRawToken(ScRawToken const&) at engine/sc/source/core/tool/token.cxx:2004:12
> #2 in ScTokenArray::AddOpCode(OpCode) at engine/sc/source/core/tool/token.cxx:2224:12
> #3 in (anonymous namespace)::prependImplicitIntersection(ScTokenArray&) at engine/sc/source/core/data/formulacell.cxx:1654:49
> #4 in ScFormulaCell::ResolveImplicitIntersection(ScTokenArray&, ScDocument&, ScAddress const&) at engine/sc/source/core/data/formulacell.cxx:2716:9
> #5 in ImportExcel::Formula(XclAddress const&, unsigned short, unsigned short, double, bool) at engine/sc/source/filter/excel/excform.cxx:127:17
> #6 in ImportExcel::Formula25() at engine/sc/source/filter/excel/excform.cxx:72:5
> #7 in ImportExcel8::Read() at engine/sc/source/filter/excel/read.cxx:1184:49
> #8 in ScFormatFilterPluginImpl::ScImportExcel(SfxMedium&, ScDocument*, EXCIMPFORMAT) at engine/sc/source/filter/excel/excel.cxx:255:35
> #9 in ScDocShell::ConvertFrom(SfxMedium&) at engine/sc/source/ui/docshell/docsh.cxx:1329:52
> #10 in SfxObjectShell::DoLoad(SfxMedium*) at engine/sfx2/source/doc/objstor.cxx:777:27
> #11 in ScFilterTestBase::loadDoc(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, int) at engine/sc/qa/unit/helper/scfiltertestbase.cxx:40:21
> #12 in ScFiltersTest::load(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int) at engine/sc/qa/unit/filters-test.cxx:68:31
> #13 in non-virtual thunk to ScFiltersTest::load(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int) at engine/sc/qa/unit/filters-test.cxx
> #14 in test::FiltersTest::recursiveScan(test::filterStatus, rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) at engine/unotest/source/cpp/filters-test.cxx:132:20
> #15 in test::FiltersTest::testDir(rtl::OUString const&, std::basic_string_view<char16_t, std::char_traits<char16_t>>, rtl::OUString const&, SfxFilterFlags, SotClipboardFormatId, unsigned int, bool) at engine/unotest/source/cpp/filters-test.cxx:157:5
> #16 in ScFiltersTest::testCVEs() at engine/sc/qa/unit/filters-test.cxx:91:5
>
> 0x7befc900e420 is located 0 bytes after 64-byte region [0x7befc900e3e0,0x7befc900e420)
> allocated by thread T0 here:
> #0 in operator new[](unsigned long) at /home/sberg/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:111:37
> #1 in ScTokenArray::Clone() const at engine/sc/source/core/tool/token.cxx:1901:24
> #2 in ImportExcel::Formula(XclAddress const&, unsigned short, unsigned short, double, bool) at engine/sc/source/filter/excel/excform.cxx:126:70
> #3 in ImportExcel::Formula25() at engine/sc/source/filter/excel/excform.cxx:72:5
Signed-off-by: Stephan Bergmann <stephan.bergmann@collabora.com>
Change-Id: I2ce67e89c24fee8e1bdfa7baf40ce02783637254
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4962
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit e4161389322e3f096e3b1537058a94e0636eaeaa)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207469
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
XLSX marks a dynamic-array master with cm="1" on the cell and a
matching dynamicArrayProperties metadata block. Both import and
export now travel through mbDynamicArrayMaster on the cell.
XLSX import plumbs the flag through the three formula paths.
XML_normal and XML_shared land in applyCellFormulas and
applySharedFormulas through setCellFormula. XML_array lands in
applyArrayFormulas through setCellArrayFormula. Each path sets
mbDynamicArrayMaster on the imported cell or on the matrix master.
XLSX export reads the flag in XclExpFormulaCell::SaveXml to drive
cm="1" and the dynamicArrayProperties block. The legacy pair of a
Ctrl+Shift+Enter (CSE) master that calls a dynamic-array function
stays as a fallback while the importers and the UI entry path are
being wired through.
XLS has no @ encoding and no dynamic-array marker. Save and load
mirror the ODF behaviour:
- The exporter strips ocSingleValue (alongside ocSpaces and
ocWhitespace) in GetNextToken so the BIFF stream stays valid.
The saved formula evaluates to the upper-left value the way XLS
always did.
- The importer walks the just-built RPN of every plain non-array
formula and prepends @ when the formula intends an array. The
resolve runs before the formula cell is constructed, while the
parse array is still mutable. The static helper compiles a
missing RPN on demand so the array-intent walk has the post-fix
order it needs.
- XLS array records keep the legacy CSE behaviour. They have no
dynamic-array encoding, so loading them as static arrays matches
what the file format can express.
Tests cover an XLSX import of Spill.xlsx, an XLSX round trip of the
same file, a direct-XML XLSX export check that the spilled master
at C2 keeps cm="1" and the dynamicArrayProperties metadata block,
and an XLS round trip of =@TRANSPOSE(B1:B4) where the @ reappears
after reload.
Signed-off-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>
Change-Id: I30318bad4cdb50bbd92240fd71d70df0959a0eda
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4664
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 79eda1a177abf9a348dbc67c211b26cabd0cb4c1)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207218
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
* Update translations from branch 'master'
to c1984947ae4582f7d2fdb2b96aaaaebb210fefea
- update translations for master/26.8
and force-fix errors using pocheck
Change-Id: I3a590c433afc5fe06caeabefd54443e293c8b5ad
Use OUString::iterateCodePoints() to get the next code point. Just
incrementing the index does not work with surrogate pairs.
This is an existing bug that was exposed by properly handling surrogate
pairs while case folding in:
commit 8922952429
Author: Khaled Hosny <khaled@libreoffice.org>
Date: Mon Jul 24 18:45:38 2023 +0300
i18nutil: Fix ICU case folding of surrogate pairs
Change-Id: I51328ae6d17ef935d5be00f7327949a26724b9ab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207750
Tested-by: Jenkins
Reviewed-by: Khaled Hosny <khaled@libreoffice.org>
Deleting a word that sits inside an existing tracked formatting change,
with change tracking on but tracked changes hidden, then undoing the
deletion, left the word invisible until Show Changes was switched on again.
Such a deletion produces a redline that is a delete with a format change
stacked on top of it. SwRangeRedline::InvalidateRange only sent the
SwRedlineDelText and SwRedlineUnDelText hints when GetType() was Delete,
but GetType() returns the top of the stack, which is Format here, so the
hints were never sent. Without SwRedlineUnDelText the paragraph frame kept
the stale extents in its merged paragraph and went on hiding the word until
the next full reformat, which toggling Show Changes happens to trigger.
Look through a stacked format change with GetTypeIgnoringAdditonalFormat(),
the same way Show() and Hide() already do, so the hints are sent for these
redlines too and the merged paragraph updates itself on undo.
Change-Id: I8070b89de4d7fb4485a4609d90cdfb93f1db4b29
Signed-off-by: Pranam Lashkari <lpranam@collabora.com>
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/5924
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Michael Stahl <michael.stahl@collabora.com>
(cherry picked from commit 60dbffe37033d6ec947e4f386dffe2e6ef7ce0f6)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207735
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
...redlines when hiding changes
The bugdoc had a format redline, but redlines were hidden, so it looked
like normal text. Then the user selected a word, pressed delete and
seemingly nothing happened, which is unexpected.
What happened is that pressing delete for a selected format redline
creates a delete-then-format redline and our layout code only looked at
the "format" on top, not hiding the text when redlines (deletions) were
asked to be hidden.
Fix the problem by moving GetRedlineTypeIgnoringAdditonalFormat() into
SwRangeRedline and then using it in HideIterator::Next(), to hide not
only deletions but also delete-then-formats when hiding redlines.
This is a problem similar to what commit
1a34019623 (tdf#166319 sw interdependent
redlines: handle ODF export of delete under format, 2025-05-20) fixed,
but there the problem was updating the model to match the layout when
hiding redlines at a model level; and here the problem was to have the
layout from the model in a correct way.
Signed-off-by: Miklos Vajna <vmiklos@collabora.com>
Change-Id: I753d0b9fc8af9d6330f8d0fa719babd7b25ee8f6
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4808
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
(cherry picked from commit 2c5c0e0fca4c510fc436ce9c8850983d953408f7)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207753
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
On at least the GTK and gen plugins, iter_n_children was returning 1
when the node has children on demand but then iter_children will return
false in order to ignore the dummy node. This was causing an infinite
recursion when iter_previous is called and the previous node has
on-demand children because that uses the result of iter_n_children to
determine if the node has children and then uses iter_children to move
to a child node without checking the return value. That meant the
iterator wouldn’t move and it would keep searching from the same place
forever.
This patch fixes it by making iter_n_children non-virtual and making it
bail out early with 0 if the node has children on demand. Otherwise it
will ask the backend via a virtual function which has been renamed to
do_iter_n_children so that it is similar to how do_iter_children works.
Change-Id: Ie9a3d5d51c9eae0789048fa5240441663642595d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207589
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Use the existing helper method instead of creating the
QtInstanceTreeIter directly using the same logic.
Change-Id: If467e962bbd32e905ed8a4052f9fb4f8d4b8b34e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207748
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Use the existing helper method instead of calling
QAbstractItemModel::index manually in
QtInstanceIconView::do_insert.
Change-Id: I871661aab546d46c72ced4d4ebebe87938d123ad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207747
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
This fixes a LO 4.3 regression.
When a Calc sheet is read-only,
and the find-replace dialog does a FindAll or ReplaceAll,
then the SearchResults dialog shows up,
and never really went away.
In editable sheets, the destructor was called when it was closed,
but not for non-editable sheets.
Or, to say it in the words of SearchResultsDlg::Close()
// Remove this dialog from the view frame after the dialog gets
// dismissed, else it would keep popping up endlessly!
SfxDispatcher* pDispacher = mpBindings ->GetDispatcher();
SfxBoolItem aItem(SID_SEARCH_RESULTS_DIALOG, false);
if (pDispacher)
{
pDispacher->ExecuteList(SID_SEARCH_RESULTS_DIALOG,
SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aItem });
}
But the dispatcher was asking GetBlockState
if it was allowed to execute this command
and was being told 'no' because of bNeedEdit.
Since state doesn't matter, just make it a FASTCALL.
Change-Id: Ib12975a2b236b021422bbcd11b6487f9781962c7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207740
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
* Update helpcontent2 from branch 'master'
to 3a7c9104199ddb09e06aad8d6ce1a34ee8bea581
- tdf#74078 documentation: remove 'Page Style' from F&R Attributes
Remove documentation from help
for an attribute that has been removed from the dialog.
git push origin ecma2:refs/for/master
Change-Id: I76768722d66fc5622fb627d8da084b3e506c8c74
Reviewed-on: https://gerrit.libreoffice.org/c/help/+/207741
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
Tested-by: Jenkins
Replaces the manual addition of mapping offsets (GetMapping[X|Y]Offset)
with the encapsulated LogicToOffsetLogic[X|Y] helpers introduced
recently in CoordinateMapper.
This continues the ongoing architectural cleanup by standardizing how
absolute logical coordinates are transitioned into view-relative
logical space before being scaled to device pixels.
- Updated LogicToDevicePixel overloads (Point, Rectangle, Polygon,
B2DPolygon).
- Updated LogicToPixel overloads (Point, Rectangle, Polygon).
- Updated LogicToDeviceSubPixel.
Change-Id: Ie0a6fc40ada9127860a244f3f93e02d9cc658f72
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203652
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Following the migration of the device origin state into
CoordinateMapper, this commit updates the complex coordinate
transformation methods in map.cxx to query the origin directly
from the mapper.
Bypassing the OutputDevice wrappers (GetDeviceOriginX/Y) makes it
explicitly clear that the mapper owns this physical window offset.
This reduces internal reliance on the OutputDevice god-class API
and sets the stage to potentially remove these wrappers entirely.
- Updated LogicToDevicePixel overloads (Point, Rectangle).
- Updated ImplLogicToDevicePixel overloads (Polygon, B2DPolygon,
PolyPolygon).
- Updated ImplDevicePixelToLogic (Rectangle) and
ImplPixelToDevicePixel (Region).
Change-Id: I1b5915f27bf6117a0fd303c7f30603a67ca181a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203651
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
This commit finalizes the migration of the core scalar coordinate
transformations by moving the logic out of OutputDevice and entirely
into CoordinateMapper.
To clearly separate the public API (which handles MapMode state
branching) from the internal math engine (which unconditionally
applies offsets and scaling), the mapping operations have been
explicitly split.
- Removed ImplLogicXToDevicePixel() and ImplLogicYToDevicePixel()
from OutputDevice.
- Added LogicToDevicePixelX() and LogicToDevicePixelY() to
CoordinateMapper to act as the primary state-checking API.
- Added ImplCalcDevicePixelX() and ImplCalcDevicePixelY() to
CoordinateMapper to isolate the raw transformation math.
- Updated all scalar call sites across vcl (bitmap, map, mask,
outdev, pixel, rect) to route their math through the mpMapper
instance.
Change-Id: Ibb23aec54dd6eab6e3a753c2a61f8e023aa03883
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203650
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
vcl/source/outdev/ImplMapRes.cxx:115:70: runtime error: signed integer overflow: -9223372036854775808 + -57089 cannot be represented in type 'long long'
#0 0x592c9880de2d in operator() vcl/source/outdev/ImplMapRes.cxx:115:70
#1 0x592c9880de2d in ImplMapRes::CalcMapResolution(MapMode const&, long, long) vcl/source/outdev/ImplMapRes.cxx:119:9
#2 0x592c9819827c in OutputDevice::SetMapMode(MapMode const&) vcl/source/outdev/map.cxx:519:18
#3 0x592c9830750e in GDIMetaFile::Play(OutputDevice&, unsigned long) vcl/source/gdi/gdimtf.cxx:365:26
#4 0x592c978beda6 in TestImportSVM vcl/source/filter/svm/SvmConverter.cxx:1281:22
This seems to have appeared since:
commit 64c6a8c44b7730d1f703f260e7359642e8af9288
Date: Sun Mar 22 15:09:35 2026 +0200
Fraction->double in MapMode
Clamp the divided value to sal_Int32 range to explicitly restore the
limits that BigInt path incidentally.
Signed-off-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Change-Id: I3c8061a72e447e4bdcad07ace3075076d09285be
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/1891
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Noel Grandin <noel.grandin@collabora.com>
(cherry picked from commit b1dd07307b7a00e73996975616efa113940fdf37)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207723
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Steps to reproduce:
1. Create a calc document with a chart in Calc Online.
2. Open an empty calc document in LO desktop.
3. Copy the chart from Calc Online and paste it into the LO Desktop Calc
file ===> Chart is not pasted.
Details of the issues fixed:
1. <img ...> tag is self closing. Code in calc filter expected a closing
img tag. This is now fixed.
2. Add graphic loading logic for embedded images in html like:
<img src="data:image/png;base64,iVBOR.....">
Signed-off-by: Dennis Francis <dennis.francis@collabora.com>
Change-Id: Ib4aef64727da458b014b570f0e22e81bc869226c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202268
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
(cherry picked from commit dfb400a2eb7574b474e2227dd3c911651543f153)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207719
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
Completes the logical-to-device transformation pipeline by moving
the final physical offset calculations into CoordinateMapper.
OutputDevice no longer needs to manually assemble the view pixels,
device origins, and pixel offsets.
- Added LogicToDevicePixelX() and LogicToDevicePixelY() to
CoordinateMapper to handle the final transformation from view
space to physical device space.
- Simplified ImplLogicXToDevicePixel() and ImplLogicYToDevicePixel()
in map.cxx to directly delegate to these new mapper methods.
- Added comments in CoordinateMapper to clearly delineate the
Viewport (view space) and Physical window (device space) methods.
- Updated the unmapped branches in map.cxx to fetch the device
origin directly from mpMapper.
Change-Id: If7dbcf3fe9ed70fabc6c24d3b4a426cdde7d438c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203649
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
These functions are declared as file-local static helpers in map.cxx,
so they should follow the standard lcl_ naming convention rather
than the Impl prefix, which is generally reserved for private
class methods.
- Renamed ImplLogicToSubPixel() to lcl_logicToSubPixel().
- Renamed ImplSubPixelToLogic() to lcl_subPixelToLogic().
- Updated all call sites in SubPixelToLogic(), LogicWidthToDeviceSubPixel(),
LogicHeightToDeviceSubPixel(), and LogicToDeviceSubPixel().
Change-Id: I01e64f41b153526c13f15856e1182d3bea6802f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203648
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Continues the encapsulation of coordinate mapping logic by moving
the intermediate logical-to-pixel calculation into CoordinateMapper.
This removes the need for OutputDevice to query the mapper for
individual scaling and DPI components just to do the math itself.
- Added LogicToViewPixelX() and LogicToViewPixelY() to CoordinateMapper
to handle the multiplication of the offset logical coordinate, map
resolution scale, and DPI.
- Simplified OutputDevice::ImplLogic[X|Y]ToDevicePixel() to delegate
directly to these new helpers instead of relying on lcl_logicToPixel.
- Included minor formatting cleanup in LogicToLogic.
Change-Id: Iabf90dd129e3f51102c05e27fe11af1bb6d946a1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203647
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins
Completes the deprecation of legacy coordinate subsystem naming by
renaming GetOutOffYPixel() and SetOutOffYPixel() to
GetDeviceOriginY() and SetDeviceOriginY() across OutputDevice,
Window, and CoordinateMapper.
This unifies axis naming conventions following previous X-axis
refactoring passes, clarifying that these fields represent the
physical origin offsets of the device rendering canvas.
This patch also moves view transformation logic inline from outdev/map
to CoordinateMapper, and wraps sprawling multi-line logic formulas
across mapping routines to clean up formatting boundaries.
Key changes:
* include/vcl/outdev.hxx / window.hxx: Updated public declarations
to replace GetOutOffYPixel with GetDeviceOriginY.
* vcl/inc/CoordinateMapper.hxx: Migrated view transformation cache State
members and mapping calculation methods into the mapper object.
* Global adjustments: Patched all related coordinate offset reads
and tracking writes throughout desktop, editeng, sc, svx, and vcl.
Change-Id: I28fec54a7f3312cc41ada2de38b26351c0a65527
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203646
Tested-by: Jenkins
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Rename GetOutOffXPixel() and SetOutOffXPixel() to GetDeviceOriginX()
and SetDeviceOriginX() across OutputDevice, Window, and CoordinateMapper.
The legacy "OutOff" naming convention obscured the difference between
system-level window positioning offsets and internal content scrolling
(SetPixelOffset). The new nomenclature explicitly communicates that
these metrics strictly govern the device coordinate space origin.
This patch focuses strictly on the X-axis coordinate reads and cleans
up duplicated formatting signatures inside the CoordinateMapper header.
Impacted modules:
* include/vcl: Update public declarations in outdev.hxx and window.hxx.
* vcl/inc: Clean up CoordinateMapper.hxx whitespace and scaling hooks.
* Global: Patch dependent pixel coordinate reads across desktop, editeng,
sc, sfx2, svx, and vcl.
Change-Id: I546e1d255887e3b280ff15caca2e27ef10de52d7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206509
Reviewed-by: Dan Williams <dcbw@libreoffice.org>
Tested-by: Jenkins