Calling all developers! The LibreOffice Technology Hackfest will take place in the City of Budapest on June 4th and 5th, 2024.
Calling all developers! The LibreOffice Technology Hackfest will take place in the City of Budapest on June 4th and 5th, 2024.
Love LibreOffice? Help the community that makes it, learn new things, and get a sticker pack for your contributions! (Plus the chance to win some bonus extra merchandise, including mugs, T-shirts and hoodies…)
We’re two weeks into the Month of LibreOffice, May 2024. And so far, 178 people have already taken part and can claim their sticker packs at the end of the month. If you don’t see your name/username on that page yet, and haven’t taken part, here are some ways to join in:
LibreOffice Conference 2024 will take place in Luxembourg, at the Digital Learning Hub and the local campus of 42 Luxembourg in Belval, Esch-sur-Alzette, from 10 to 12 October 2024. As usual, the conference will be preceded by an open day for community member meetings on 9 October 2024.
The photo clearly shows the Terres Rouges building, the large red building in the centre of the Belval University campus, which used to be the largest steelworks in Luxembourg and is home to the Digital Learning Hub, an initiative of the Ministry of National Education, Childhood and Youth of the Grand Duchy of Luxembourg.
The Call for Papers is already open, and can be accessed at the following address: https://events.documentfoundation.org/libreoffice-conference-2024/cfp. The deadline for proposals is 15 August 2024. Approved speakers will be notified by 20 August 2024, while the conference schedule will be published during the first week of September.
The conference website will be ready soon, with additional logistic details for people attending the conference. A big thanks to Paolo Vecchi, who is organizing the conference with the help of local government bodies and volunteers.
In the previous parts of the blog posts series on fixing software crashes, I have written about some crash fixes in LibreOffice around segfaults, aborts, and I discussed how test them. Here I write about fixing assertion failure.
Assertion is a mechanism provided to the developers to make sure that things are good in runtime, conforming to what they were assuming. For example, making sure that some pointer is valid, some data elements match expectation, or some similar assumptions that need to be valid in order to get the correct results.
As an example, consider the C++ function basegfx::utils::createAreaGeometryForLineStartEnd()
, which creates a geometric representation of an arrow. The code resides here:
basegfx/source/polygon/b2dlinegeometry.cxx:84
This is the line of code which contains assertion:
assert((rCandidate.count() > 1) && "createAreaGeometryForLineStartEnd: Line polygon has too few points");
On top of the actual function implementation, the C++ code asserts many conditions to make sure that they are met. In the above assertion, it checks to make sure that the number of points in the given data structure is more than 1. Otherwise, it leads to an assertion failure.
For various reasons, sometimes these sort of assumption may not be valid. To avoid reaching to incorrect results, it is important to have such assertions in place, to find such issues as soon as possible. If you are developing LibreOffice, you may have already built the code from sources in debug mode. Therefore, you may see software stops working, or simply crashes.
This crash may not happen for the end users, which use the release version of software. Therefore, these type of crashes have lower impact for the end users, and they are usually considered of lower importance compared to the crashes that happen for the end users.
One of the things that can help diagnose the problem is the stack trace, or simply backtrace. The way to obtain a backtrace depends on the platform and/or IDE that you use. If you use an IDE like Qt Creator, Visual Studio, etc., getting a backtrace would be as easy as debugging LibreOffice, making the assert fail, and then copy the backtrace from the UI. To learn more about IDEs, see this Wiki page:
If you want to use gdb on Linux, you may run LibreOffice with this command line:
$ instdir/program/soffice –backtrace
and then make the assert fail, and you will have the backtrace in gdbtrace.log file. You can learn more int this QA Wiki article:
TDF Wiki: QA/BugReport/Debug_Information
One thing to mention is that if you work on a reported bug regarding to assertion failure, then the actual way to reproduce the issue and make the assertion fail is usually described in the relevant TDF Bugzilla issue. In the meta bug related to assertion failure, you may find some of these issues in the last part of this blog post.
To fix the problem, first you should gain understanding of the assumption, and why it fails. You should be able to answer these questions by reading the code and debugging it:
To gain this understanding, you have to look into the places where backtrace points. Backtrace can be complex, containing the whole stack of the function calls across the software, linking to places in the code, but let’s discuss a simplified form.
Consider this bug fix:
tdf#152012 Fix assert fail on opening date picker
The problem was that an assertion failure was happening when opening date picker field in a DOCX file. This is the simplified form of the stack trace:
1 __pthread_kill_implementation pthread_kill.c:44 2 __pthread_kill_internal pthread_kill.c:78 3 __GI___pthread_kill pthread_kill.c:89 4 __GI_raise raise.c:26 5 __GI_abort abort.c:79 6 __assert_fail_base assert.c:92 7 __GI___assert_fail assert.c:101 8 o3tl::span::operator[] span.hxx:83 9 OutputDevice::ImplLayout text.cxx:1396 10 OutputDevice::DrawTextArray text.cxx:948 11 Calendar::ImplDraw calendar.cxx:71 12 Calendar::Paint calendar.cxx:1133
The problem was caused by an out of bound access to a vector of integers, and to fix that, you had to see why this happens, and fix that.
This is the description from the commit title:
Previously, for the 7 days of the week, a 7 letter string
smtwtfs
(depending on the week start day this can be different, but length is always 7) was sent to this method without providing the length, thus the string length: 7 was used. In this case, positions of the letters were calculated and used from other array namedmnDayOfWeekAry[7]
.mnDayOfWeekAry[k+1]
was used as the position of letterk
(k=0..5). In this case, there was 7 letters for 7 days, and only 6 positions provided by the array. This caused assertion failure inspan.hxx:83
when trying to access mnDayOfWeekAry[7] viao3tl::span<T>::operator[]
.
As you can see, a false assumption was creating assertion failure, and the fix was essentially changing the code based on the corrected assumption.
Sometimes, the fix can be easier. As an example, by only checking a pointer to make sure that it is valid, the assertion failure does not happen. Therefore, to fix the problem, you have to carefully study the code and its behavior.
Many of the assertion failure bugs are fixed in daily works of the developers, before causing problems for the end users, which use the “release” version of the software, that do not crash because of the assertion failure. But there are some of these issues remaining.
Do you want to help fix some of the remaining issues? Then, please refer to the list here, read some bug report, and pick one:
Berlin, May 10, 2024 – LibreOffice 7.6.7 Community, the last minor release of the 7.6 line, is available from https://www.libreoffice.org/download for Windows, macOS, and Linux. This is the most thoroughly tested version, for deployments by individuals, small and medium businesses, and other organizations in productivity environments. This new minor release fixes bugs and regressions which can be looked up in the changelog [1].
For enterprise-class deployments, TDF strongly recommends the LibreOffice Enterprise family of applications from ecosystem partners – for desktop, mobile and cloud – with many dedicated value-added features and other benefits such as SLA (Service Level Agreements): https://www.libreoffice.org/download/libreoffice-in-business/
Users can download LibreOffice 7.6.7 Community from the office suite website: https://www.libreoffice.org/download/. Minimum requirements are Microsoft Windows 7 SP1 and Apple macOS 10.14. LibreOffice Technology-based products for Android and iOS are listed here: https://www.libreoffice.org/download/android-and-ios/
The Document Foundation does not provide technical support for users, although they can be helped by volunteers on user mailing lists and on the Ask LibreOffice website: https://ask.libreoffice.org
LibreOffice users, free software advocates and community members can support The Document Foundation with a donation at https://www.libreoffice.org/donate
[1] Change log pages: https://wiki.documentfoundation.org/Releases/7.6.7/RC1 and https://wiki.documentfoundation.org/Releases/7.6.7/RC2
Kudos to Ilmari Lauhakangas for helping to elaborate this list.
410 bugs, 67 of which are enhancements, have been reported by 260 people.
398 bugs have been triaged by 66 people.
430 bugs have been set to RESOLVED.
Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.
149 bugs have been fixed by 37 people.
List of high severity bugs fixed
List of crashes fixed
List of performance issues fixed
List of old bugs ( more than 4 years old ) fixed
The LibreOffice Google Summer of Code projects have been selected for 2024.
Good luck to the contributors – we appreciate their work on these important features and improvements! And thanks to our mentors for assisting them: Tomaž Vajngerl (Collabora); Thorsten Behrens, Stephan Bergmann and Sarper Akdemir (allotropia); Rafael Lima; Andreas Heinisch; Heiko Tietze, Xisco Faulí, Michael Weghorn and Hossein Nourikhah (TDF).
Between August 19 and 26, contributors will submit their code, project summaries, and final evaluations of their mentors. Find out more about the timeline here, and check out more details about the projects on this page.
LOWA is LibreOffice built with Emscripten as a Wasm executable that runs in the browser. Controlling that LibreOffice through UNO with JavaScript looks like a natural fit. Enter Embind, a mechanism to generate the binding glue between JavaScript and Wasm/C++.
As we will see, the Embind vs. UNO match is not perfect, but it kind-of gets the job done, at least for a first iteration.
To dive straight into technical matters, the UNO type system is mapped to JavaScript as follows. (If you would like to see some example code first, jump ahead to the Starting Points and come back here later for reference.)
BOOLEAN
, depending on context and somewhat inconsistently maps to JavaScript Boolean
and to JavaScript Number
values 0 and 1. (The C/C++ representation of UNO BOOLEAN
is sal_Bool
, which is an alias for unsigned char
, which Embind maps to JavaScript Number
. So in places where we directly rely on Embind, like for the return value of a UNO interface method invocation, we get the Embind mapping to Number
. But in places where we have more control, like for the JavaScript get
method for a UNO ANY
, we can be a bit more fancy and use a mapping to Boolean
.)BYTE
, SHORT
, UNSIGNED SHORT
, LONG
, UNSIGNED LONG
, FLOAT
, and DOUBLE
all map to JavaScript Number
(with restricted value ranges for everything but UNO DOUBLE
).HYPER
and UNSIGNED HYPER
both map to JavaScript BigInt
(with restricted value ranges).CHAR
and STRING
both map to JavaScript String
(with single UTF-16 code unit strings for UNO CHAR
).TYPE
maps to JavaScript Module.uno_Type
objects. There are construction functions Module.uno_Type.Void
, Module.uno_Type.Boolean
, Module.uno_Type.Byte
, Module.uno_Type.Short
, Module.uno_Type.UnsignedShort
, Module.uno_Type.Long
, Module.uno_Type.UnsignedLong
, Module.uno_Type.Hyper
, Module.uno_Type.UnsignedHyper
, Module.uno_Type.Float
, Module.uno_Type.Double
, Module.uno_Type.Char
, Module.uno_Type.String
, Module.uno_Type.Type
, Module.uno_Type.Any
, Module.uno_Type.Sequence
, Module.uno_Type.Enum
, Module.uno_Type.Struct
, Module.uno_Type.Exception
, and Module.uno_Type.Interface
for representations of all the UNO TYPE
values. The Module.uno_Type.Sequence
construction function recursively takes a UNO TYPE
argument for the component type, while the Module.uno_Type.Enum
, Module.uno_Type.Struct
, Module.uno_Type.Exception
, and Module.uno_Type.Interface
construction functions each take a string argument denoting the given type’s name in dotted notation (e.g., Module.uno_Type.Interface('com.sun.star.uno.XInterface')
). Those JavaScript objects implement toString
, which is also used for equality checks (e.g., type === 'com.sun.star.uno.XInterface'
).ANY
maps to JavaScript Module.uno_Any
objects. There is a constructor taking a UNO TYPE
argument and a corresponding value (using an undefined
value for UNO type VOID
). Those JavaScript objects implement a method get
that returns the JavaScript representation of the contained UNO value.Module.uno_Sequence_...
objects. The problem is that Embind does not let us have a generic mapping to the C++ com::sun::star::uno::Sequence<T>
class template; we can only have individual Embind mappings to specific class template instantiations. As a hack, for every UNO sequence type that appears somewhere in the LibreOffice UNO API, we generate a specific JavaScript Module.uno_Sequence_...
. The naming is Module.uno_Sequence_boolean
, Module.uno_Sequence_byte
, Module.uno_Sequence_short
, Module.uno_Sequence_unsigned_short
, Module.uno_Sequence_long
, Module.uno_Sequence_unsigned_long
, Module.uno_Sequence_hyper
, Module.uno_Sequence_unsigned_hyper
, Module.uno_Sequence_float
, Module.uno_Sequence_double
, Module.uno_Sequence_char
, Module.uno_Sequence_string
, Module.uno_Sequence_type
, and Module.uno_Sequence_any
for the simple UNO component types; Module.uno_Sequence_...
followed by the UNO type name in dollar-separated notation (e.g., Module.uno_Sequence_com$sun$star$uno$XInterface
) for enum, struct, and interface component types; and Module.uno_SequenceN_...
, with N greater than 1, for sequence component types (e.g., Module.uno_Sequence2_long
for the UNO type “sequence of sequence of LONG
“). That means that there currently is just no way to come up with e.g. a JavaScript representation of the UNO type “sequence of interface com.sun.star.frame.XDesktop
“, as that sequence type happens to not be mentioned anywhere in the LibreOffice UNO API. (But for those sequence types that are used as interface method parameter or return types, corresponding JavaScript representations are provided. That should hopefully cover all relevant use cases for now; a future overhaul of this part of the mapping is likely.) These JavaScript sequence objects have two constructors, one taking a JavaScript array of member values (e.g., new Module.uno_Sequence_long([1, 2, 3])
) and one taking a size and a Module.FromSize
marker (as Emind does not allow to have multiple constructors with the same number of arguments) whose members will have default values (e.g., new Module.uno_Sequence_long(3, Module.FromSize)
). Additional methods are resize
(taking the new length as argument), size
(returning the current length), get
(taking an index as argument and returning the member at that index), and set
(taking an index and a new member value as arguments). (The naming of those resize
, size
, get
, and set
methods is modelled after Embind’s emscripten::register_vector
.)Module.uno_Type_...
followed by the UNO type name in dollar-separated notation (e.g., Module.uno_Type_com$sun$star$uno$TypeClass
).Module.uno_Type_...
followed by the UNO type name in dollar-separated notation (e.g., Module.uno_Type_com$sun$star$beans$NamedValue
, Module.uno_Type_com$sun$star$uno$Exception
). Polymorphic UNO struct types face a similar issue to sequence types, in that Embind does not allow to directly map their corresponding C++ class templates. It would be possible to do a similar hack and add specific mappings for all instantiated polymorphic struct types that are mentioned anywhere in the LibreOffice UNO API, but that has not been implemented so far. (And, similar to sequence types, a future overhaul of this part of the mapping is likely.)Module.uno_Type_...
followed by the UNO type name in dollar-separated notation (e.g., Module.uno_Type_com$sun$star$uno$XInterface
). Null references are mapped to JavaScript null
. The special com.sun.star.uno.XInterface
UNO interface methods queryInterface
, acquire
, and release
are not exposed to JavaScript client code.Module.uno_Function_...$$...
followed by the service’s name in dollar-separated notation, followed by the constructor’s name set of by two dollar signs (e.g., Module.uno_Function_com$sun$star$beans$Introspection$$create
). Like with other UNO language bindings, those functions take the com.sun.star.uno.XComponentContext
as an additional first argument.Module.uno_Function_...
followed by the singleton’s name in dollar-separated notation (e.g., Module.uno_Function_com$sun$star$frame$theDesktop
). Like with other UNO language bindings, those functions take the com.sun.star.uno.XComponentContext
as their (sole) argument.To make all this work, the Embind mapping of the LibreOffice UNO API needs to be set up first. This is done by a call to
const uno = init_unoembind_uno(Module);
which also returns a wrapper object uno
that allows for more natural access to all the UNOIDL entities whose mappings use that dollar-separated notation: Instead of Module.uno_Type_com$sun$star$uno$XInterface
one can write uno.com.sun.star.uno.XInterface
, and a call to uno_Function_com$sun$star$beans$Introspection$$create(context)
can be written as uno.com.sun.star.beans.Introspection.create(context)
. If you want to cut down on the common uno.com.sun.star
prefix even further,
const css = uno.com.sun.star;
lets you reduce that to just css.uno.XInterface
and css.beans.Introspection.create(context)
.
The starting points to access the LibreOffice UNO API from JavaScript are Module.getUnoComponentContext()
(returning the central css.uno.XComponentContext
, through which all the services and singletons are reachable) and a Module.getCurrentModelFromViewSh()
convenience function (returning the css.frame.XModel
of the currently showing document). The gitlab.com/allotropia/lowa-demos
repository is a growing site of example code showing all of this in action.
Summing this up, here is some example code that iterates over all the paragraphs of a Writer document and gives each of them a random foreground text color:
const uno = init_unoembind_uno(Module);
const css = uno.com.sun.star;
const model = Module.getCurrentModelFromViewSh();
const document = css.text.XTextDocument.query(model);
const text = document.getText();
const access = css.container.XEnumerationAccess.query(text);
const paragraphs = access.createEnumeration();
while (paragraphs.hasMoreElements()) {
const paragraph = css.text.XTextRange.query(
paragraphs.nextElement().get());
const props = css.beans.XPropertySet.query(paragraph);
const color = new Module.uno_Any(
Module.uno_Type.Long(),
Math.floor(Math.random() * 0xFFFFFF));
props.setPropertyValue("CharColor", color);
color.delete();
}
Embind is built on the concept that whatever C++ objects you reference from JavaScript, you manually and explicitly need to declare those references as no longer needed once you are done, by calling delete()
methods on the corresponding JavaScript objects. (Or else, you risk memory leaks.) This can be quite cumbersome and would pollute the code with tons of such delete()
calls. Luckily, JavaScript grew a FinalizationRegistry
mechanism that allows code to be executed when the JavaScript garbage collector finds an objet to be unused and reclaims it. (And that code can thus transparently do the delete()
call for us.) Embind implements such FinalizationRegistry
-support for some types (those that are modelled based on some “smart poiner”) but not for others.
That means that (besides all the primitive types) JavaScript mappings of UNO string, type, enums, sequences, exceptions, and interfaces all do not need explicit delete()
calls, while the mappings of UNO any and UNO sequences, and the various Module.uno_InOutParam_...
all need explicit delete()
calls.
Even though we expect that the JavaScript engines that we target do support the FinalizationRegistry
mechanism, Embind is prepared to work with older engines that do not support it. Therefore, whenever an object is transparently cleaned up, Embind logs a somewhat unhelpful warning to the JavaScript console, stating that it “found a leaked C++ instance” (and that it will “free it automatically”).
For each UNO interface type there is a JavaScript class method query
taking any JavaScript UNO object reference (in the form of the common com.sun.star.uno.XInterface
base interface) as argument (and internally using UNO’s queryInterface
to obtain either a correspondingly-typed reference to that object, or a null reference). There is also a JavaScript helper function Module.sameUnoObject
, taking two interface references as arguments and returning whether both are references to the same UNO object.
UNO interface methods taking out or in-out parameters need special treatment. There are Module.uno_InOutParam_...
wrappers (with a val
property carrying the actual value) that need to be set up and passed into the UNO method. Such wrappers have a constructor taking no arguments (creating a dummy object, suitable for pure out parameters) and another constructor taking one argument of the wrapped type (suitable for in-out parameters). For example, to read data from a com.sun.star.io.XInputStream
:
const stream = ...;
const input = css.io.XInputStream.query(stream);
if (input) {
const data = new Module.uno_InOutParam_sequence_byte;
input.readBytes(data, 100);
for (let i = 0; i != data.val.size(); ++i) {
console.log('read byte ' + data.val.get(i));
}
data.delete();
}
Support for throwing and catching exceptions between JavaScript and C++ is rather rough: JavaScript code can use try ... catch (e) ...
to catch a UNO exception thrown from C++, but all the information it can get about that exception is e.name
stating the exception’s type. Also, for technical reasons, the catch block needs some increment
– and decrementExceptionRefcount
boilerplate,
try {
...
} catch (e) {
incrementExceptionRefcount(e);
//TODO, needed when building with JS-based -fexceptions,
// see
// <https://github.com/emscripten-core/emscripten/issues/17115>
// "[EH] Fix inconsistency of refcounting in Emscripten
// EH vs. Wasm EH"
if (e.name === 'com::sun::star::uno::RuntimeException') {
...
}
decrementExceptionRefcount(e);
}
To throw UNO exceptions from JavaScript code, there is a helper function Module.throwUnoException
that takes a UNO (exception) type and an instance of that type:
Module.throwUnoException(
Module.uno_Type.Exception(
'com.sun.star.lang.IllegalArgumentException'),
{Message: 'bad argument', Context: null,
ArgumentPosition: 0});
The JavaSript-to-UNO binding is a full mapping, so you can even implement new UNO objects in JavaScript. This requires quite some boilerplate, though. For example, the below obj
implements com.sun.star.lang.XTypeProvider
and com.sun.star.task.XJob
:
const obj = {
// Implementation details:
implRefcount: 0,
implTypes: new Module.uno_Sequence_type([
Module.uno_Type.Interface(
'com.sun.star.lang.XTypeProvider'),
Module.uno_Type.Interface(
'com.sun.star.task.XJob')]),
implImplementationId: new Module.uno_Sequence_byte([]),
// The methods of XInterface:
queryInterface(type) {
if (type == 'com.sun.star.uno.XInterface') {
return new Module.uno_Any(
type,
css.uno.XInterface.reference(
this.implXTypeProvider));
} else if (type == 'com.sun.star.lang.XTypeProvider') {
return new Module.uno_Any(
type,
css.lang.XTypeProvider.reference(
this.implXTypeProvider));
} else if (type == 'com.sun.star.task.XJob') {
return new Module.uno_Any(
type,
css.task.XJob.reference(
this.implXJob));
} else {
return new Module.uno_Any(
Module.uno_Type.Void(), undefined);
}
},
acquire() { ++this.implRefcount; },
release() {
if (--this.implRefcount === 0) {
this.implXTypeProvider.delete();
this.implXJob.delete();
this.implTypes.delete();
this.implImplementationId.delete();
}
},
// The methods of XTypeProvider:
getTypes() { return this.implTypes; },
getImplementationId() {
return this.implImplementationId;
},
// The methods of XJob:
execute(args) {
if (args.size() !== 1 || args.get(0).Name !== 'name') {
Module.throwUnoException(
Module.uno_Type.Exception(
'com.sun.star.lang.IllegalArgumentException'),
{Message: 'bad args', Context: null,
ArgumentPosition: 0});
}
console.log(
'Hello, my name is ' + args.get(0).Value.get());
return new Module.uno_Any(
Module.uno_Type.Void(), undefined);
},
};
obj.implXTypeProvider
= css.lang.XTypeProvider.implement(obj);
obj.implXJob
= css.task.XJob.implement(obj);
obj.acquire();
// ... pass obj to UNO here ...
obj.release();
I have previously discussed fixing crashes in 2 parts (segfaults, aborts). Here I discuss testing crashes to avoid creating re-creating regressions.
When you fix a crash, you have to make sure that it does not happen again in the future. The key to achieve such a goal is to write a suitable test. The test should do the exact steps to reproduce the problem on the program in order to detect the known crash before the new code is merged.
This can be done using either UITests, or CppUnitTests. UITests are written in Python. They are easier to write, but they do not run on each and every platform, and they are usually slower. CppUnitTests, on the other hand, are written in C++. They are much faster, and they run on every platform that CI runs to make sure that everything is built and can be run correctly.
Consider the below issue around footnotes:
This problem was happening when someone created a footnote, deleted the reference, and then hovered the mouse on the removed footnote reference. To reproduce that, one could use keyboard to generate a key sequence that repeats the required steps:
Write something, add footnote, select all the footnotes and remove them, then go back to the text, and hover the footnote reference.
Using keyboard-only is not always enough, but here it was possible. To implement the UITest, you should first find the appropriate place to put the test file, and then write a Python script for that. Here, the test was written in sw/qa/uitest/writer_tests2/deleteFootnotes.py
. The UITest test can be found alongside the bug fix, in the class class tdf150457(UITestCase)
:
If you look into the code, the test_delete_footnotes()
function consists of many invocations of postKeyEvent calls, that emulate key input events:
pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0);
To insert footnotes, UNO commands are used.
dispatchCommand(mxComponent, ".uno:InsertFootnote", {});
Just doing the same steps would be enough, as if the crash happens with the fix in place, or in a bad commit in the future, the test would fail. This test failure will prevent the same problem in the future.
The nice thing is that it turned out the same test could have been written using C++ and CppUnitTest, which is considered superior.
The new CppUnitTest can be found in the below change:
The new test resides in sw/qa/extras/uiwriter/uiwriter3.cxx, and essentially uses postKeyEvent and dispatchCommand as similar functions.
If you look at the current version of the test, you can see that it was simplified in later commits, but the idea is the same: “repeat the same steps that lead to crash in the code”.
It is expected that every bug fix is accompanied with a test, to avoid seeing the same problem in the future. If you want to know more about UITests and CppUnitTests, please take a look at this TDF Wiki pages:
Also, keep in mind that looking into the existing tests is the best way to understand how to write a new test. Therefore, make sure that you look into qa/ folders of the modules when you want to add a new test.
Kudos to Ilmari Lauhakangas for helping to elaborate this list.
468 bugs, 82 of which are enhancements, have been reported by 297 people.
469 bugs have been triaged by 73 people.
429 bugs have been set to RESOLVED.
Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.
143 bugs have been fixed by 35 people.
List of critical bugs fixed
List of high severity bugs fixed
List of crashes fixed
List of performance issues fixed
List of old bugs ( more than 4 years old ) fixed
Calc now supports much better copy&paste when you transfer data between Google Sheets and Calc.
This work is primarily for Collabora Online, but the feature is fully available in desktop Calc as well.
First, Collabora Online was using the
deprecated
document.execCommand()
API to paste text, which is problematic, as the "paste" button on the
toolbar can't behave the same way as pressing Ctrl-V on the keyboard.
Second, it turns out Google Sheets came up with some additional HTML attributes to represent spreadsheet data in HTML in a much better way, and Calc HTML import/export had no support for this, while this is all fixable.
In short, Collabora Online now uses the Clipboard API to read from the system clipboard -- this has to be supported by the integration, and Calc's HTML filter now support the subset of the Google Sheets markup I figured out so far. This subset is also documented.
Note that the default behavior is that the new Clipboard API is available in Chrome/Safari, but not in Firefox.
For the longer version, here are some screenshots:
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
The tracking issue on the Online side was cool#8023.
You can get a snapshot / demo of Collabora Office 24.04 and try it out yourself right now: try the unstable snapshot. Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF's next release too (24.8).
One of the areas that can help LibreOffice, but may not directly be visible to the users even though it has a big impact is the quality assurance, is automated testing. Here, I discuss some areas and notes around improving tests for LibreOffice. First, I start with regressions and bug fixes without a test.
This is the description from the GSoC ideas page:
While there are some automated tests for LibreOffice, there are not nearly enough. Adding more and better tests helps developers who work on the code to be more productive by allowing them to find regressions as early as possible.
To elaborate more, I should say there are many regressions and bugs in general that are fixed, but lack testing. It is important to have tests for those bug fixes, to avoid such problems in the future. You can see a list of those fixed issues that lack tests here:
If you want to add some new tests for the bug fixes, first you should read the bug report very carefully to understand what is it about, and try to test the fix yourself. You can either use git revert
command to revert the fix, and see the problem in action, or try changing back the fix in the code, if it is not too big.
That is important, because you have to see that the test fails without the fix in place, but succeeds when it is applied. This is an essential step when writing the test.
To know more about unit tests, you may look into these Wiki pages:
Some tests are written in the past, but now have issues because of the way they are written. In this case, porting them can provide improvement.
Tests can be written in multiple languages. At least, C++, Python, Java and BASIC are currently in use for different tests across the LibreOffice code base. Again in the GSoC ideas page, you can read:
There is some support in LibreOffice for automated tests, both at the level of unit tests, and at the level of system tests that drive a full LibreOffice instance. Currently tests can be written in C++, Java, or Python. Various new automated tests should be developed to improve the test coverage.
Tests written exclusively for Java (e.g. the JUnit framework) should be ported to C++ so that they can execute much more rapidly. Similarly, tests that do remote control of an existing LibreOffice instance, should be re-factored to run inside that instance to make debugging much easier.
Almost all JUnitTests and UITests, and also some smoke tests, run as an outside process. To verify, the trick is to remove the soffice
(.exe
) binary, or to remove its execute permission (on Linux). In this way, out-of-process tests should fail, as they need to run the soffice
binary. After a successful build, you can see if this works. For example, try this:
make -d JunitTest_framework_complex
As an example, we have this issue around complex tests that should be ported to Python:
You may find many examples of the previously ported test in the issue page. Keep in mind that usually old Java tests should be removed in the same patch that provides the CppUnitTest port.
Also, you may find examples of UITests ported to C++ from Python. For example, see this patch:
It ports a previously implemented UITest from Python to C++. The result is a faster test, which is more robust.
If you want to add or port some tests, please focus on a specific area of the code. The LibreOffice code base is huge, and consists of more than 200 modules. It is not easy, and in fact not suggested, to work across different applications and modules. It is much better that you pick a specific application, and even inside that application, like Writer, Calc, Impress, etc., focus on a specific module. In this way, it would be much easier to understand the ideas and the way tests are implemented.
One important question is around the complexity of writing or porting tests. The answer is not straightforward, as it depends on the area that the test is written. But one can take a look at what others did in the past. By looking into Gerrit or git log
, you can find what other people, including GSoC applicants, were able to achieve during their work.
After writing a few tests, or porting a few tests, it may become easier for you to write more tests. Another thing is that you don’t have to write tests from scratch. There are many tests available in the LibreOffice code base, and you can create your new test based on existing tests and customize it to match the purpose of the issue you are working on.
Kudos to Ilmari Lauhakangas for helping to elaborate this list.
477 bugs, 55 of which are enhancements, have been reported by 313 people.
458 bugs have been triaged by 79 people.
419 bugs have been set to RESOLVED.
Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.
147 bugs have been fixed by 40 people.
List of critical bugs fixed
List of high severity bugs fixed
List of crashes fixed
Writer now supports legal numbering for two more formats: DOC and RTF (ODT and DOCX were working already.)
This work is primarily for Collabora Online, done as a HackWeek project, but the feature is fully available in desktop Writer as well.
Legal numbering is a way to influence the number format of values inherited in a multi-level numbering. Say, the outer numbering uses Roman numerals and the inner numbering uses X.Y as the number format, but the inner level wants to display the outer values as Arabic numerals. If this is wanted (and guessing from the name, sometimes lawyers do want this), then the inner number portion will expand to values like "2.01" instead of "II.01", while the outer number portions will remain values like "II".
Mike did 80% of the work, what you can see here is just the RTF/DOC filters.
Picking a smaller feature task like this looked like a good idea, since I wanted to spend some of the time on regression fixing around last year's multi-page floating table project.
For (binary) DOC, the relevant detail is the fLegal
bit in the LVLF
structure. Here is the
result:
It shows how the outer "II" gets turned into "2", while it remained "II" in the past. This works for both loading and saving.
The same feature is now handled in the RTF filter as well. There the relevant detail is the
\levellegal
control word, which has an odd 1 default value (the default is usually 0). Here is the
result:
It shows that the RTF filter is up to speed with the DOC one by now.
As for the multi-page floating tables, I looked at tdf#158986 and tdf#158801.
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
You can get a snapshot / demo of Collabora Office 24.04 and try it out yourself right now: try the unstable snapshot. Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF's next release too (24.8).
If you copy contents from LibreOffice Writer to a plain text editor like gedit or Notepad, you will see that it does a straightforward thing: It copies the text and some basic formatting like converting bullets to ‘•’. For the Writer tables, the conversion is very simple right now: every cell is written in a separate line.
For example, if you have a table like this:
A | B --|-- C | D
When you copy the table from LibreOffice Writer and paste it into a plain text editor, it will become something like this, which is not always desirable.
A B C D
It is requested that like LibreOffice Calc, or Microsoft Word, and many other programs, the copy/paste mechanism should create a text like this:
A B C D
The columns are separated by <tab>.
This feature request is filed in Bugzilla as tdf#144576:
There are many steps in copy/pasting, including the data/format conversion and clipboard format handling. Here, you have to know that the document is converted to plain text via “text” filter.
The plaintext (ASCII) filter is located here in the LibreOffice core source code:
Therefore, to change the copy/paste output, you have to fix the ASCII filter. That would also provide the benefit that plain text export will be also fixed as requested here.
In this folder, there are a few files:
$ ls sw/source/filter/ascii/ ascatr.cxx parasc.cxx wrtasc.cxx wrtasc.hxx
To change the output, you have to edit this file:
In this file, there is a loop dedicated to create the output.
// Output all areas of the pam into the ASC file do { bool bTstFly = true; ... }
Inside this loop, the code iterates over the nodes inside the document structure, and extracts text from them. To check for yourself, add the one line below to the code, build LibreOffice, and then test. You will see that a *
is appended before each node.
SwTextNode* pNd = m_pCurrentPam->GetPoint()->GetNode().GetTextNode();
if( pNd )
{
+ Strm().WriteUChar('*');
...
}
For example, having this table, with 1 blank paragraph up and down:
A | B --|-- C | D
You will get this after copy/paste into a plain text editor:
* *a *b *c *d *
To fix the bug, you have to differentiate between table cells and other nodes. Then, you should take care of the table columns and print tab between them.
To go further, you can only add star before table cells:
if( pNd )
{
SwTableNode *pTableNd = pNd->FindTableNode();
+ if (pTableNd)
+ {
+ Strm().WriteUChar('*');
+ }
...
}
You can look into how other filters handled tables. For example, inside sw/source/filter/html/htmltab.cxx you will see how table is managed, first cell is tracked and appropriate functions to handle HTML table are called.
For the merged cells, the EasyHacker should first checks the behavior in other software, then design and implement the appropriate behavior.
To gain a better understanding of the Writer document model / layout, please see this document:
This presentation is also very helpful to gain a good understanding of Writer development:
Introduction to Writer Development – LibreOffice 2023 Conference Workshop, Miklos Vajna
Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.
If you accept this notice, your choice will be saved and the page will refresh.
When working with LibreOffice Impress, “Slide Master” is the place where you can change the templates used for different types of the slides used in your presentation. Here we discuss a possible improvement for the “Slide Master” by making the copy from master slides possible.
To see the problem and the room for enhancement, open LibreOffice Impress, then choose “View->Master->Slide Master” from the menus. Then, try to copy the master page on the left in the slide sorter. Unfortunately, it is not possible.
Having this feature is helpful, because different page types have many things in common, and being able to copy/paste helps creating templates much faster.
Looking into sd/source/core/drawdoc3.cxx
, you can see a huge function SdDrawDocument::InsertBookmarkAsPage
, which is relevant here. It contains ~600 lines of code. This huge function is in itself a problem. Therefore, to implement the enhancement, on should try to first refactor the function, then add a unit test in sd/qa/unit
, find and then separate all the ~6 use cases, and fix the style/name merging.
After the cleanup, the main fix should be implemented. The suggested path to implement this comes from Jean-Francois. He suggest to improve the duplicate()
method, which is described in the documentation:
As described in the above documentation, its role is to duplicate a page:
Creates a duplicate of a DrawPage or MasterPage, including the Shapes on that page and inserts it into the same model.
However, the implementation does not work for master slides, as the macros in the attachment file implies. The solution should add the needed implementation for master slides.
The implementation is inside sd/source/ui/unoidl/unomodel.cxx
inside duplicate function:
// XDrawPageDuplicator uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage ) { ... }
The above issue is filed as tdf#45617. If you like to work on it, just follow the Bugzilla link to see more information.
To implement this feature, first you have to build LibreOffice from the sources. If you have not done that yet, please refer to this guide first:
Kudos to Ilmari Lauhakangas for helping to elaborate this list.
515 bugs, 76 of which are enhancements, have been reported by 297 people.
523 bugs have been triaged by 67 people.
456 bugs have been set to RESOLVED.
Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.
181 bugs have been fixed by 39 people.
List of high severity bugs fixed
After a long slog since November when the previous version of coverity was EOLed and we had to start using 2022.6.0 with its new suggestions for std::move etc, LibreOffice is now finally back to a 0 warnings coverity state
by caolan (noreply@blogger.com) at February 11, 2024 06:02 PM
This post describes some challenges around having multiple views of one opened document in LibreOffice core, when those views belong to LOK views, representing different users, with their own language, locale and other view settings.
This work is primarily for Collabora Online, but is useful for all clients of the LOK API.
LOK views are meant to represent separate users, so we need to make sure that when a user sets their preferences and trigger an action, then the response to that action goes to the correct view, with the correct view settings.
This is different from the desktop LibreOffice use-case, where multiple windows are still meant to share the same user name, language, undo stack and so on.
In this post, I would like to present 4 small improvements that recently happened to the LOK API to provide this wanted separation of views.
The first was an issue where two users were editing the same document, one busily typing and the other clicked on a link in Calc. What could happen sometimes is the link popup appeared for the user who typed, not for the user who clicked on the link:
This specific problem can be fixed by making sure that link click callbacks are invoked synchronously (while the clicking view is still active) and not later, when the current view may or may not be the correct one.
It turns out the same problem (async command dispatch) affects not only hyperlinks, but many other cases as well, where we want to stay async, for example, when one dialog would invoke another dialog, like the Calc conditional format -> add dialog:
There you don't want to change async commands into sync commands, because that may mean spinning the main loop inside a dialog, resulting in nested main loops. This can be fixed by making sure that async commands to be dispatched (sfx2 hints in general) are processed in a way that the current view at dispatch & processing is the same, which is now the case.
The third problem was around wrong language & locale in the status bar:
This is not simply a problem of missing translation, the trouble was that the status bar update is also async and by the time the update happened, the locale of the view on the left was used, for a string that appears on the right.
The way to fix this is to perform the update of toolbars/statusbar/etc (in general: SfxBindings) in a way that the language at job schedule time and at UI string creation time is the same.
The last problem was quite similar, still about bad language on the UI, but this time on the sidebar:
This is similar to the statusbar case, but the sidebar has its own executor for its async jobs, so that needed a fix similar to what the statusbar already had, now done.
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
You can get the latest Collabora Online Development Edition 23.05 and try it out yourself right now: try the development edition. Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF's next release too (24.8).
by Popa Adrian Marius (noreply@blogger.com) at January 25, 2024 10:29 AM
LibreOffice 24.2 – with a new year.month versioning scheme – will be released as final at the beginning of February, 2024 ( Check the Release Plan ) being LibreOffice 24.2 Release Candidate 2 (RC2) the forth pre-release since the development of version 24.2 started in mid June, 2023. Since the previous release, LibreOffice 24.2 RC1, 113 commits have been submitted to the code repository and 61 issues got fixed. Check the release notes to find the new features included in this version of LibreOffice.
LibreOffice 24.2 RC2 can be downloaded for Linux, macOS and Windows, and it will replace the standard installation.
In case you find any problem in this pre-release, please report it in Bugzilla ( You just need a legit email account in order to create a new account ).
For help, you can contact the QA Team directly in the QA IRC channel or via Matrix.
LibreOffice is a volunteer-driven community project, so please help us to test – we appreciate it!
Happy testing!!
Using comments is a key feature in text processing. A typical workflow might be to review a document where notes are made by different colleagues. LibreOffice Writer currently shows these comments in the document margin, which is limited to the page height, ending up in the need to scroll long text (even while editing [1]) and eventually in paging-like interactions if the number of comments exceed the total size.…
This post is part of a series to describe how Writer now gets a feature to handle tables that are both floating and span over multiple pages.
This work is primarily for Collabora Online, but is useful on the desktop as well. See the 10th post for the previous part.
Previous posts described the hardest part of multi-page floating tables: making sure that text can wrap around them and they can split across pages. In this part, we'll look at a case where that content is not just text, but the wrapping content itself is also a table.
Regarding testing of the floating table feature in general, the core.git repository has 92 files now
which are focusing on correct handling of floating tables (filenames matching
floattable-|floating-table-
). This doesn't count cases where the document model is built using C++
code in the memory and then we assert the result of some operation.
Here are some screenshots from the improvements this month:
The first screenshot shows a situation where the mouse cursor is near the right edge of the first page of a floating table. What used to happen is we found this position close to the invisible anchor of the floating table on that page, then corrected this position to be at the real anchor on the last page. In short, the user clicked on one page and we jumped to the last page. This is now fixed, we notice that part of the floating table is close to the click position and we correct the cursor to be at the closest position inside the table's content.
The next screenshot shows a floating table where the content wrapping around the table happens to be an inline table. You can see how such wrapping didn't happen in the past, and the new rendering is close to the reference now.
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
You can get a snapshot / demo of Collabora Office 23.05 and try it out yourself right now: try the unstable snapshot. Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF's next release too (24.8).
by Popa Adrian Marius (noreply@blogger.com) at December 18, 2023 07:20 PM
This post is part of a series to describe how Writer now gets a feature to handle tables that are both floating and span over multiple pages.
This work is primarily for Collabora Online, but is useful on the desktop as well. See the 9th post for the previous part.
Previous posts described the hardest part of multi-page floating tables: reading them from documents, so we layout and render them. In this part, you can read about UI improvements when it comes to creating, updating and deleting them in Writer.
Regarding testing of the floating table feature in general, the core.git repository has 89 files now which are focusing on correct
handling of floating tables (filenames matching floattable-|floating-table-
). This doesn't count
cases where the document model is built using C++ code in the memory and then we assert the result
of some operation.
Here are some screenshots from the improvements this month:
The first screenshot shows that the underlying LibreOffice Insert Frame dialog is now async (compatible with collaborative editing) and is now exposed in the Collabora Online notebookbar.
There were other improvements as well, so in case you select a whole table and insert a new frame, the result is close to what the DOCX import creates to floating tables. This includes a default frame width that matches the table width, and also disabling frame borders, since the table can already have one.
The next screenshot shows an inserted floating table, where the context menu allows updating the properties of an already inserted floating table, and also allows to delete ("unfloat") it.
Several of these changes are shared improvements between LibreOffice and Collabora Online, so everyone benefits. For example, inserting a frame when a whole table was selected also cleared the undo stack, which is now fixed. Or unfloating table was only possible if some part of the table was clipped, but now this is always possible to do.
If you would like to know a bit more about how this works, continue reading... :-)
As usual, the high-level problem was addressed by a series of small changes:
You can get a snapshot / demo of Collabora Office 23.05 and try it out yourself right now: try the unstable snapshot. Collabora intends to continue supporting and contributing to LibreOffice, the code is merged so we expect all of this work will be available in TDF's next release too (24.2).
(And do you have a vacancy for a back-scrubber?)
Thank you, Red Hat, for generously letting me work for so long on stuff that is near and dear to my heart. At the intersection of theory and practice, of compiler technology and the LibreOffice code base. But, to keep doing what I love, I need to move on.
So, thank you, allotropia, for having me. I’m excited.
And, above all, thank you, LibreOffice, family of friends. Lets make sure to keep this a happy family, one that Tolstoy would have nothing to write home about. With quarrels and arguments, for sure; feud even. But happy at heart. I wish to keep meeting you all for years to come, virtually, and for a feast at FOSDEM or LOCon. And booze.
To paraphrase Hamburger Tafel (donations needed, btw), “Wir haben LibreOffice noch lange nicht satt.”
Have fun, stay safe, peace,
sberg
Hello LibreOffice Planet!
This is my first blog post on the topic of LibreOffice. Let me quickly explain my link to LibreOffice. I work for a data protection authority in the EU and help navigate the digital transformation of our office with about 100 staff members. While many of our partner organisations adopt Microsoft 365, our office decided to pilot Nextcloud with Collabora Office Online.
In the future, I want to blog (in my personal capacity) about my thoughts related to the use of alternative word processing software in the public sector in general and in our specific case.
As there are no dedicated resources for training, preparation of templates etc., during the pilot of LibreOffice, the experience so far covers a large spectrum of user satisfaction. Generally, our staff has been spent years of their life using Microsoft Office and has the expectation that any other software works the same way. If it does not, they send an email to me (best case) or switch back to Microsoft Office.
During the week, I discussed again some smaller LibreOffice bugs. Then, I showed this weekend some FOSS Blender animated short videos to family members. It seems that Blender is more successful in its domain than LibreOffice. Is that possible? Or are animated short videos just more capturing due to their special effects? 😅
You can watch the 1min Blender animated short movie “CREST� on Youtube or the making-off. The latter you find here below.
I find it very inspiring to see what talented artists can do with Blender. For my part, I have once installed Blender and deinstalled it. Back then it was not easy to use for people not familiar with video animation software. Blender competes with proprietary software such as Maya or Cinema 4D. The latter is about 60Â USD per month in the annual subscription plan. Not exactly cheap.
Then, I read in the fediverse about people working with LibreOffice:
I just tried to use #LibreOffice #Draw to draw some arrows and boxes onto JPEG images for emphasizing stuff.
The UX is really bad for somebody not working with Draw all the time.
Whatever I do, instead of drawing onto the image, the image gets selected instead.
Could not find any layer-sidebar.
Could not scale text without starting the “Character …� menu, modifying font size blindly + confirming > just to see its effect and then start all over.
Dear #FOSS, we really should do better.
— Author Karl Voit (12 November 2023 at 14:51)
In my past, I have worked on online voting systems. They are not very good yet despite years of efforts. xkcd dedicated a comic to voting software
Elections seem simple—aren’t they just counting? But they have a unique, challenging combination of security and privacy requirements. The stakes are high; the context is adversarial; the electorate needs to be convinced that the results are correct; and the secrecy of the ballot must be ensured. And they have practical constraints: time is of the essence, and voting systems need to be affordable and maintainable, and usable by voters, election officials, and pollworkers.
— Author Matthew Bernhard et al. in their paper Public Evidence from Secret Ballots from 2017
What is the unique challenge of developing word processing software? Happy to hear back from you in the blog comments or on the companion fediverse post!
by Robert Riemann (robert@riemann.cc) at November 12, 2023 10:20 PM
by Popa Adrian Marius (noreply@blogger.com) at November 01, 2023 02:01 PM
I attended LibreOffice Conference Asia x UbuCon Asia 2023 (LOUCA23) in Surakarta, Indonesia, on October 7~8.
This was the second time LibreOffice Conference Asia has been held in Tokyo in 2019, as it could not occur due to the COVID-19 pandemic. UbuCon Asia was first held online in 2021, and the first in-person event was held in Seoul, Korea in 2022, and this still was the second in-person event.
I was burnt out by the pandemic and had stopped most of my OSS activities, but I still had many friends in the OSS world, so I went to Indonesia to meet with them.
Therefore, I had initially intended to be a general participant. Still, a friend of the speaker was suddenly unable to attend due to illness, so I gave a presentation in his place. Here is my slide:
As mentioned, I am halfway out of OSS activities, but I know what my friends are doing, so it was not so difficult to talk about this subject.
Although I cannot say that the presentation itself was a great success (due to my English language skills), I was pleased because the audience was very responsive and easy to talk to, and many people approached me after the presentation was over.
Other than my presentation, I was naturally interested in the two keynote speeches by The Document Foundation and was surprised and grateful when Franklin Weng mentioned my name as an "Asian activist to be featured at the LibreOffice Latin America Conference. "
I listened to Muhammad Syazwan Md Khusaini's "Hands-On on Translating in Ubuntu" with great interest; however, I was a bit surprised to hear from a friend that many Indonesians use English for desktop environments and applications like LibreOffice. I recognized that this was quite different from Japan.
The event itself was just as enthusiastic. Unlike OSS events in Japan (laugh), the participants were young, and there were many women. I was also surprised to see junior high school students among the speakers.
Both lunch and dinner were complimentary, and the one-day Surakaruta city tour the day after the event was delightful. I appreciated the hospitality of the local staff.
This was my first time in Indonesia, and although short, I enjoyed many things, including the train trip. In Yogyakarta, I visited a museum and learned a lot about the history of Indonesia. However, I was overcharged by the tuk-tuk in Yogya.
I know it was a lot of work for the organizers, but as I have many friends in LibreOffice and am also an Ubuntu user, I was very grateful that the two events were co-hosted. Thanks to all the sponsors, global/local organizers, and everyone who talked to me there. See you soon!
by Naruhiko Ogasawara (noreply@blogger.com) at October 27, 2023 01:13 PM
by Popa Adrian Marius (noreply@blogger.com) at October 11, 2023 02:47 PM
by Popa Adrian Marius (noreply@blogger.com) at October 11, 2023 02:46 PM
LibreOffice is a complex application with a large and growing number of options. It is not easy to find the right needle in the haystack. Like most other complex applications, it will be valuable and useful enhancement to add a search field to the “Tools > Options” dialog that iterates over the various tabs and filters where the search text is found. The Search Field in Options project aims to provide this search functionality in “Tools > Options” page.
GetAllStrings()
method to fetch strings from 69 dialogs step by stepsalhelper::Thread
- asynchronously)_
) and Tilde (~
) symbols from fetched strings to make the search function work correctlyDuring 13 weeks GSoC program, I added a search field in Options dialog and included the node names and their .ui strings into searching. Since sub-dialogs under the Options are not initialized at startup of Options dialog, it was not possible to access their .ui strings. To overcome this issue we had two options:
When I felt that Option A is just wasting my time (~5 weeks); I switched to Option B where I can -at least- make some progress. The main issue in Option B was initializing all dialogs which takes about 4-8 secs. I tried to initialize them at background but there was some errors on Win10 that I don’t reproduce the issue on my linux machine. Then I tried to see the errors on Win10 with a virtual machine, but it was too slow to test. Therefore I uninstalled Manjaro/Linux (which I’ve been using it more than 1.5 years) from my computer and had to install Win10 (which I last used 6 years ago) on my machine to see the problems in there. There was some visual inconsistencies while initializing sub-dialogs using salhelper::Thread
at background.
After working long hours for weeks meanwhile the time was running out, I decided to initialize almost half of them at Options dialog startup and the remaining ones at the time of searching. In that way, time of initializing process is divided by ~2 which can be acceptable time in some degree in terms of user experience.
There is a single patch on Gerrit for this project: https://gerrit.libreoffice.org/c/core/+/152519. The patch has more than 30 patchsets and includes “+2255 -47” changes.
The most challenging part was implementing GetAllStrings() function for every ~69 dialogs step by step. Current implementation may not be the best solution for user experience, but at least searching through the numerous options is now possible.
Following tasks are left and can be implemented after GSoC:
salhelper::Thread
- asynchronously)I’m very happy that we all reached the end of GSoC. During that time, I know that I had a responsibility for doing everything that I can. Therefore I worked hard and tried to complete as much tasks as I can.
I learned a lot of things during the GSoC. Although GSoC is finished, I will definitely continue to contribute to LibreOffice. I am really happy to be a part of the LibreOffice community and Google Summer of Code. I’m really thankful to LibreOffice and Google for providing us this such a great opportunity which helped me gain this amazing experience!
I always tried to be active on IRC #libreoffice-dev channel, and I want to thank for everybody who helped me about my questions.
And most importantly, greatly thankful to Andreas Heinisch and Heiko Tietze who were my mentors throughout the GSoC period. They always guided me everything about my questions. Thank you endlessly for your time and effort. I appreciate that you always motivating and encouraging me in all that I attempt and do. I can never truly express how grateful I am. Your guidance, reviews, help and shared experiences have been invaluable. Thank you very much for everything.
I’d like to express my gratitude to everyone in the LibreOffice community for their help and kindness. They always tried to answer my questions on IRC. I fell very lucky to work with this amazing community. I have learned a lot from you and I will never forget this wonderful experience.
Regards,
Bayram Çiçek
All weekly GSoC reports:
Useful links:
Writer supports Small Caps, but Impress and drawing shapes in general never fully supported Small Caps. The option was available, and the character dialog provided a preview, but Small Caps was rendered the same as All Caps, as seen here.
This has lingered for years and it's not easy as a user to try and manually workaround with varying font sizes because underline/overline/strike-through decorations won't link up, as seen in this example:
to:
Also noticed during all of this was the wrong width scaling used for the red wave line underneath incorrect spelling in impress when the text is superscript or subscript so the line didn't stretch over the whole text, as seen here:
Now corrected as:
and finally added was a missing implementation in the RTF export of shape text to allow the small caps format to be copy and pasted into other applications from impress.
When I wrote Quo vadis with The Document Foundation? a month ago, that was mostly a side product of sorting out my thoughts on open source governance in general, and on LibreOffice in particular. And while that sparked some discussion on the identity of the LibreOffice project, mostly here on Board Discuss, it ultimately was preparation for a talk Thorsten and me had submitted for a vacation on Chaos Communication Camp 2023. Our preparation was somewhat chaotic -- because both Thorsten and me decided to get very creative about the "dont come by car" suggestion by the organizers and our talk being scheduled on the first day of the event -- so we ended up honouring the LibreOffice tradition of finishing slides only hours before the scheduled slot.
The session itself did not seem to have suffered too much by this -- it was more free form, which might actually have been a bonus. We ended up even being allowed to use some extra time for Q&A as there was quite some interest for that in the audience.
The video recording can be found on media.ccc.de and describes both bits of the history of the LibreOffice fork a decade ago and lessons learned that are still relevant for open source communities forking (or otherwise reorganizing themselves) today.
A huge thank you to all the volunteers that made #CCCamp23 (and therefore this talk) happen, especially c3voc for the recording and c3cert who did a great job in checking a minor injury I suffered due to my own stupidity during the event.
Comments? Feedback? Additions? Most welcome here on the fediverse !