The Document Foundation Planet

 

January 17, 2025

Michael Meeks

2025-01-17 Friday

  • Up early, sync with Dave, Anuj, lunch with Julia, worked away at contractuals. Onto mail catch-up, and slides.

January 17, 2025 04:48 PM

LibreOffice QA Blog

LibreOffice 25.2 RC2 is available for testing

LibreOffice 25.2 will be released as final at the beginning of February, 2025 ( Check the Release Plan ) being LibreOffice 25.2 Release Candidate 2 (RC2) the forth and last pre-release since the development of version 25.2 started in mid Juny, 2024. Since the previous release, LibreOffice 25.2 RC1, 104 commits have been submitted to the code repository and 55 issues got fixed. Check the release notes to find the new features included in this version of LibreOffice.

LibreOffice 25.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!!

Download it now!

by x1sc0 at January 17, 2025 12:52 PM

January 16, 2025

Michael Meeks

2025-01-16 Thursday

  • Up too early; train - with Christian, sky-train, some data analysis on the plane, heathrow-express.
  • Home, read minutes of calls I missed: seems I should miss more calls; text review, dinner with the family. Worked after dinner, missed bible-stidy group, bed early.

January 16, 2025 09:00 PM

LibreOffice Dev Blog

Outlook for the new year 2025

Happy new year 2025! I wish a great year for you, and the global LibreOffice community. Now that we are now in 2025, I briefly discuss the year 2024 and outlook for 2024 in the development blog.

LibreOffice Conference 2024, Luxembourg

LibreOffice Conference 2024, Luxembourg

At The Document Foundation (TDF), our aim is to improve LibreOffice, the leading free/open source office suite that has millions of users around the world. Our work is community-driven, and the software needs your contribution to become better, and work in a way that you like.

My goal here, is to help people understand LibreOffice code easier, and eventually participate in LibreOffice core development to make LibreOffice better for everyone. In 2024, I wrote 22 posts around LibreOffice development in the dev blog (4 of them are unpublished drafts).

Outlook For the New Year

Focus of the development blog for 2025 in this blog will be:

  • Introducing new EasyHacks
  • Describing user interface creation with VCL
  • Explaining LibreOffice architecture
  • Explaining Python interaction with LibreOffice

I have written about some of these topics in 2024. Therefore, this year I will try to expand the previous writings and provide new articles about them. For example, creating user interfaces using VCL with the help of glade interface designer will be one of important things to discuss.

You can give feedback by writing a comment here, or sending me an email to hossein AT libreoffice DOT org.

We provide mentoring support to those who want to start LibreOffice development. You are welcome to contact me if you need help to build LibreOffice and do some EasyHacks via the above email address. Also, you can always refer to our Getting Involved Wiki page:

Let’s hope a great year for LibreOffice (and the world) in 2025.

by Hossein Nourikhah at January 16, 2025 02:29 PM

Official TDF Blog

localwriter: A LibreOffice Writer extension for local generative AI

LibreOffice is a privacy-oriented office suite that runs on your own computer and doesn’t include AI features out-of-the-box. But we know that many users are interested in combining AI tools with the suite, so we talked to John Balis who is working on a (fully optional!) LibreOffice extension called localwriter. Here’s what he had to say…

What does the extension do?

Localwriter is a libreoffice writer extension to allow for inline generative editing with local inference. It can be used with any language model supported by Ollama or text-generation-webui. This extension adds two powerful commands to LibreOffice Writer:

  • Extend Selection – Uses a language model to predict what comes after the selected text. There are a lot of ways to use this. Some example use cases for this include, writing a story or an email given a particular prompt, adding additional possible items to a grocery list, or summarizing the selected text.
  • Edit Selection – A dialog box appears to prompt the user for instructions about how to edit the selected text, then the selected text is replaced by the edited text. Some examples for use cases for this include changing the tone of an email, translating text to a different language, and semantically editing a scene in a story.

When did you start working on it?

I started working on localwriter in July 2024, because I wanted an AI tool to assist with my writing that would benefit from the intrinsic advantages in terms of availability (can’t lose access), confidentiality (doesn’t leak data), and integrity (no surprise model version changes) that come with using a fully open source local AI stack instead of a third-party API. I feel it is really important to embrace learning to benefit from artificial intelligence without sacrificing agency, and this software follows from that line of thinking.

What are the current limitations, and what’s coming next?

localwriter currently only supports LibreOffice Writer, although Calc support is in development and will be offered in the next release. Another limitation is that it does not support streaming, and does not offer a “Chat with document” feature.

How can others help to improve it?

There are a ton of open feature requests in the repository from several users, which should be really easy for an experienced LibreOffice extension developer to complete. I can easily set up anyone interested with a task to work on. Tests would be welcome, as currently it doesn’t have any tests. Also, donating to me helps me allocate my own time towards development.

Get the extension here

by Mike Saunders at January 16, 2025 11:02 AM

January 15, 2025

Michael Meeks

2025-01-15 Wednesday

  • More meetings & planning - tour of the very well equipped maker-space - and a party to celebrate the awesome work that ZenDiS has been doing in the year since its founding.
  • Had a TDF Advisory Board call in the middle: encouraged by the level of competence of the advice.

January 15, 2025 09:00 PM

Official TDF Blog

Czech translation of LibreOffice Getting Started Guide 24.8

Czech LibreOffice Getting Started Guide cover

Zdeněk Crhonek (aka “raal�) from the Czech LibreOffice community writes:

The Czech team has finished its translation of the LibreOffice Getting Started guide 24.8. As usual it was a team effort, with translations by Petr Kuběj, Zdeněk Crhonek and Radomír Strnad; localized pictures from Roman Toman; and technical support from Miloš Šrámek. Thanks to all the team for their work!

The Czech translation of the Getting Started Guide 24.8 is available for download here.

The team will continue working on a translation of the Math Guide 24.8. We always looking for new translators and correctors. Join us!

Stanislav Horá�ek cleaned up the bookshelf page and he added an online version of the Math Guide. More online versions are ti come.

Great work everyone! 😊

by Mike Saunders at January 15, 2025 01:53 PM

January 14, 2025

Michael Meeks

2025-01-14 Tuesday

  • Up early, tram to a meeting - all-day meeting plus dinner with partners & ZenDiS, up late.

January 14, 2025 09:00 PM

January 13, 2025

Michael Meeks

2025-01-13 Monday

  • Up unpleasantly early: train, train, tube, train, plane, sky-train, train, train - experience to get to Bochum via Dusseldorf for meetings - left my luggage on one of the trains at some point - annoying.
  • Met up with Lily, Frank & out for dinner slowly gathering more partners.

January 13, 2025 09:00 PM

Marius Popa Adrian

A sad day for the Firebird Project

Helen Borrie, a key figure in the Firebird relational database project and a longtime contributor at IBPhoenix, passed away on January 2, 2025. Her contributions were essential to Firebird’s creation and its development over the past 25 years.Read the rest of the official announcement

by Popa Adrian Marius (noreply@blogger.com) at January 13, 2025 01:15 PM

Jaybird 6.0.0 released

We're happy to announce the first release of Jaybird 6, Jaybird 6.0.0.

by Popa Adrian Marius (noreply@blogger.com) at January 13, 2025 01:06 PM

Official TDF Blog

Announcing the LibreOffice Calc Guide 24.8

Dione Maddern and The Documentation Team are proud to announce the immediate availability of the LibreOffice Calc Guide 24.8, an update of the existing Calc Guide 24.2 with enhancements taken from the current LibreOffice 24.8 Calc module.

Calc Guide 24.8

The book was reviewed for clarity, readability and content additions, notably the Calc database table referencing in formulas, removal of deprecated JavaScript debugger and refactoring of the Calc’s chart topic – in which the chapter on charts was split in two, one for the chart basics and the second for the chart types. Dione Maddern, Calc editor says:

I took on the challenge of compiling the Calc Guide because I wanted to learn about advanced editing and working with master documents. While I’ve previously worked on large documents in the engineering and insurance industries, documents were often compiled with clunky cut-and-paste techniques which created a lot of errors and labor-intensive rework. Working on the Calc Guide 24.8 was a great opportunity to expand my skills in LibreOffice and document production generally. It was also a wonderful opportunity to work with the LibreOffice Documentation Team. I had a great time working with such a fun and supportive team.

Special thanks to Ed Olson, Lisa Samy and Claire Wood for their review of the contents of the guide. And to B. Antonio F. for his throughout review of formatting the guide and by writing a set of macros, bundled in an LibreOffice extension that allows automatic and assisted fixing of images, tables , styles and more.


Dione Maddern

It was also a wonderful opportunity to work with the LibreOffice Documentation Team. I had a great time working with such a fun and supportive team. (Dione Maddern)


Ed Olson

It has been an honor to share my wordsmithing skills with the LibreOffice documentation team. Replacing verbose paragraphs in the Calc guides with simplified, minimalist text has been both challenging and rewarding. I look forward to continuing my work on other applications in the suite as new releases become available. (Ed Olson)


Lisa Samy

Joining the Calc Guide team marked my first time contributing to an open-source platform. My time working with other team members was both enriching, yet eye-opening to all the facets of document editing. As such, I thoroughly enjoyed my experience with the LibreOffice Community as a whole. (Lisa Samy)


B. Antonio F.

I accepted the challenge of creating mechanisms to harmonize he appearance of chapter text according to the chapter template established by the documentation team. It was an opportunity to delve deeper into macro programming and get to know the LibreOffice API better. SanityCheck macros allow you to correct formatting errors (based on styles), correctly adjust images, tables, and automatically apply descriptions for accessibility. With SanityCheck you can check documentation chapters in English, Spanish and Portuguese. (B. Antonio F.)


Claire Wood

I enjoyed working on the Calc Guide as it gave me the opportunity to work with a truly global team. The content also challenged my knowledge about spreadsheets. I was happy to develop my knowledge, getting new information and develop my strengths in LibreOffice. (Claire Wood)


You can download the LibreOffice Calc Guide 24.8 from the LibreOffice Bookshelf and the LibreOffice Documentation website.

by Olivier Hallot at January 13, 2025 12:58 PM

LibreOffice Design Blog

Results from a survey about Writer templates

By Ndidi Folasade Ogboi

LibreOffice Writer has long been a trusted tool for users worldwide, offering an open-source solution for documents. But what happens when we take a step back and look at the user experience? How do templates fit into the workflows of users, what makes a great template and where do users want LibreOffice writer to improve?…

by Heiko Tietze at January 13, 2025 10:06 AM

January 09, 2025

LibreOffice QA Blog

QA/Dev Report: December 2024

General Activities

  1. LibreOffice 24.8.4 was announced on December 19
  2. Olivier Hallot (TDF) improved the warning in Help when JavaScript is not active and did many cleanups in help pages
  3. Dione Maddern created a help page for Alignment Sidebar deck
  4. Alain Romedenne improved and updated help for ScriptForge libraries
  5. Bogdan Buzea improved some UI labels, improved help for superordinate object settings and cached spreadsheet formulas and did many code cleanups
  6. Tomaž Vajngerl (Collabora) continued working on PDF 2.0 and PDF/A-4 support
  7. Miklós Vajna, Rashesh Padia, Attila Szűcs, Bayram Çiçek, Szymon Kłos, Marco Cecchetti, Pranam Lashkari, Hubert Figuière (Collabora) worked on LOKit used by Collabora Online
  8. Xisco Faulí (TDF) worked on crash report analysis tools, upgraded many dependencies and did many code stability improvements
  9. Michael Stahl (allotropia) made style name handling more robust, improved the handling of hidden frames after recent changes and improved the correctness of HTML import regarding formatting
  10. Mike Kaganski (Collabora) added an application-wide Viewer mode where all files are opened in read-only state while all editing tools are disabled, dropped all code specific to Windows 7, 8 and 8.1 while also making use of new possibilities such as handling long Windows paths with wildcards, made the Unix document mailer script future-proof in case the attach parameter is disallowed in mailto URLs, fixed an issue with calculating minimum heights for menus, fixed an issue with the number format being reported incorrectly in Writer tables, fixed an issue with multi-selection in Calc showing an incorrect cell format and preventing change of format, fixed inability to edit doubles in Basic IDE’s Watch window and fixed an issue preventing the use of points for custom image height/width in the PNG export dialog
  11. Caolán McNamara (Collabora) improved dark mode support, fixed crashes and fixed many issues found by static analysers and fuzzers and did code cleanups
  12. Stephan Bergmann (allotropia) fixed an issue with emailing multiline messages on Unix and worked on the MAR updater and WASM build. He also adapted the code to compiler changes and did code cleanups
  13. Noel Grandin (Collabora) improved saving time of XLSX files with lots of conditional formatting, improved the speed of processing styles when opening DOCX files and worked alongside Michael Stahl in making style name handling more robust. He also did many code cleanups and optimisations
  14. Justin Luth (Collabora) fixed a DOCX compatibilityMode import and export issue, fixed an issue with imported area fill images not being saved with their associated documents, fixed a Calc comment copying crash and fixed an issue with tables of contents in DOCX files misbehaving when the printer list has been disabled
  15. Michael Weghorn (TDF) did a big reorganisation in accessibility-related code to make it easier to work with, continued working with Cambalache developer (UI editing app) and did various accessibility fixes. He also worked on using native widgets in Qt UIs
  16. Balázs Varga (allotropia) improved and expanded Writer’s accessibility warnings, fixed saving “Fit height to text” property of drawing objects to PPTX, fixed laying out of text in SmartArt objects found in PPTX files and implemented support for soft edge and glow effects in text frame objects in PPTX files
  17. Patrick Luby made resizing windows on macOS appear smoother, implemented jumping the view to the proportional location in the document when Option-clicking the scrollbar on macOS (instead of just advancing a single screen/page), implemented support for native macOS full screen mode, fixed an issue causing a long delay in opening the Print dialog on macOS when objects with transparency were present and fixed macOS printing issues related to page settings in Calc and brochures
  18. Jim Raykowski did a big rework of macro organiser dialogs, reducing them from five to one
  19. Oliver Specht (CIB) improved support for VML textboxes in DOCX files and fixed an issue with paragraph spacing of bullets in Impress
  20. Heiko Tietze (TDF) added visual feedback into the status bar for when AutoCalculate is active in Calc
  21. László Németh continued polishing support for inline headings in Writer documents
  22. Ilmari Lauhakangas (TDF) did code cleanups after the decision to remove support for Windows 7, 8 and 8.1 from version 25.8
  23. Christian Lohmaier (TDF) improved the Windows build setup
  24. Eike Rathke (Red Hat) improved date input detection in Calc and helped finish ODF 1.4 support for EASTERSUNDAY function
  25. Jonathan Clark (TDF) improved the detection of Asian scripts in text runs adjacent to weak punctuation characters or explicit direction marks
  26. Sahil Gautam (allotropia) continued polishing the Libreoffice Theme GSoC project
  27. Andreas Heinisch implemented support for pasting HTML strikethrough formatting, made it so the choice of “Link” when inserting an image is remembered during a session and fixed an issue with dashed lines sometimes becoming solid in imported graphics
  28. Chris Sherlock did code cleanups in VCL
  29. Vasily Melenchuk (CIB) fixed an issue with unwanted background fill in placeholders in PPTX files
  30. Laurent Balland replaced a binary DocBook template with an ODF one
  31. Xuan Chen fixed shading issues in custom shapes in PPT files
  32. Armin Le Grand (Collabora) worked on a renovation of graphics rendering on Linux with Cairo library
  33. Björn Michaelsen did refactoring in Writer code
  34. Ariel Darshan implemented support for autorepeating slides in windowed mode in Impress
  35. Samuel Adesola made it possible to access Writer’s view layout options via the View menu
  36. Marc Mondesir fixed touchpad scrolling for Slides and Pages panes in Impress and Draw
  37. Andrei Alin fixed a ReadLine API function not always stripping line-ending characters
  38. André Herbst fixed an issue with canceling a cell dragging operation leaving behind a visual glitch
  39. David Gilbert implemented support for clipping stroke paths in imported PDFs
  40. Tibor Nagy (allotropia) fixed an issue with overflowing text in Impress presenter notes getting cut off from printing, fixed presenter notes not being relayouted when changing paper size in the print dialog and similarly for changing orientation for handouts
  41. Mohit Marathe continued polishing the new Comments Sidebar deck
  42. Jean-Pierre Ledure worked on the ScriptForge library

Kudos to Ilmari Lauhakangas for helping to elaborate this list.

Reported Bugs

400 bugs, 60 of which are enhancements, have been reported by 249 people.

Top 10 Reporters

  1. Eyal Rozenberg ( 13 )
  2. Justin L ( 12 )
  3. Gabor Kelemen (allotropia) ( 9 )
  4. Alex Kemp ( 9 )
  5. Roman Kuznetsov ( 8 )
  6. gplhust955 ( 7 )
  7. Robert Großkopf ( 7 )
  8. Anna ( 7 )
  9. Óvári ( 7 )
  10. Mike Kaganski ( 6 )

Triaged Bugs

365 bugs have been triaged by 69 people.

Top 10 Triagers

  1. Buovjaga ( 77 )
  2. BogdanB ( 62 )
  3. m_a_riosv ( 31 )
  4. V Stuart Foote ( 20 )
  5. Mike Kaganski ( 15 )
  6. zcrhonek ( 14 )
  7. Dieter ( 13 )
  8. raal ( 11 )
  9. Heiko Tietze ( 10 )
  10. Michael Weghorn (away) ( 8 )

Resolution of resolved bugs

371 bugs have been set to RESOLVED.

Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.

Fixed Bugs

138 bugs have been fixed by 31 people.

Top 10 Fixers

  1. Balazs Varga ( 13 )
  2. Mike Kaganski ( 10 )
  3. Bogdan Buzea ( 9 )
  4. Caolán McNamara ( 6 )
  5. Patrick Luby ( 6 )
  6. Michael Weghorn ( 6 )
  7. Jonathan Clark ( 6 )
  8. Andreas Heinisch ( 4 )
  9. Justin Luth ( 4 )
  10. Heiko Tietze ( 3 )

List of high severity bugs fixed

  1. tdf#155211 Regression: dashed lines become solid when breaking imported SVG / exporting to SVG ( Thanks to Andreas Heinisch )
  2. tdf#163033 Crash when attempting to save a COPY of a sheet-with-comments from a now-closed spreadsheet ( Thanks to Justin Luth )
  3. tdf#164093 Crash when clicking on the Sidebar Tab menu button for SB deck selector pop-up menu with AT active on Windows ( Thanks to Michael Weghorn )
  4. tdf#164417 Autofiltered XLSX with dates cannot be opened in MSO ( Thanks to Balazs Varga )

List of crashes fixed

  1. tdf#163033 Crash when attempting to save a COPY of a sheet-with-comments from a now-closed spreadsheet ( Thanks to Justin Luth )
  2. tdf#163221 Hovering the mouse over a Basic dialog will make it grow or crash (Dialog Editor) ( Thanks to Noel Grandin )
  3. tdf#163948 Crash upon startup after enabling Notes Pane ( Thanks to Sarper Akdemir )
  4. tdf#164075 crashtesting: assert on import of rtf exported from LibreOffice ( Thanks to Justin Luth )
  5. tdf#164093 Crash when clicking on the Sidebar Tab menu button for SB deck selector pop-up menu with AT active on Windows ( Thanks to Michael Weghorn )
  6. tdf#164098 Typing tatweel character leads to a crash ( Thanks to Jonathan Clark )
  7. tdf#164299 Pasting from Calc to Impress in HTML format crashes LO ( Thanks to Oliver Specht )
  8. tdf#164359 Crash on double-click of level 2 word in Impress ( Thanks to Miklos Vajna )

List of old bugs ( more than 4 years old ) fixed

  1. tdf#113015 “Online updates” checks the updates of extensions installed too ( Thanks to Bogdan Buzea )
  2. tdf#124954 HELP for recalculating of formulas on opening of a spreadsheet needs updating ( Thanks to Bogdan Buzea )
  3. tdf#127937 Provide feedback of AutoCalculation at the status bar ( Thanks to Heiko Tietze )
  4. tdf#128957 UI Can’t set custom image height/width in PNG Options Window in points ( Thanks to Mike Kaganski )
  5. tdf#131332 HELP: replace custom date formats with ISO 8601 to stop promoting ambiguous formats ( Thanks to Bogdan Buzea )
  6. tdf#132111 Initial cell’s number format in Writer table is reported wrong ( Thanks to Mike Kaganski )
  7. tdf#135320 FILEOPEN PPTX: effect similar to soft edges (“inward soft edges”) not shown ( Thanks to Balazs Varga )
  8. tdf#135628 SendSimpleMailMessage bodytext with new lines ends up as multiple recipients ( Thanks to Stephan Bergmann )
  9. tdf#138615 Insure Windows wildcards work properly with long paths ( Thanks to Mike Kaganski )
  10. tdf#42989 FORMATTING: Selecting Multiple Cells with Different Formats Show as Same Format and Can’t Be Changed as a Group ( Thanks to Mike Kaganski )
  11. tdf#61358 UI: Remember state of option “Insert image from file -> Linked” ( Thanks to Andreas Heinisch )
  12. tdf#62845 Option for “Document Viewer Mode” (read-only mode by default) required. ( Thanks to Mike Kaganski )
  13. tdf#66791 FORMATTING: Incorrect application of “Asian text font” for quotation marks when the paragraph contains a mixture of western and asian characters ( Thanks to Jonathan Clark )
  14. tdf#79298 FORMATTING: Copy/paste: importing of strikethrough attribute doesn’t work ( Thanks to Andreas Heinisch )
  15. tdf#85428 Imported PDF displays extra-long lines for shaded area ( Thanks to Dr. David Alan Gilbert )
  16. tdf#88226 Excessive text in Presentation Notes is not printed ( Thanks to Tibor Nagy )

WORKSFORME bugs

44 bugs have been retested by 20 people.

Top 10 testers

  1. Buovjaga ( 9 )
  2. BogdanB ( 8 )
  3. V Stuart Foote ( 4 )
  4. m_a_riosv ( 4 )
  5. Robert Großkopf ( 3 )
  6. Telesto ( 2 )
  7. John ( 2 )
  8. Xisco Faulí ( 1 )
  9. Regina Henschel ( 1 )
  10. Alan ( 1 )

DUPLICATED bugs

63 bugs have been duplicated by 20 people.

Top 10 testers

  1. Mike Kaganski ( 11 )
  2. Buovjaga ( 11 )
  3. BogdanB ( 8 )
  4. V Stuart Foote ( 7 )
  5. m_a_riosv ( 7 )
  6. Timur ( 4 )
  7. Gabor Kelemen (allotropia) ( 2 )
  8. Eyal Rozenberg ( 2 )
  9. zcrhonek ( 2 )
  10. Roman Kuznetsov ( 1 )

Verified bug fixes

28 bugs have been verified by 14 people.

Top 10 Verifiers

  1. Buovjaga ( 7 )
  2. BogdanB ( 5 )
  3. Stéphane Guillou (stragu) ( 4 )
  4. Lars Jødal ( 2 )
  5. raal ( 1 )
  6. Gerald Pfeifer ( 1 )
  7. Eyal Rozenberg ( 1 )
  8. Mihai Vasiliu ( 1 )
  9. steve ( 1 )
  10. lol ( 1 )

Categorized Bugs

1175 bugs have been categorized with a metabug by 27 people.

Top 10 Categorizers

  1. BogdanB ( 1024 )
  2. Roman Kuznetsov ( 36 )
  3. Eyal Rozenberg ( 25 )
  4. V Stuart Foote ( 21 )
  5. Dieter ( 10 )
  6. Buovjaga ( 8 )
  7. Aron Budea ( 7 )
  8. Timur ( 6 )
  9. Stéphane Guillou (stragu) ( 6 )
  10. Telesto ( 5 )

Regression Bugs

58 bugs have been set as regressions by 16

by x1sc0 at January 09, 2025 01:08 PM

January 08, 2025

Miklos Vajna

Ignoring the paragraph margin at the top of pages in Writer

Writer has the concept of paragraph margins and page margins, but what happens when you combine the two? It turns out the expectation is that sometimes the top paragraph margin is ignored in this case. We'll see two cases where the behavior of Writer is now improved to better match Word in this regard.

This work is primarily for Collabora Online, but the feature is available in desktop Writer as well.

Motivation

As described in a previous bugreport, there was a first problem where Word ignored the top paragraph margin of a document, but Writer did not. A recent bugreport then pointed out that the first implementation went too far and now a wanted top margin was ignored. This lead to a set of conditions which now does a decent emulation of Word's rules in this regard.

Results so far

Here is the old Writer render result for a document where the top margin should be ignored:

Bugdoc: old Writer render

And here is the new Writer render result for a document where the top margin is ignored:

Bugdoc: new Writer render

Finally, the reference render result, showing the ignored top paragraph margin:

Bugdoc: reference render

As you can see, now the unwanted top paragraph margin is omitted at page top.

How is this implemented?

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:

Want to start using this?

You can get a development edition of Collabora Online 24.04 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 (25.2).

by Miklos Vajna at January 08, 2025 08:53 AM

January 07, 2025

Official TDF Blog

Hazard: A LibreOffice Impress template to play Jeopardy-like games

Hazard LibreOffice template screenshot

Marcial Machado recently posted on Reddit about his “fully-featured LibreOffice Impress template for creating Jeopardy-style games. Just add your questions and categories, and you’re good to go!” So let’s find out more…

What does the template do?

At its core, the template is meant to emulate what a game of Jeopardy is like. You can click on any of the squares on the game board and it will send you to the slide with the associated question, where you can either return to the board in the case of a misclick, or reveal the answer to the question. Returning to the board from the revealed answer slide will erase the square you clicked on to clearly show which questions are left to be answered.

You can also use the green and red arrows at the top to give and remove points to up to 6 teams in increments of 100, in order to keep track of everyone’s correctly- and incorrectly-guessed answers. Once the board’s cleared, you can click the pink button at the bottom right to clearly display the top three teams and the points they earned. I made sure to include details on how to edit, and use, the template in the first two slides!

Why did you develop it?

The simple reason for why I developed this template was because: I use LibreOffice, I wanted a Jeopardy presentation that worked in LibreOffice, and I couldn’t find one. The more verbose reason is that there is a comparative dearth of visually-appealing presentation templates in the OPT world than there is in the PPTX world; this is no fault of the creators of OPT templates, but rather because the proprietary nature of something like PowerPoint incentivizes templates made for profit, whereas most people who create LibreOffice Impress templates do it out of interest.

This necessarily means that there are just less people making LibreOffice Impress templates in total, without mentioning the much smaller userbase LibreOffice has compared with Microsoft Office. Now, some PowerPoint files do work in Impress, and the work done by the dev team and contributors is commendable, but a converted document is still a converted document. Formatting might be slightly off, and macros are almost always a bust. Since I realized I wanted this Jeopardy project to exist, and realizing my own frustration with the fact that such a project didn’t exist already, I went ahead and tried it out myself, and then released it to the public!

Hazard LibreOffice template screenshot

Do you have any tips for other people interested in creating templates in LibreOffice?

I have a few:

  • Focus on a problem you, yourself, have. You’ll be much more eager to bring a project to completion and to a high level of quality if you have a vetted interest in the final product.
  • Tell yourself that no one, ever, is going to make what you want to be made. The problem with a community of like-minded contributors is that everyone thinks everyone else is likely to fix the problem they have, so there’s a huge diffusion of responsibility; think of walking past some trash on the sidewalk and thinking, “someone else will pick that up eventually.” No! You be the one who throws it in the trash! In the same way, once you realize there’s an issue you can fix, or you can learn how to fix, be the one to fix it – no one else is gonna fix it for you!
  • Be patient. Like, really patient. Because no one is gonna fix this problem for you, you have all the time in the world to get it right. Read some documentation, go to some forums, sit on it a few days. Maybe get some feedback. Depend on time and on others to both find motivation and create a better end-product. The Jeopardy template I ended up releasing was the third completed project I made!

Get the template from here

by Mike Saunders at January 07, 2025 02:23 PM

January 03, 2025

LibreOffice QA Blog

LibreOffice 25.2 RC1 is available for testing

LibreOffice 25.2 will be released as final at the beginning of February, 2025 ( Check the Release Plan ) being LibreOffice 25.2 Release Candidate 1 (RC1) the third pre-release since the development of version 25.2 started in mid Juny, 2024. Since the previous release, LibreOffice 25.2 Beta1, 175 commits have been submitted to the code repository and 76 issues got fixed. Check the release notes to find the new features included in this version of LibreOffice.

LibreOffice 25.2 RC1 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!!

Download it now!

by x1sc0 at January 03, 2025 01:07 PM

December 31, 2024

December 20, 2024

LibreOffice Design Blog

LibreOffice Themes will replace the color customization

Since the first implementation of a dark color theme we continuously improved the customization of LibreOffice. In a GSoC projects this year, Sahil Gautam made it possible to not only change the application colors but also what is defined by the operating system respectively the desktop environment.…

by Heiko Tietze at December 20, 2024 12:55 PM

December 18, 2024

LibreOffice QA Blog

QA/Dev Report: November 2024

General Activities

  1. LibreOffice 24.8.3 was announced on November 14
  2. Olivier Hallot (TDF) did big updates to screenshots in Help, added a help page for login/password dialog and improved help pages on Skia, Writer Navigator and Edit – External links in Draw and Impress. He also added extended tips for Style dialog and Skia options
  3. Pierre F. continued reorganising help pages for Calc functions
  4. Dione Maddern added help pages for Number Format and Design Sidebar decks
  5. Alain Romedenne improved help for BASIC’s Mid method and updated help for ScriptForge’s Exception.PythonShell() method
  6. Bogdan Buzea fixed over 50 issues pointed out by PVS-Studio static analyser, did other code cleanups and worked on harmonising the use of date formats in Help to ISO 8601
  7. Tomaž Vajngerl (Collabora) started working on PDF 2.0 and PDF/A-4 support
  8. Jaume Pujantell (Collabora) fixed an issue with fill content of graphic objects being lost upon PPTX export
  9. Bayram Çiçek, Szymon Kłos, Skyler Grey, Vivek Javiya, Marco Cecchetti, Pranam Lashkari, Hubert Figuière and Miklós Vajna (Collabora) worked on LOKit used by Collabora Online. Vivek also added a command to remove content control formatting
  10. Julien Nabet did some internal improvements to database code and fixed several issues pointed out by static analysers
  11. Xisco Faulí (TDF) fixed 80 issues pointed out by PVS-Studio static analyser, upgraded many dependencies, added a script to check the latest version of external libraries, expanded ODF 1.4 support with help from Regina and did many restructurings in automated tests as well as code cleanups
  12. Michael Stahl (allotropia) made document compression handling more robust, fixed an issue in the WMF export code causing incomplete redactions and did many improvements to hiding elements in Writer
  13. Mike Kaganski (Collabora) fixed a hang related to Windows clipboard, made copying of rich text take font encoding into account, fixed an issue with setting page backgrounds via Java API, made footnote/endnote navigation more robust, made it so nested footnotes in ODF files are ignored instead of causing a read error (support has to be added to ODF spec), made hyphenation code more robust, fixed an issue with certain documents opening as modified and fixed an issue with incorrect OLE object scaling during loading
  14. Caolán McNamara (Collabora) fixed an issue with tabs getting skipped when cycling with Ctrl+PgDn/PgUp in Calc’s Format Cells dialog, fixed crashes and fixed many issues found by static analysers and fuzzers and did code cleanups
  15. Stephan Bergmann (allotropia) worked on WASM build. He also adapted the code to compiler changes and did code cleanups
  16. Noel Grandin (Collabora) fixed an issue with Calc’s background colour conditional formatting sometimes missing newly added entries, made it faster to open XLSX files with lots of conditional formatting and made inspection of BASIC macros in the macro editor safer by detecting and skipping the display of very large UNO property values. He also did many code cleanups and optimisations
  17. Justin Luth (Collabora) fixed an issue with forms not being editable immediately after opening, fixed Sidebar display of background fill not being updated after changing page style in Writer, fixed right-clicking not activating rename or delete for the targeted background image in the Area tab of dialogs, fixed an issue with not being able to add or delete gradients and bitmaps for background fills, made Calc’s row height optimisation faster, fixed an Excel compatibility issue related to row heights and fixed None area colour in a page style not being retained upon DOC export
  18. Michael Weghorn (TDF) made the blinking indication animation of selected text objects respect operating system animation settings (to avoid causing trouble for hypersensitive users), fixed an issue causing unnecessary accessibility notifications related to Quick Find bar, worked with Cambalache developer to polish this UI editing app that aims to be a replacement for Glade and fixed a crash related to Orca screenreader. He also worked on using native widgets in Qt UIs
  19. Balázs Varga (allotropia) made Calc’s lookup functions more robust, added a “Summary below data” option for Calc’s Subtotals, added an option to sheet protection to keep Pivot Tables and Pivot Charts working and made the accessibility error reporting more finegrained and categorised better
  20. Patrick Luby made macOS dictation work smoothly, fixed an issue with Calc cells getting cleared when switching windows with certain types of keyboards on macOS, made it so modifier keys are ignored for trackpad swipe events on macOS to prevent unwanted actions and improved the overall smoothness of macOS UI
  21. Jim Raykowski made macro assignment smoother by pre-selecting the desired macro in the Customize dialog when arriving from the macro organiser dialog, made it possible to change footnotes to endnotes and vice versa via context menu entries in the Writer Navigator, improved the page change control in Writer Navigator, fixed unwanted opening of Sidebar in Math with Alt+2/3/4 shortcuts and added an expert option DisableLayerHighlighting for more finegrained control over when object highlighting is done while the mouse is hovered over the layer bar
  22. Oliver Specht (CIB) improved the correctness of cell padding import from RTF files, fixed SVG clipboard format support, made it so formatting is preserved when copying and pasting hyperlinks from Writer to Impress, made it so manually added bullets or numbering are reverted, if a paragraph style is applied, fixed an issue with incorrect spacing attributes in table cells in imported RTF files and enabled additonal functions in editable sections while in read-only mode
  23. Heiko Tietze (TDF) made view options for element boundaries more intuitive, improved the layout of File Properties dialog, made it possible to save user-defined Math formulas and added a command to center objects to slide/page in Impress/Draw
  24. László Németh worked on support for inline headings in Writer documents and fixed an issue with incorrect ordering of Table of Contents in PDF files when headings reside in text frames
  25. Ilmari Lauhakangas (TDF) fixed an issue with misleading tooltips for internal links in shapes, fixed a background colour issue in Math’s edit area and updated help for Status Bar and Image Compression dialog
  26. Christian Lohmaier (TDF) improved the Windows build setup
  27. Eike Rathke (Red Hat) added language and locale support for French (Republic of Guinea)
  28. Jonathan Clark (TDF) implemented support for font-relative units in indentation and margins, made it so exported SVGs have a direction attribute, so RTL text works as expected and took care of loose ends in the break iterator rework
  29. Sahil Gautam continued merging patches from the Libreoffice Theme GSoC project and continued polishing the Duplicate Records feature in Calc, including its Help
  30. Rafael Lima made it so the new Quick Find Sidebar deck is aware of dark mode
  31. Andreas Heinisch made Hyperlink dialog smarter in how it automatically grabs links from the clipboard, made it so navigating with arrow keys in Calc no longer disables highlighting of referenced cells and fixed a crash when editing Table of Contents with preview activated
  32. Bartosz Kosiorek implemented support for the units centimeter, percentage, hectare and are in libvisio
  33. Chris Sherlock did code cleanups in VCL
  34. Hossein Nourikhah (TDF) added a minimal vcl weld example application and fixed issues in Notebookbar definition files
  35. Vasily Melenchuk (CIB) made it so any task progress in LO status bar is also represented as progress in Windows taskbar
  36. Andras Timar (Collabora) made the XML in exported DOCX files satisfy the expectations of some third party applications
  37. Pierre Vacher made it so UNO API’s SortableGridDataModel service can be notified of changes
  38. Laurent Balland fixed bundled templates not being valid ODF due to compressed mimetype file (this issue was not in any release)
  39. Áron Budea (Collabora) fixed some issues reported by PVS-Studio static analyser
  40. Gülşah Köse (Collabora) fixed incorrectly detected hidden AutoFilter buttons in XLSX files and fixed XLSX import of AutoFilter ascending sort conditions
  41. Kurt Nordback fixed an issue with disappearing elements in Bubble charts and expanded the features of bar/pie of pie chart types
  42. Regina Henschel worked on better ODF 1.4 conformance
  43. Xuan Chen improved the build options benefiting CPU architectures such as riscv64
  44. Melvin George added a unit test for exporting footnotes to PDF
  45. Barry-Thomas-Paul: Moss improved the code for handling Python extensions

Kudos to Ilmari Lauhakangas for helping to elaborate this list.

Reported Bugs

399 bugs, 65 of which are enhancements, have been reported by 264 people.

Top 10 Reporters

  1. Eyal Rozenberg ( 28 )
  2. Gabor Kelemen (allotropia) ( 18 )
  3. Mike Kaganski ( 11 )
  4. nobu ( 11 )
  5. Regina Henschel ( 8 )
  6. Dragan Marinović ( 6 )
  7. Gerald Pfeifer ( 5 )
  8. peter josvai ( 5 )
  9. László Németh ( 4 )
  10. Xisco Faulí ( 4 )

Triaged Bugs

416 bugs have been triaged by 72 people.

Top 10 Triagers

  1. Buovjaga ( 90 )
  2. m_a_riosv ( 37 )
  3. Heiko Tietze ( 36 )
  4. Mike Kaganski ( 20 )
  5. raal ( 20 )
  6. V Stuart Foote ( 17 )
  7. Stéphane Guillou (stragu) ( 12 )
  8. Nicole A. ( 10 )
  9. Julien Nabet ( 10 )
  10. Michael Weghorn ( 9 )

Resolution of resolved bugs

380 bugs have been set to RESOLVED.

Check the following sections for more information about bugs resolved as FIXED, WORKSFORME and DUPLICATE.

Fixed Bugs

118 bugs have been fixed by 30 people.

Top 10 Fixers

  1. Mike Kaganski ( 12 )
  2. Justin Luth ( 9 )
  3. Noel Grandin ( 5 )
  4. Heiko Tietze ( 5 )
  5. Balazs Varga ( 5 )
  6. Jonathan Clark ( 5 )
  7. László Németh ( 5 )
  8. Andreas Heinisch ( 4 )
  9. Michael Weghorn ( 4 )
  10. Caolán McNamara ( 4 )

List of critical bugs fixed

  1. tdf#163325 Crashes on Editing TOC when Preview is on ( Thanks to Andreas Heinisch )

List of high severity bugs fixed

  1. tdf#162992 FILESAVE : Cell filtering (list) not saved in XLSX format ( Thanks to Gülşah Köse )
  2. tdf#163667 Saving a particular spreadsheet takes a very long time ( Thanks to Noel Grandin )
  3. tdf#163842 XLS, XLSX Certain roundtripped spreadsheets not opening in Excel due to regression ( Thanks to Gülşah Köse )
  4. tdf#85976 [RFE] Add a “remove duplicate records” command ( Thanks to Sahil Gautam )

List of crashes fixed

  1. tdf#155449 Launching Orca after Writer sometimes crashes Writer (stack trace provided) gtk3 a11y atkwrapper.cxx ( Thanks to Michael Weghorn )
  2. tdf#163325 Crashes on Editing TOC when Preview is on ( Thanks to Andreas Heinisch )

List of old bugs ( more than 4 years old ) fixed

  1. tdf#103916 UI An added / modified gradient (dialog Page Background) is not available in other documents ( Thanks to Justin Luth )
  2. tdf#108189 inspection of object hangs LO – memory leak ( Thanks to Noel Grandin )
  3. tdf#122716 IMPORT Writer can lose encoding for some multibyte symbols when copy-paste from XLSX/Calc ( Thanks to Mike Kaganski )
  4. tdf#124741 Empty row height changes when exported to XLSX (width fixed) ( Thanks to Justin Luth )
  5. tdf#126857 One/some logic possibilities missing from context menu for alignment of images ( Thanks to Heiko Tietze )
  6. tdf#131862 ODF: Remove deprecated attribute table:cell-range-address from element ( Thanks to Regina Henschel )
  7. tdf#136003 PROTECT SHEET: Can’t delete rows, despite of allow to deletes ( Thanks to Sahil Gautam )
  8. tdf#36709 For first line indent using Ch (Characters) as unit, the indent value should change when font-size changes ( Thanks to Jonathan Clark )
  9. tdf#81913 Navigating with arrow keys disables cell highlighting (in text and in spreadsheet) ( Thanks to Andreas Heinisch )
  10. tdf#85976 [RFE] Add a “remove duplicate records” command ( Thanks to Sahil Gautam )
  11. tdf#86731 Spellcheck does not flag missing dictionary ( Thanks to Szymon Kłos )
  12. tdf#89352 Allow user to change all Footnotes to Endnotes, and vice-versa ( Thanks to Jim Raykowski )
  13. tdf#91315 Parentheses inverted in mixed RTL and LTR text in SVG export ( Thanks to Jonathan Clark )
  14. tdf#94147 Some Selected Objects Flash/Blink ( Thanks to Michael Weghorn )
  15. tdf#95239 Wrong ToC in Navigator and PDF when using frames ( Thanks to László Németh )
  16. tdf#95852 Can’t edit forms immediately after opening. WORKAROUND: Navigate to next page by clicking on left page list OR right-click ( Thanks to Justin Luth )

WORKSFORME bugs

44 bugs have been retested by …

by x1sc0 at December 18, 2024 02:45 PM

December 12, 2024

LibreOffice QA Blog

LibreOffice 25.2 Beta1 is available for testing

LibreOffice 25.2 will be released as final at the beginning of February, 2025 ( Check the Release Plan ) being LibreOffice 25.2 Beta1 the second pre-release since the development of version 25.2 started in mid Juny, 2024. Since the previous release, LibreOffice 25.2 Alpha1, 450 commits have been submitted to the code repository and 105 issues got fixed. Check the release notes to find the new features included in this version of LibreOffice.

LibreOffice 25.2 Beta1 can be downloaded for Linux, macOS and Windows, and it can be installed alongside the standard version.

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!!

Download it now!

by x1sc0 at December 12, 2024 04:00 PM

December 04, 2024

Miklos Vajna

Editeng RTF export: fixing a lost paragraph style

Impress shape text doesn't have much support for styles, e.g. the default UI in Writer gives you a paragraph style dropdown, and you don't get the same in Impress. Still, a paragraph style is attached to bullets based on their outline level, and Impress has a View → Outline menu item to give you that styled text you can copy. Pasting that to Writer started to lose styles recently and it's now fixed to work again.

This work is primarily for Collabora Online, but the feature is available in desktop Impress as well.

Motivation

As described in a previous commit, I had a case where lots of not needed paragraph styles were exported to RTF in case an Impress document had enough master pages. The idea was to only export actually used paragraph styles, to avoid wasting CPU power.

Turns out filtering out paragraph styles has to happen at two locations:

  • in the style table to assign an index to a paragraph style
  • when referring to those styles

The problem was that unused styles were removed from the style table, but not from the style → index mapping, so as soon as you had both used and unused paragraph styles, the declared and the referred style indexes didn't match anymore.

Results so far

Here is a sample paste result in Writer, where you can see that the text doesn't have a custom paragraph style:

Bugdoc: old Writer paste

And here is the same paste, now with paragraph styles restored:

Bugdoc: new Writer paste

As you can see, now the pasted text has paragraph styles.

How is this implemented?

If you would like to know a bit more about how this works, continue reading... :-)

The bugfix commit was editeng RTF export: fix broken offsets into the para style table.

The tracking bug was tdf#163883.

Want to start using this?

You can get a development edition of Collabora Online 24.04 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 (25.2).

by Miklos Vajna at December 04, 2024 10:34 AM

November 29, 2024

Chris Sherlock

The mess that is the VCL

 Let me count the ways, in no particular order and in no way exhaustive:

  • OutputDevice is the base class for printing, windowing and PDFs. It doesn't just do output. 
  • OutputDevice has GetOutDevType() because the base class needs to know what child class is using it. Ugh. 
  • OutputDevice drawing primitives not only draw, but they record a metafile. There are literally functions that turn off drawing and just let it record the metafile. I made an attempt at seperating the concerns, but it got nowhere. 
  • VCL relies on DrawingLayer and DrawingLayer relies on the VCL. 
  • There is a concept of a VirtualDevice, which is derived from OutputDevice. VirtualDevice does a bunch of things, but one of which is alpha-handling. In OutputDevice, there is a member which is a VirtualDevice. Each drawing function in Outputdevice calls upon the correlated drawing function in this member VirtualDevice.
  • Bitmaps don't get modified via the Bitmap class. Instead, you have to use BitmapInfoAccess, BitmapReadAccess and BitmapWriteAccess. I'm still puzzling out why these are seperate classes. 
  • Bitmaps are transformed in SalGraphics indirectly via OutputDevice. Except when they aren't, in which case it fails, whereby OutputDevice tries an alternative way via SalGraphics. Otherwise, it tries its own poor man approach at drawing the bitmap. Consequently, often times you bypass the platform optimized ways of doing things, because its not been implemented.
  • Fonts are lazy loaded from OutputDevice. There is no central font manager. To get the fonts, you have to go through SalGraphics. To get a SalGraphics, you need to initialize a lot of stuff not related to fonts. 
  • Font caching is done from OutputDevice. Lazily. Font data is updated for all frames. Frames are a concept needed for Windows. Frames are not a concept needed by Printers and VirtualDevices, or even PDFs. Note that Printers, VirtualDevices and PDFs all inherit from OutputDevice. 
  • OutputDevice converts between "logical" units and display units. It's a nightmare to know what each function needs what sort of units. For the mapping between units, I refer you to vcl/source/gdi/mapmod.cxx and vcl/source/outdev/map.cxx
  • There is tools and basegfx. They do the same thing, though basegfx is considerably better written. You have Size and B2DSize, Point and B2DPoint, Polygon and B2DPolygon, PolyPolygon and B2DPolyPolygon. OutputDevice must handle it all. 
  • Gradient handling is sort of half baked in OutputDevice, much of gradient handling is done in other modules. 
  • Font substitution is truly, truly weird. PhysicalFontSelect::FindFontFamilyByAttributes() has clearly got a bug in it - (e.g. ImplFontAttrs::None == ((nSearchType ^ nMatchType) & ImplFontAttrs::Rounded an XOR?) and it is a truly strange weighting scheme. Yes, I did try to untangle that beast with proper unit tests, but gave up after being told I was being unreasonable. 
  • There is VCL, canvas, cppcanvas and drawinglayer. drawinglayer is way better than VCL, but we are stuck with VCL for everything. 
  • Consider the following Window hierarchy: WorkWindow inherits from SystemWindow, which inherits from Window. Window holds an OutputDevice to do stuff. WindowOutputDevice derives from OutputDevice. This is needed because OutputDevice often needs to know if it is doing Window operations, via WindowOutputDevice. Try untangling this in your head.
  • Text layout is its own beast, and has its own set of classes. A lot of text layout is worked out in OutputDevice. 
  • Text layout is done via OutputDevice::ImplLayout(). I present to you the ImplLayout function signature:

        std::unique_ptr<SalLayout> ImplLayout(
            const OUString&, sal_Int32 nIndex, sal_Int32 nLen, const Point& rLogicPos = Point(0, 0),
            tools::Long nLogicWidth = 0, KernArraySpan aKernArray = KernArraySpan(),
            std::span<const sal_Bool> pKashidaArray = {}, SalLayoutFlags flags = SalLayoutFlags::NONE,
            vcl::text::TextLayoutCache const* = nullptr, const SalLayoutGlyphs* pGlyphs = nullptr,
            std::optional<sal_Int32> nDrawOriginCluster = std::nullopt,
            std::optional<sal_Int32> nDrawMinCharPos = std::nullopt,
            std::optional<sal_Int32> nDrawEndCharPos = std::nullopt) const; 
     

by Chris Sherlock (noreply@blogger.com) at November 29, 2024 10:58 PM

November 26, 2024

allotropia

Precision-engineering for JavaScript

This post is about recent improvements for ZetaJS, the JavaScript wrapper library for ZetaOffice’s WebAssembly version of LibreOffice:

There is something of a mismatch between the UNO type system and the JavaScript types used by zetajs. For example, JavaScript only has a single number type for both integer and floating point values, while UNO has a whole slew of different numeric types (BYTE, SHORT, UNSIGNED SHORT, LONG, UNSIGNED LONG, FLOAT, DOUBLE) that all map to that one JavaScript type. Similarly, the different UNO sequence<T> types all map to JavaScript arrays, where information about the UNO element type T is lost.

Normally, that’s not an issue. When you call a UNO method that returns a LONG, you get a number just like when you call a UNO method that returns a DOUBLE, and your JavaScript code then has a number to work with, and that’s all. Similarly, when you call a UNO method that returns a sequence<LONG>, you get an array of numbers you can work with, just like when you call a UNO method that returns a sequence<DOUBLE>. And when you then call a UNO method that takes a seaquence<LONG> as an argument, you pass in an array of numbers, and the zetajs runtimes figures out how to dress that array up as a UNO sequence<LONG>, and all is well.

However, one place where UNO’s insistance on more precise typing gets in the way is the UNO ANY type. It is not just a means to transport any kind of UNO value, it also carries precise type information. A UNO ANY value that contains a LONG of value 1 is something different than a UNO ANY vlaue that contains an UNSIGNED LONG of value 1. And a UNO ANY value that contains a reference of type css.uno.XInterface to some UNO object is something different than a UNO ANY value that contains a reference of type css.lang.XComponent to the same UNO object.

Again, most of the time, those precise distinctions are irrelevant to most of the code. When you call a UNO method that returns an ANY, and you know that that ANY value must contain a LONG, you just want to get a JavaScript number out, regardless of what precise numeric UNO type was encoded in that ANY value. Similarly, when you call a UNO method that returns an ANY that must contain a css.uno.XInterface reference, you just want to get some JavaScript object that you can do further UNO method calls on (or null), regardless of what precise UNO interface type was encoded in that ANY value. And when you then call a UNO method that takes an ANY that must contain a LONG, you want to just pass in a JavaScript number, and the zetajs runtime shall figure out how to dress that up as a UNO ANY containing a LONG (or throw an exception, if you passed something that just can’t be dressed up accordingly).

But, sometimes, you need more fine-grained control. There might be a UNO method that takes an ANY argument and behaves completely differently when you pass it a LONG of value 1 or an UNSIGNED LONG of value 1. But when you call that UNO method with the JavaScript number 1, zetajs will always dress that up as a UNO ANY of type LONG for you, never as an UNSIGNED LONG. To solve that issue, the zetajs UNO binding also has the notion of a zetajs.Any JavaScript type, which records a value along with its precise UNO type. You can thus pass either a new zetajs.Any(zetajs.type.long, 1) or a new zetajs.Any(zetajs.type.unsigned_long, 1) when you call that picky UNO method.

Now, when a UNO method returns an ANY value, the zetajs binding used to be conservative: You might want to know exactly what UNO type it contains (even though, most of the time you don’t actually care), so it always returned those wrapped zetajs.Any objects that carry the precise contained UNO type. But that lead to awkward code. When you call e.g. x.nextElement() to get a UNO ANY that contains a reference to another UNO object, you had to unwrap that first (with zetajs.fromAny) before you could do any further calls on the obtained UNO object: zetajs.fromAny(x.nextElement()).doSomething(). But you know that this call to x.nextElement() will return an ANY containing an interface reference, and you don’t care about the exact UNO interface type—you just want to do another method call on the obtained object.

So, recently (in Let zetajs return unwrapped ANY representations), the zetajs binding was changed so that it now always returns unwrapped UNO ANY values: x.nextElement() no longer returns a zetajs.Any wrapper (on which you would need to call zetajs.fromAny first), it directly returns the relevant JavaScript object. And the resulting overall code looks way better: x.nextElement().doSomething().

When, in the other direction, you pass something into a UNO method that takes an ANY argument, you still have the same options you had before: Either, you simply pass the JavaScript number 1, and zetajs figures out for you that that should be dressed up as a UNO ANY of type LONG, or you want to be picky and pass in either a new zetajs.Any(zetajs.type.long, 1) or a new zetajs.Any(zetajs.type.unsigned_long, 1).

And when it comes time that you do want to be picky about the ANY values that you obtain as return values from UNO method calls, there’s now a $precise way to do that: x.$precise.nextElement() (and same for any other UNO method call) will always give you back a wrapped zetajs.Any value. See the updated The zetajs UNO Mapping for all the details.

by allotropiasoft at November 26, 2024 09:00 AM

November 22, 2024

LibreOffice Dev Blog

VCL weld: create LibreOffice GUI from design files

LibreOffice uses VCL (Visual Class Library) as its internal widget toolkit to create the graphical user interface (GUI) of LibreOffice. Here I discuss how to use UI files designed with Glade interface designer to create LibreOffice user interfaces with a framework called weld, which is part of LibreOffice core source code.

Creating a Minimal VCL Weld Application

In my previous blog post, you can find out about the structure of a minimal VCL application. Please refer to the below blog post to see how a Window is created in VCL, and how it can be used as a test workbench called minvcl. You can run it with ./bin/run minvcl after you build LibreOffice.

VCL application in its minimal form

Here I discuss how to go further, and create user interface with Glade interface designer, and do most of the things without writing code.

VCL Weld Mechanism

In order to simplify user interface creation in LibreOffice, experienced LibreOffice developer, Caolán, has introduced a mechanism to load UI files created with Glade interface designer, and use them as if they are UI files for each and every GUI framework that LibreOffice supports: from GTK itself to Qt, Windows, macOS and even the so-called gen backend that only requires the X11 library on Linux.

To illustrate how the VCL weld mechanism works, I have added a minimal example, minweld, as a test workbench. The structure of the code is very similar to the previous example, minvcl, but there are some changes in the code. In the new code, UI is created from a .ui file that is designed visually with Glade interface designer. The .ui file is an XML file which contains placement of widgets that should be displayed on the screen.

The complete code for minweld is available in the LibreOffice core source code repository, which can also be viewed online:

Glade UI File

In minweld, I have used an existing Glade UI file, tipofthedaydialog.ui. This is the user interface for displaying a tip of the day in LibreOffice at startup. Heiko, the TDF design mentor, has discussed this dialog box in detail before:

Easyhacking: How to create a new “Tip-Of-The-Day” dialog

But, you can assume that it is a simple .ui file, that one can create with Glade. Here, we use it to create our own user interface in C++. You may use any other .ui file that you have created with almost the same code.

Tip of the day displayed at LibreOffice startup

Tip of the day displayed at LibreOffice startup

This UI file is found in cui/uiconfig/ui/tipofthedaydialog.ui, and minweld loads it. This is how it looks when you open it in Glade interface designer:

tipofthedaydialog.ui in Glade user interface designer

tipofthedaydialog.ui in Glade user interface designer

Let’s look into the specifics of minweld.cxx.

Header Includes

Headers are almost the same, but here we use vcl/weld.hxx instead of vcl/wrkwin.hxx. Therefore, you can see this line in the code:

#include <vcl/weld.hxx>

Then we have the C++ code for the application. The TipOfTheDayDialog class is defined with:

class TipOfTheDayDialog : public weld::GenericDialogController
{
public:
    TipOfTheDayDialog(weld::Window* pParent = nullptr);
    DECL_LINK(OnNextClick, weld::Button&, void);

private:
    std::unique_ptr<weld::Label> m_pTextLabel;
    std::unique_ptr<weld::Button> m_pNextButton;
    sal_Int32 m_nCounter = 0;
};
...
}

As you can see, TipOfTheDayDialog inherits from weld::GenericDialogController, and not Application class as before. Also, TipOfTheDayDialog constructor receives a parent of type weld::Window*, which is nullptr now. The reason is that there is no parent window in this example. Using weld:: prefix is also done for other types of widgets that we use in LibreOffice. For example, we use weld::Button to denote a push button in LibreOffice, or in any application that is created with the vcl::weld mechanism.

Class Constructor

This is the code for the TipOfTheDayDialog constructor. Here, we initialize two member variables, m_pTextLabel and m_pNextButton which point to a label and a button, respectively. We will interact with these two in our code. There are string literals like lbText and btnNext , which are the IDs of those widgets in Glade. The IDs should be unique for linking to specific variables in the code.

TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent)
: weld::GenericDialogController(pParent, u"cui/ui/tipofthedaydialog.ui"_ustr,
u"TipOfTheDayDialog"_ustr)
, m_pTextLabel(m_xBuilder->weld_label(u"lbText"_ustr))
, m_pNextButton(m_xBuilder->weld_button(u"btnNext"_ustr))
{
    m_pNextButton->connect_clicked(LINK(this, TipOfTheDayDialog, OnNextClick));
}

One last step is linking the events with functions in the code. You may do that with the LINK macro. In the last line, connect_clicked activates OnNextClick from the class TipOfTheDayDialog, whenever m_pNextButton is clicked.

Event Handler

This is the implementation of the event handler. It should be started with IMPL_LINK macro, in the form of IMPL_LINK_NOARG(Class, Member, ArgType, RetType). The code is straightforward: It increases a counter which is initially zero, and displays it alongside a text:

IMPL_LINK_NOARG(TipOfTheDayDialog, OnNextClick, weld::Button&, void)
{
    ++m_nCounter;
    m_pTextLabel->set_label(u"Here you will see tip of the day #"_ustr
+ OUString::number(m_nCounter) + ".");
}

With a call to set_label function, m_pTextLabel is updated every time that you click on “Next Tip” button.

Running the Example

You may run the example after you have built LibreOffice from sources. Then, you may simply invoke:

./bin/run minweld

The result is a little bit different from the tipoftheday dialog in LibreOffice, as it does not use a picture. But, it has a nice feature: if you click on “Next Tip”, it will show a text and a counter that goes up whenever you click on it again.

Final Notes

You may look into the original “tip of the day” dialog box in cui/source/dialogs/tipofthedaydlg.cxx, which is more complex than the one that we created here, as it reads some data from the configuration and uses images. But, the idea is the same. Inherit a class from GenericDialogController, define and link variables to the widgets with their IDs, add event handlers. Now, the application with VCL graphical user interface is ready to use!

This is somehow similar to the way one creates dialog boxes with Qt and other widget toolkits. On the other hand, the VCL weld mechanism is different in the way that it uses such a toolkit to create UI on the fly. Therefore, if you choose a desired VCL UI plugin, then it will use that specific library for creating user interface. For example, you can run minweld example with Qt this way:

export SAL_USE_VCLPLUGIN=qt5

./bin/run minweld
The minweld example in Qt (light theme)

The minweld example in Qt (light theme)

You may also run it with GTK3 UI, this way:

export SAL_USE_VCLPLUGIN=gtk3

export GTK_THEME=Adwaita:light # For light/dark theme

./bin/run minweld
The minweld example in GTK3 (light theme)

The minweld example in GTK3 (light theme)

I hope that this explanation was helpful for you to understand the basics of GUI design and implementation in LibreOffice. You can try doing small improvements in LibreOffice GUI by looking into the EasyHacks that with the tag “Design“:

TDF Wiki: EasyHacks categorized by “Design” as the required skill

We welcome your code submissions to improve LibreOffice. If you would like to start contributing to LibreOffice, please take a look at our video tutorial:

Getting Started (Video Tutorial)

by Hossein Nourikhah at November 22, 2024 05:07 PM

November 21, 2024

Marius Popa Adrian

Read free book "Detailed New Featuires Of Firebird 5": available as HTML and as PDF

Dive deep into the revolutionary features of Firebird 5.0 with this comprehensive guide written by database expert Denis Simonov and edited by Alexey Kovyazin.This book offers an in-depth exploration of the significant advancements that make Firebird 5.0 a pivotal release in the world of relational databases.Whether you're a seasoned database administrator, a curious developer, or an IT

by Popa Adrian Marius (noreply@blogger.com) at November 21, 2024 09:05 AM

November 14, 2024

LibreOffice Dev Blog

Notebookbar part 1: custom widgets for the tabbed interface

Notebookbar, or tabbed interface is an attempt to modernize LibreOffice user interface. In these series, I try to explain the implementation in LibreOffice code. In the first part, I discuss custom Glade widgets that are building blocks of Notebookbar user interface.

Building LibreOffice From Sources

If you haven’t built LibreOffice from sources before, you can refer to can refer to this tutorial:

Getting Started (Video Tutorial)

The next sections assume that you have a working build environment.

Custom Widgets in Glade Catalogs

Notebookbar implementation consists of .ui files, configuration files and C++ implementation. Let’s look into the user interface files.

First time that you clone LibreOffice source code, and try to open a Notebookbar UI file like this, you may see error:

$ glade ./sc/uiconfig/scalc/ui/notebookbar.ui

You may see an error, which indicates that a required catalog related to LibreOffice is not available.

Glade error

Glade error

To fix this issue, you have to know that Notebookbar uses custom widgets that with the Glade interface designer. These custom widgets are available from a Glade catalog with the name of LibreOffice.

Inside sc/uiconfig/scalc/ui/notebookbar.ui, you may see these two lines:

<requires lib="gtk+" version="3.20"/>
<requires lib="LibreOffice" version="1.0"/>

Glade catalogs are xml files with the keyword glade-catalog inside them, so we can search for this keyword:

$ git grep -l glade-catalog
extras/source/glade/libreoffice-catalog.xml.in
extras/source/glade/makewidgetgroup.xslt

The .in files is an input file in which the build process creates the final xml file out of it. Searching for glade-catalog inside the build folder results:

$ grep -lr glade-catalog
...
instdir/share/glade/libreoffice-catalog.xml

As you can see, the result goes inside the folder instdir/share/glade/, so to be able to use the catalog, you should add this folder to the glade catalog search path. One of the easiest ways to do this, is to add it via Glade interface itself. Use ☰ (hamburger menu), go to “Glade Preferences”, and add instdir/share/glade/ to the “Extra Catalog & Template paths”. Then, reload a notebookbar UI file, and the error should go away. This setting is saved inside ~/.config/glade.conf configuration file.

Custom Widgets for the Notebookbar

Inside the Glade custom catalog instdir/share/glade/libreoffice-catalog.xml, you can see 10 custom widgets:

$ grep "glade-widget-class\ " instdir/share/glade/libreoffice-catalog.xml
<glade-widget-class title="Notebookbar ToolBox" name="sfxlo-NotebookbarToolBox" generic-name="Notebookbar ToolBox" parent="GtkToolbar" icon-name="widget-gtk-toolbar">
<glade-widget-class title="Notebook switching tabs depending on context" name="sfxlo-NotebookbarTabControl" generic-name="NotebookbarTabControl" parent="GtkNotebook" icon-name="widget-gtk-notebook"/>
<glade-widget-class title="Horizontal box hiding children depending on its priorities" name="sfxlo-PriorityHBox" generic-name="PriorityHBox" parent="GtkBox" icon-name="widget-gtk-box"/>
<glade-widget-class title="Horizontal box hiding children depending on its priorities" name="sfxlo-PriorityMergedHBox" generic-name="PriorityMergedHBox" parent="GtkBox" icon-name="widget-gtk-box"/>
<glade-widget-class title="Box which can move own content to the popup" name="sfxlo-DropdownBox" generic-name="DropdownBox" parent="GtkBox" icon-name="widget-gtk-box"/>
<glade-widget-class title="Box which can hide own content" name="VclOptionalBox" generic-name="VclOptionalBox" parent="GtkBox" icon-name="widget-gtk-box"/>
<glade-widget-class title="Vertical box hiding children depending on context" name="sfxlo-ContextVBox" generic-name="ContextVBox" parent="GtkBox" icon-name="widget-gtk-box"/>
<glade-widget-class title="Managed Menu Button" name="svtlo-ManagedMenuButton" generic-name="ManagedMenuButton" parent="GtkButton" icon-name="widget-gtk-button"/>
<glade-widget-class title="NotebookBar Toolbar Addons" name="NotebookBarAddonsToolMergePoint" generic-name="ShowText" parent="GtkToolButton" icon-name="widget-gtk-toolbutton"/>
<glade-widget-class title="NotebookBar MenuItem Addons" name="NotebookBarAddonsMenuMergePoint" generic-name="ShowText" parent="GtkMenuItem" icon-name="widget-gtk-menuitem"/>

The previous xml shows the custom widgets that are building blocks of building Notebookbar. Let’s look into each of them, based on their title and names.

Notebookbar widgets

In the next picture, you can see the notebookbar in LibreOffice, and compare it to what is visible in Glade user interface designer. As you can see, not everything is visible in the designer. Specifically, icons and text are not visible in the designer but are visible in the final application.

 

LibreOffice with Notebookbar

Notebookbar in LibreOffice

Main Widget

1. Notebookbar Tab Control: This widget has the name sfxlo-NotebookbarTabControl, and is the primary widget for Notebookbar. It can change the set of visible tabs based on the user context. Its parent class is GtkNotebook and provides context-sensitive tab switching.

Container Widgets

2. NotebookbarToolBox: This widget is named sfxlo-NotebookbarToolBox,  its parent class is GtkToolbar. It can contain toolbar elements.

NotebookbarTabControl

NotebookbarTabControl

3. Priority Horizontal Box: This widget has the name sfxlo-PriorityHBox, and its parent class is GtkBox. It is the horizontal box hiding children depending on its priorities. In this way, lower priority widgets becomes hidden to give the more important widgets room to be displayed on a screen that is not big enough to show all the available elements.

4. Priority Merged Horizontal Box: This widget has the name sfxlo-PriorityMergedHBox, and its parent class is GtkBox. It is the “horizontal box hiding children depending on its priorities”. This widget is also related to the previous one for creating more room for important widgets, but it is used inside the PriorityHBox.

5. Optional Box: This widget has the name VclOptionalBox, and its parent class is GtkBox. This “box which can hide own content”, is a widget that is useful for creating small areas dedicated to a specific purpose. For example, you may see Home-Section-Clipboard, which is used to define an area for clipboard related tasks inside Home tab.

6. Contextual Vertical Box: This widget has the name sfxlo-ContextVBox and is a “vertical box hiding children depending on context” and its parent class is GtkBox. It provides a box that can act based on the context, showing and hiding its children accordingly. You may look into sw/uiconfig/swriter/ui/notebookbar_single.ui, which provides an example use.

Here is the correct control hierarchy, as depicted and described in the TDF Wiki:

Correct Notebookbar controls hierarchy

Correct Notebookbar controls hierarchy

Menu Widgets

7. Dropdown Box: This widget has the name sfxlo-DropdownBox, its parent class is GtkBox and is a “box which can move own content to the popup”. This is also useful where the space for the tabbed interface is not big enough. The menu, is what you can see in “File” and “Help” menu in every notebookbar in LibreOffice tabbed interface. Please note that only 1 GtkBox child should be inside it, so that the popup works properly. In fact, the above diagram shows the correct usage.

8. Managed Menu Button: This widget has the name svtlo-ManagedMenuButton, and its parent class is GtkButton. It is a “Managed Menu Button”. It provides a button that opens a dynamic menu which is populated according to the context.

Custom Widgets for the Extensions

9. NotebookBar MenuItem Addons: This widget has the name NotebookBarAddonsToolMergePoint, and its parent class is GtkToolButton. Specifically, LibreOffice extensions can use it for adding additional tools to the notebookbar.

10. NotebookBar MenuItem Addons: This widget has the name NotebookBarAddonsMenuMergePoint, and its parent class is GtkMenuItem. This is also used for adding extra items into the notebookbar.

Final Notes

You can find useful information about Notebookbar in the design team blog:

And at last, these are some useful Wiki articles around Notebookbar in the TDF Wiki:

by Hossein Nourikhah at November 14, 2024 03:04 PM

November 08, 2024

allotropia

Announcing ZetaOffice, a new LibreOffice Technology product for web, mobile & desktop

Hamburg and Bolzano, November 8th, 2024 – During the two-day annual South Tyrol Free Software Conference, allotropia software GmbH today announces beta versions of its new product line “ZetaOffice”.

ZetaOffice is a new set of applications, libraries and services, all powered by the LibreOffice Technology stack. Featured among its products is ZetaJS, an innovative browser-based plugin, with unique programmability & embeddability – the perfect tool for complex office editing, process automation and line-of-business applications in the web.

Additionally, leveraging the unique portability and flexibility of the LibreOffice Technology stack, ZetaOffice will be available in bit-by-bit identical versions (allowing for perfect interoperability and feature parity) also for open-source-based mobile operating systems (Android, and derived OS), as well as for all relevant desktop operating systems (Windows, macOS, Linux – via flatpak and snapcraft).

“We’re very excited being able to offer powerful, data-sovereign Open Source office functionality on even more platforms today”, says Thorsten Behrens, owner and managing director of allotropia software. “In particular our innovative, WASM-based browser version of LibreOffice will be a game-changer for every web developer in need of processing, analysing or integrating with office documents.”

“This could not have come at a better time”, says Michiel Leenaars, director of strategy at philanthropic investor NLnet Foundation. “It is long overdue but certainly in the wake of the recent geo-political developments, we all recognise the urgent need for Europe to regain its technological independence when it comes to core technologies – as boring as these may seem. ZetaOffice shows that Europe has the talent and capacity to break with the past and create new paradigms and use innovation and collaboration to save the day.”

“ZetaOffice is the perfect addition to our portfolio of tools for document and business process automation”, says Uli Brandner, CEO and owner of CIB Group. “With solutions like CIB flow for workflow modeling and CIB coSys for high-quality template management, CIB Group already offers powerful digitalization tools. As demand grows to bring proven applications to the web and stay on the cutting edge of technology, ZetaOffice stands out as an innovative solution precisely tailored to our customers’ needs.”

A detailed blog post, including links to beta versions of the software, is available here.

For the products, please refer to our website at zetaoffice.net.

ZetaOffice and the team at allotropia thanks the European Commission’s Next Generation Internet initiative/NGI Zero for its financial contribution to the development of this software.

About ZetaOffice:

ZetaOffice is a product line based on LibreOffice Technology, comprising of desktop LTS products for classical office productivity requirements; a browser-native version based on WebAssembly for fast, client-side integration and automation of office technology; and an
upcoming mobile app widget, for deep integration in mobile line-of-business applications. ZetaOffice is focused on speed, superb embeddability, excellent inter-product as well as Office compatibility, and geared towards digital-sovereign & data protection needs.

About ZetaJS:

ZetaJS is a JavaScript library, available via the npm package manager, to enable developers to quickly & conveniently embed ZetaOffice WebAssembly in web applications. ZetaJS makes available the entire gamut of the LibreOffice programmability interfaces, providing a web-native component for JavaScript developers to deeply embed an office suite into their web apps. In contrast to classical cloud-office setups, ZetaJS can be used as an integral, client-side part of any web application – permitting users to interact with office documents as part of a larger application framework, with very low latency. That way, e.g. direct integration for editing, suggestions or running calculations in complex spreadsheets can be provided. Similarly, it’s trivially easy to implement direct, client-side rendering and export of office documents into PDF or HTML – all via a self-hostable, digital-sovereign Open Source solution.

About allotropia software GmbH:

The company allotropia software GmbH provides services, consulting and products around LibreOffice and related opensource projects. Founded in 2020 by long-time developers of the project, its stated mission is to make LibreOffice shine – in as many different shapes and forms as necessary to serve modern needs towards office productivity software. allotropia software GmbH is headquartered in Hamburg, Germany at the birthplace of the OpenOffice/LibreOffice project. For more information, visit allotropia.de, or follow fosstodon.org/@allotropia on Mastodon and LinkedIn: www.linkedin.com/company/allotropia-software-gmbh

by allotropiasoft at November 08, 2024 10:59 AM

Launching ZetaJS for ZetaOffice

Today allotropia has launched the ZetaOffice range of products at the SFSCON in South Tyrol. ZetaOffice is a LibreOffice Technology built & designed for professional use in the browser, on the desktop and on mobile.

We are excited to additionally announce a massively improved way for which LibreOffice Technology can be used fully client-side on the web. As an additional building block, we have developed the ZetaJS wrapper, which enables convenient embedding and automating WASM (WebAssembly) builds of ZetaOffice via JavaScript. With that, all of the LibreOffice Technology APIs and features are available to web applications – and by leveraging WASM, which runs ZetaOffice client-side, no server or cloud services are needed. All processing is taking place on the client browser, which minimizes latencies & load (of course, a minimal static delivery of web application code, assets and the WASM binary is still needed, but that’s extremely light-weight). 

Examples

Let’s look at some simple examples to give you an idea, how easy ZetaOffice integration is. All comprise of an HTML and a JavaScript file. A ZetaOffice WASM build will automatically be included from the following URL. To replace it with a custom WASM build see config.sample.js of each demo.

https://cdn.zetaoffice.net/zetaoffice_latest/

Next you need to upload the zetajs/ folder onto a webserver of your choice, which sets the following HTTP headers (see developer.mozilla.org for further details):

Cross-Origin-Opener-Policy "same-origin"
Cross-Origin-Embedder-Policy "require-corp"

So back to the example code. The HTML files for all examples embed ZetaOffice and some JavaScript loading code. Please check the actual JavaScript file for the code interacting with ZetaOffice.

Lets have a look at the simple.html (see live). ZetaOffice displays its content using an HTML canvas. So in line 14 we initialize this canvas. Currently a list of attributes like is needed for the canvas. But we will migrate those attributes to the ZetaJS wrapper, so they won’t be needed anymore in the HTML code.

<canvas
  id="qtcanvas" contenteditable="true"
  oncontextmenu="event.preventDefault()" onkeydown="event.preventDefault()"
  style="height:100%; width:100%; border:0px none; padding:0;"/>

The Module variable on line 30 passes the information needed to initialize WASM binaries. First is the canvas. And second is an array of JavaScript files which will be executed in the main Web Worker running the WASM binary. Web Workers are a process like feature of the browsers WASM runtime environment. We pass the ZetaJS wrapper and a file with custom JavaScript code, in this example the simple.js. You may need to ensure, that the zeta.js is reachable under the given URL path.

Line 33 to 39 preload the soffice.js file to ensure, it’s not being blocked by the browsers origin policy when loaded from a foreign origin. Line 42 triggers a website resize event, to make ZetaOffice display nicely inside the canvas. This can be done more precise, as shown in the more complex demos. But for the start the resize event will be triggered after a fixed interval. And finally the soffice.js document is finally loaded which triggers the start of the WASM binary.

Second is the simple.js file. It’s running inside the same Web Worker as the WASM binary to enable interaction. When running in Chromium / Google Chrome you will find a dropdown list labeled “top” at the upper left of the “Console” tab in the developer tools. There you can select the em-pthread_1 Web Worker to debug code in the simple.js file.

Inside the simple.js you will find pretty much the same code as when controlling a LibreOffice running naively on Linux, Windows or any other native OS. It is using LibreOffice’s UNO interface. Most existing examples using UNO via Python or Basic can be easily moved to JavaScript.

The control flow is being passed by the Module.zetajs.thenwhich gets called as soon as the WASM binary is loaded. It passes the zetajs object from which we first get the common com.sun.star object (do not confuse it’s abbreviation css with HTML CSS). In the lines 11 to 21 we get some control objects via UNO, which allow us to trigger the load of an example office document example.odt which is embedded in the WASM binary.

Module.zetajs.then(function(zetajs) {
  function getTextDocument() {
    const css = zetajs.uno.com.sun.star;
    const context = zetajs.getUnoComponentContext();
    const desktop = css.frame.Desktop.create(context);
    let xModel = desktop.getCurrentFrame().getController().getModel();
    if (xModel === null
      || !zetajs.fromAny(
        xModel.queryInterface(zetajs.type.interface(css.text.XTextDocument))))
    {
      xModel = desktop.loadComponentFromURL(
        'file:///android/default-document/example.odt', '_default', 0, []);
    }
    const toolkit = css.awt.Toolkit.create(context);

Line 27 is where the actual application logic starts. In this simple example we get a cursor object from the document to insert the text string here! at the top. In the final section from line 32 to 38 each paragraph of the office document becomes colored in a random color.

    const xText = xModel.getText();
    const xTextCursor = xText.createTextCursor();
    xTextCursor.setString("string here!");
  }
  {
    const xModel = getTextDocument();
    const xText = xModel.getText();
    const xParaEnumeration = xText.createEnumeration();
    for (const next of xParaEnumeration) {
      const xParagraph = zetajs.fromAny(next);
      const color = Math.floor(Math.random() * 0xFFFFFF);
      xParagraph.setPropertyValue("CharColor", color);
    }

This other simple-examples/ show you a little more interesting tasks you can do with the same basic techniques as shown here. While the HTML files are all the same, the simple_key_handler.js (see live) shows you how to register to ZetaOffice event handlers. And finally rainbow_writer.js (see live) uses this to implement a small tool coloring text as you write it.

More Complex Examples

The next big step is in the standalone/ (see live) example. It adds a nice loading animation and shows you how to pass messages between the WASM Web Worker and the browsers main thread, handling the HTML page. This is being used to implement some simple controls on the HTML page for formatting text inside ZetaOffice. The demo is build as a npm package and can be run according to the contained README.md. Don’t forget to pass an URL to the soffice_base_url variable as explained above!

Additional examples are vuejs3-ping-tool/ (see live) and letter-address-tool/ (see live). The vuejs3-ping-tool/is again a npm package, and show-cases how to automatically fill spreadsheets documents with values, displaying them in nicely animated Calc charts. The other letter-address-tool/ example gives you an impression how to connect ZetaOffice with external data sources to automatically create letters from templates, and export the result as office document or PDF file.

Please share your feedback as a comment in the blog, or use the GitHub issue tracker for suggestions or bugs in the code!

by Moritz Duge at November 08, 2024 10:58 AM

Miklos Vajna

Handling page captures for Writer TextBoxes

Writer TextBoxes provide the user with shapes that can have complex geometry and complex content. There is also a feature to capture shapes inside page boundaries: now the two features interact with each other better.

This work is primarily for Collabora Online, but the feature is available in desktop Writer as well.

Motivation

As described in a previous post, Writer implements the TextBox feature with a pair of objects: a Draw shape (with complex geometry) and a (hidden) Writer TextFrame, providing complex content. To avoid wrapping problems, the underlying TextFrame always has its wrap type set to "through", i.e. text may wrap around the Draw shape, but the hidden TextFrame is always ignored during text wrapping.

In most cases this provides the expected behavior, because the user sees one object, so wrapping around at most one object is not surprising.

However, there is also an other feature, that shapes may be captured inside page frames: if their position would be outside the page frame, Writer corrects this, so they are not off-page. This also makes sense, so it can't happen that your document has a shape that is hard to find, due to a silly position.

The trouble comes when these two are combined: the Draw shape's position gets adjusted to be captured inside the page frame, but the TextFrame's wrap type is "through", and objects with this wrap type are an exception from the capturing mechanism, so the position of the two shapes get out of sync.

Results so far

The problem is now solved by improving the layout, so in case the TextFrame is actually part of a Draw shape + TextFrame pair (forming a TextBox), then we calculate the effective wrap type of the TextFrame based on the wrap type of its Draw shape, so either both objects are captured or none, which results in consistent render result.

Here is a sample document where all margins are configured to be equal, but capturing corrected the Draw shape (and not the TextFrame):

Bugdoc: old Writer render

And here is the same document, with consistent positioning:

Bugdoc: new Writer render

As you can see, now the rendered margins actually equal, as wanted.

How is this implemented?

If you would like to know a bit more about how this works, continue reading... :-)

The bugfix commit was sw textbox: capture fly when its draw object is captured.

The tracking bug was tdf#138711.

Want to start using this?

You can get a development edition of Collabora Online 24.04 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 (25.2).

by Miklos Vajna at November 08, 2024 07:58 AM

October 24, 2024

LibreOffice Dev Blog

Crash fix part 5: crash report tool

In previous blog posts about crashes in LibreOffice, I have discussed how to debug and fix some of crashes. Now I discuss a nice tool to keep track of the crash reports from volunteers: Crash report tool.

Crash Report Statistics

Crash report is available via this LibreOffice website:

You can see that different versions of LibreOffice listed there, and for each and every tracked version, number of crashes during the previous 1, 3, 7, 14 and 28 days can be seen. This is possible using the appropriate buttons on the top.

This data is gathered from those to volunteer to submit reports to make LibreOffice better.

This statistic is very helpful to understand the robustness of the builds in different versions.

Crash Signatures

If you choose a specific version, you may see signatures of the crashes. This is helpful when trying to fix crashes. For example, this is one of the crash signatures found in LibreOffice 24.8.0.3:

This shows that the crash happens in GetCharFormat() function. One may use this information to track and fix the problem.

Looking into one of the crashes, one may see the details of the crash, including the stack trace in the crashing thread, and link to the exact place of the source code that leads to the crash.

As an example, you can see this crash report.

Sometimes, experienced developers may be able to reproduce the bug using crash signatures while knowing some background. Otherwise, in most cases, filing a bug with documents and instructions to reproduce the bug is essential. Adding a link to the crash report can be helpful.

by Hossein Nourikhah at October 24, 2024 02:05 PM

October 17, 2024

LibreOffice Dev Blog

WSL for building LibreOffice

Windows Subsystem for Linux (WSL) is a mechanism to use complete Linux distributions on Windows. Here I discuss how to use it to build LibreOffice for both Linux and Windows binaries.

What is WSL?

WSL is the relatively new mechanism in Windows that lets you use a complete Linux distribution alongside your Windows. Interoperability between WSL and Windows lets you to share files and utilities between Windows and Linux. That is where it becomes helpful for LibreOffice, as LibreOffice make depends heavily on GNU tools, which are available in Linux.

Linux or Windows?

You can use WSL for 2 different scenarios:

1. Building for Linux: this is the full Linux build, in which Linux compilers, libraries and utilities will be used to create a Linux binary. You can then run or package the Linux build. You can find more information here:

Using WSL2 is recommended, as it is supposed to be faster, and also you can simply use the graphical interface of LibreOffice.

LibreOffice build on WSL with Linux binaries, displayed on Windows

LibreOffice build on WSL with Linux binaries, displayed on Windows

When you run the resulting binary, the graphical interface is usable, and it will use GTK fronted by default.

2. Building for Windows: this is the WSL as helper mode, where it uses only a few Linux utilities like pkg-config, make, automake and a few other utilities to configure the project.  Then, GNU Make for Windows will be the tool to build the project. More information is available here:

The results are Windows .exe files, and you can simply run them on Windows as native programs.

Build Options on Windows

You can build LibreOffice on different platforms. On Windows, it is possible to use Cygwin, but using WSL can be faster, and considering some issues with recent Cygwin versions, WSL is an alternative.

One can imagine of other ways to build LibreOffice on Windows, including MinGW. But, at the moment, MinGW, both as a helper to use Visual Studio, and also as an independent distribution to build LibreOffice, is not usable due to various reasons.

And last note: if you do not have prior experience with LibreOffice development but you are interested, you can start from our video tutorial for getting started with LibreOffice development.

by Hossein Nourikhah at October 17, 2024 02:01 PM

October 04, 2024

Miklos Vajna

Per-paragraph semi-transparent shape text in Impress

The SVG export in Impress now supports a per-paragraph setting to handle semi-transparent shape text, while previously this was only possible to control at a per-shape level.

This work is primarily for Collabora Online, but the feature is available in desktop Impress as well.

Motivation

As described in a previous post, Impress already had the capability to have semi-transparent shape text, but the SVG export of this for the case when not all paragraphs have the same setting was broken.

Transparency in SVG can be described as a property of a group (<g style="opacity: 0.5">...</g>) and it can be also a property of the text (<tspan fill-opacity="0.5">...</tspan>).

The SVG export works with the metafile of the shape, so when looking for meta actions, it tries to guess if the transparency will be for text: if so, it needs to use the tspan markup, otherwise going with the g markup is OK.

What happened here is that meta action for a normal text started, so the SVG export assumed the text is not semi-transparent, but later the second line was still transparent, so we started a group element, and this resulted in a not even well-formed XML output.

Results so far

The relevant part of the test document is simple: just 3 paragraphs, the second one is semi-transparent (and also has a bullet, as an extra):

Bugdoc: original Impress render

Once this was exported to SVG, this resulted in a non-well-formed XML, so you got this error in a web browser:

Bugdoc: old SVG render

Once tweaking the transparency mask writer to check if text started already, we get the correct SVG render:

Bugdoc: new SVG render

How is this implemented?

If you would like to know a bit more about how this works, continue reading... :-)

The bugfix commit was SVG export: fix handling of semi-transparent text inside a list.

The tracking bug was tdf#162782.

Want to start using this?

You can get a development edition of Collabora Online 24.04 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 (25.2).

by Miklos Vajna at October 04, 2024 06:22 AM

September 19, 2024

Björn Michaelsen

Nothing ever happens

Nothing ever happens.

And nothing ever happens, nothing happens at all The needle returns to the start of the song And we all sing along like before -- Del Amitri, Nothing Ever Happens

In my last post on Libreoffice I promised to talk about Writer changes once in a while, but then ... nothing ever happened. However, given that I had an annoying motorcycle accident in the meantime that turned out much more persistently annoying than originally thought, I think I have a bit of an excuse.

So ... what did happen? For one, I fixed quite a few regressions with my name on them, but ... is there much to talk about here? Mostly not: If you look at the fixes, they are often oneliners fixing something that seems rather obvious in retrospect. The more tricky question is: how did these get in in the first place? Its hard for me to say that, as the introducing commits are from even longer ago.

One thing is certain though: Often a unittest would have caught them, so whenever possible, I tried to create a reproducer adding such a test with the fix. To anyone writing bug reports: Creating minimal reproduction test is hugely valuable in this -- not just for finding the issue, but also as a starting point for a regression test. So if a bug bugs you and it is missing a minimal reproduction scenario, adding one is a great way to move this forward. Oh, and maybe verifying a bugfix, if someone provided a fix and the friendly bot say affected users are "encouraged to test the fix and report feedback".

While doing these fixes, I stumbled over Noel suggesting to speed up bookmarks in writer which is of course great, but I noticed that the code could be optimized a bit more as the bookmarks of a document are now sorted by their starting position (which was one of the first changes I made back on OpenOffice.org about more than a decade ago). Thus we can use bisectional search on the bookmarks here, which should be even faster. Now, it would be great if the discussion on this between Noel and me would available for others to learn from, wouldnt it? The cool thing is: it is.

All discussion happened on gerrit in the comments so if you want to learn about bookmark in Writer and how to maybe speed them up for documents that have a lot of them, that is a great starting point! Is there anything to add? Well maybe the following: Currently the bookmarks starting at the same position are currently not sorted. If one would sort them by their end position, the bisectional search could maybe cover even more? This would also remove one extra loop of logic and make the code simpler and easier to read.

The performance improvement is likely irrelevant -- esp. since there will be not that many documents with lots of bookmarks starting at the same position. The simpler code might be worth it though. So why wasnt it done?

It still can be tried in a follow-up, but speaking about regressions earlier: This has some obscure regression risk, because if we change the order of bookmarks starting at the same position from undefined to something ordered by the end position it might impact a lot of code using bookmarks. The function in question might actually be faster, but other functions (e.g. the inserting of new bookmarks) might actually be slower. So ... this is left as an exercise to the reader.

Comments? Feedback? Additions? Most welcome here on the fediverse !

September 19, 2024 11:30 PM

September 03, 2024

Miklos Vajna

Improved interactivity for LOK clients in Writer's layout

Writer now has support for doing partial layout passes when LOK clients have pending events, which sometimes improves interactivity a lot.

This work is primarily for Collabora Online, but the feature is useful for any LOK clients.

Motivation

I recently worked with a document that has relatively simple structure, but it has 300 pages, and most of the content is part of a numbered list. Pasting a simple string (like an URL) into the end of a paragraph resulted in a short, but annoying hang. It turns out we updated Writer's layout for all the 300 pages before the content was repainted on the single visible page. In theory, you could reorder events, so you first calculate the first page, you paint the first page, then you calculate the remaining 299 pages. Is this possible in practice? Let's try!

Results so far

The relevant part of the test document is simple: just an empty numbered paragraph, so we can paste somewhere:

Bugdoc: empty paragraph, part of a numbered list and then pasting an URL there

This is a good sample, because pasting into a numbered list requires invalidating all list items in that list, since possibly the paste operation created a new list item, and then the number portion has to be updated for all items in the rest of the list. So if you paste into a numbered list, you need to re-calculate the entire document if all the document is just a numbered list.

The first problem was that Writer tracks its visible area, but LOK needs two kinds of visible areas. The first kind decides if invalidations are interesting for part of the document area. LOK wants to get all invalidations, so in case we cache some document content in the client that is near the visible area, we need to know when to throw away that cache. On the other hand, we want to still track the actually visible viewport of the client, so we can prioritize visible vs hidden parts of the document. Writer in LOK mode thought that all parts of the document are a priority, but this could improved by taking the client's viewport into account.

The second problem was that even if Writer had two layout passes (first is synchronous, for the visible area; second is async, for the rest of the document), both passes were performed before allowing a LOK client to request tiles for the issued invalidations.

This is now solved by a new registerAnyInputCallback() API, which allows the LOK client to signal if it has pending events (e.g. unprocessed callbacks, tiles to be painted) or it's OK for Writer layout to finish its idle job first.

The end result for pasting a URL into this 300 pages document, when measuring end-to-end (from sending the paste command to getting the first updated tile) is a decrease in response time, from 963 ms to 14 ms.

How is this implemented?

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 for this problem was cool#9735.

Want to start using this?

You can get a development edition of Collabora Online 24.04 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 (25.2).

by Miklos Vajna at September 03, 2024 06:08 AM

August 26, 2024

Roman Kuznetsov

The best LibreOffice extensions. Code Highlighter 2

When I translated one book about Python to Russian which contained many examples of Python code I though quite long how to highlight them in the normal text. For book writing I used LibreOffice Writer (of course) but Writer has no a standard tool for code highlighting.

So after some searching I found the LibreOffice extension - Code Highlighter 2. It is also available on our extension site. This extension makes code highlighting using Pygments Python library. There is support for many programming languages and many color styles for highlighting there.

The extension worked fine, but I didn't like that for highlighting I should manually select every code example in the text, then press some shortcut, then select another code example, etc...

I wrote an issue on the extension github page and after some discussions the extension author Jean-Marc Zambon implemented a new feature that allows to highlight all code example in the book in only one action using Paragraph style!

So my workflow in this case will be as follows:

  • Create a snippet for the AutoText with code example that has a special paragraph style (for example, with font name Consolas and font size 12pt) with name, for example too - 'Python_code'.
  • Use this snippet to insert code examples
  • In the end of book writing just use the new feature in the extension and highlight all code examples in only one action!

 


Above you can see examples of the Code Highlighter work with some light and some dark styles.

by Roman Kuznetsov (noreply@blogger.com) at August 26, 2024 11:18 AM

August 23, 2024

Caolán McNamara

Linux Namespaces and Collabora Online

In Collabora Online (for the normal mode of operation) we have a single server process (coolwsd) that spawns a separate process (kit) to load and manage each individual document. Each of those per-document kit processes runs in its own isolated environment. See architecture for details.

Each environment contains a minimal file system (ideally bind mounted from a template dir for speed, but linked/copied if not possible) that each kit chroots into, limiting its access to that subtree.

That chroot requires the CAP_SYS_CHROOT capability (and the desirable mount requires the CAP_SYS_ADMIN capability), and granting those capabilities to the coolforkit and coolmount binaries is a root privilege that, for typical deb/rpm packages, is done automatically at install time.

But it would be far more convenient not to require these capabilities to be set to do this isolation. They grant online more ability to affect its host system than it uses, we only want to mount dirs and chroot into dirs that belong to online and have no need or desire to make them available to any other process or user, and it's awkward, especially during development. to require root privileges to set these capabilities.

This scenario is not unique, and Linux provides namespaces, typically used by container implementations, to support achieving this. So recent work in Collabora Online leverages these namespaces to do its own layer of per-document kit isolation. (There's a good series of articles by Steve Ovens on the various namespaces, with the mount namespaces the most relevant one here.)

In essence, a user level process can create its own namespace in which it is apparently root from its own perspective, but as the original uid from the outside perspective and limited to operating on resources that the original uid is limited to accessing. So for each forkit, instead of requiring initial system capabilities and creating a system level bind mount we instead have no specific initial capabilities, enter a new namespace, unique to each forkit, in which that forkit becomes king of its own castle with apparent full capabilities, and can create bind mounts and chroot into its minimal file system.

Which is pretty magical to me as the whole existence of namespaces passed me by entirely without notice despite debuting over a decade ago.

Nothing is ever simple however, so some hurdles along the way.

Entering the namespace "requires that the calling process is not threaded" (man 2 unshare) which is not a problem for the normal use case in each kit, but did pose a problem for the test coolwsd does in advance to probe if there are working namespaces on the system in determine if it should operate kits in namespace mode or not. There it turned out that the Poco::Logger we use backups existing logs when it creates a new one, and then by default spawns a  thread to compress the old log.

I initially had the vague notion that I could treat a namespace as a sort pseudo-sudo and switch back and forth freely between them, but that's not the model, typically it's a one way journey. But namespaces can be stacked instead with a namespace where the original uid is mapped to (apparent) root then containing another namespace where the user is mapped back to the original uid again. So we do that, each forkit enters its initial namespace and is mapped to root, does the mounts, enters another nested namespace mapped back to the original uid, chroots and drops all of the capabilities gained on entering a namespace.  Which aligns the namespace mode with the expectations of the non-namespaces mode as to what effective uid the kit appears to run as.

The mounts that each forkit does are private to that forkit, so while in the non-namespace case the mounts are visible system-wide, in the namespace case the mounts are not visible either to other forkits or to the parent coolwsd. So how the document is provided by coolwsd to a child kit had to be adapted for the new mode of even less potential leakage between components.

There was a glitch in mounting, because when we bind mounts dirs from our system template we want them to be readonly, which requires the typical Linux 2 step process of mount and remount with readonly flags. This worked for the non namespace case, but failed for namespaces even though the initial mount succeeded. Here we had an extra flag of MS_NOATIME when remounting to potentially shave a little time off use of the kit jail, but in namespaces removing that option from the underlying system mount isn't permitted.

Despite that mount flag change giving working namespace-using kits directly inside toplevel OS, one of our lxc-using ci systems still refused to allow a readonly remount in a namespace to work. The catch here was that lxc is bundled with default apparmor rules which additionally restrict a readonly remount call to a certain set of arguments which our remount effort didn't match, so that had to be adjusted. Specifically the rather obscure MS_SILENT use.

Performance-wise, an unexpected (to me at least) side effect of using namespaces is that the coolwsd measurement of the time to spawn a forkit on my hardware has reduced from an average of 39.63ms per spawn to an average of an average of 6.15ms per spawn, which wasn't the primary goal but is a nice benefit.

Surveying distros where namespaces are available by default suggests:

RHEL/CENTOS

  • 8.0+ works with namespaces out of the box
  • 7.9 (EOL) not enabled by default, possible with
    • echo 10000 > /proc/sys/user/max_user_namespaces

Debian

  • 11+ (bullseye) works with namespaces out of the box
  • 10 (buster) EOL, not enabled by default, possible with
    • sudo sysctl -w kernel.unprivileged_userns_clone=1

Ubuntu

  • 16.04+ works with namespaces out of the box

Ubuntu 24.04 however, while supporting namespaces out of the box, has restricted namespaces via apparmor rules, which complicates things again so Collabora Online .deb packages install an apparmor profile to enable it to use namespaces out of the box.

by caolan (noreply@blogger.com) at August 23, 2024 11:17 AM

July 17, 2024

LibreOffice Design Blog

Peer-to-peer collaboration with LibreOffice

A while ago, Simon Phipps, member of the Board of Directors at The Document Foundation, shared the idea to introduce a peer-to-peer collaboration built in to desktop LibreOffice without the requirement for a cloud provider. This idea has received a lot of attention inside the organization and the design team has started to outline the project now.…

by Heiko Tietze at July 17, 2024 08:22 AM

June 19, 2024

Collabora Community

Hacking LibreOffice in Budapest

Earlier this month, we were pleased to sponsor the Libreoffice Technology Hackfest in Budapest, Hungary, and enjoyed meeting up with some of our fellow LibreOffice Technology hackers. Over two days, a dozen developers from Collabora Productivity and the wider community met up in the Eco Community Space to work on the LibreOffice codebase, and reap the benefits of spending time together.

 

A hackfest is an event where developers from multiple organisations meet each other, work on what they want and also more freely exchange ideas while being together in person. While having an international community working remotely on the codebase is excellent, there are still many benefits to more directly seeing what problems are being tackled by other developer sitting next to you; and this friendly environment allows building relationships that can then help even more in the future (even remotely).

As one attendee Miklos Vajna shared with us after the event, “It was really great to spend a couple of days with the other developers. I found it very helpful seeing what other people are working on, sharing ideas about the future feature possibilities, and especially enjoyed going out for a dinner with everyone in Budapest after a hard day’s work!

For this reason, we were very pleased to sponsor this most recent meet up. Many thanks to all who joined us in Budapest, we look forward to seeing you soon at the next meeting!

If you would like to find out more about joining the Collabora Online or LibreOffice community, we would encourage you to join the Collabora Online Community Forum or have a look at the Collabora Online Github to learn about how to get started.

For more information about our upcoming events, and to learn where you could meet us next, do have a look at our events page.

by Richard Brock at June 19, 2024 11:00 AM

June 05, 2024

LibreOffice Design Blog

Convenient handling of shortcuts

Shortcuts are a major topic for user experience. Novices are advised to learn basic shortcuts beyond the famous Ctrl+C/X/V like Ctrl+1/2/3.. to quickly change the paragraph style to heading 1/2/3… in Writer. Once you have learned those combinations you never want to unlearn and to change the muscle memory.…

by Heiko Tietze at June 05, 2024 01:35 PM