The Document Foundation Planet


March 02, 2021

Official TDF Blog

Update on tender for a built-in UNO object inspection tool in LibreOffice

In July last year, we launched a tender to implement a dedicated, built-in UNO object inspection tool in LibreOffice. UNO refers to Unified Network Objects, the component model used by the software.

Tomaž Vajngerl was assigned to work on the tender, and has blogged about his progress. He discusses the point-and-click functionality to inspect selected objects in the document, and his next steps.

If you’re interested in the technology “under the hood” in LibreOffice, check it out!

by Mike Saunders at March 02, 2021 02:10 PM

Olivier Hallot

Exporting LibreOffice Guides to HTML (Part I)

LibreOffice is an open source office suite full of tricky secrets. One of my favorites is the possibility to export a text document to XHTML or HTML5, both are W3C standards supported by most modern web browsers.

But you, the reader, will certainly ask: If I have the Guides in ODT and PDF file format why do I need another format? Why spend energy adding another medium for the LibreOffice Guides? 

There are advantages and drawbacks for the endeavor. On the thumbs up side, the community get a way to read the guides without actually downloading the PDF or ODT file and contents can be accessed with the browser's navigation tools (including bookmarking and more). One example is the current ODF Standard files exported to XHTML, available at the OASIS website.

A second advantage is that (X)HTML pages can be crawled and indexed by search engines robots and the LibreOffice Guides can be found on the search results pages of Bing, Google, DuckDuckGo and others.

Another exciting possibility for distributing the guides in (X)HTML format is that they could be installed on the intranets of schools, colleges and universities, public libraries, also community, public administrationand private company websites. The files are static and don't need a server side scripting languages such as php or asp. Distributing the rich contents of the LibreOffice Guides in a browser readable format will add value to every LibreOffice migration project.

One critical factor in the success of a LibreOffice migration project is how quickly users can transition to the new software and having readily available, easily accessible documentation in different forms should not be underestimated.

How difficult is to convert the Guides to an (X)HTML format?

My experience is that there are some work to do in the ODT side, and some work on the exported (X)HTML. The nice part is that these changes are small and can be partially automated.

LibreOffice has an interesting XHTML export filter. The developers did their best to preserve formatting and document fidelity between different rich text output formats. A second tool I tried is the nice extension writer2xhtml, which also have interesting features.

However reading contents in a browser (or even a tablet and a mobile phone) requires scrolling instead of the usual page turning, as in a printed book.

The layout of the document's content must be adapted to the browser's navigation actions. This requires the layout to be adjusted for on-screen viewing. Besides, it is interesting to also adapt the contents to tablets and perhaps mobile phones.

Luckily, all elements for navigation exist in the ODT file, they are just in the wrong position when exported to XHTML. The approach is to wrap these elements in sections with specific names. After being exported to XHTML these sections are mapped in <div id="name">...</div> and can be accessed by both a CSS and Javascript for pagination and layout.

Here is one layout among many alternatives, for a simple export of our Guides to a browser page layout.

Besides the existing sections in the chapter, we can add other blocks with content of interest, for example a donation section a search form for either an external or internal search, such as Xapian and Omindex.

In the next post, I'll describe the changes needed in the Guide templates and discuss some of the alternate approaches for the task.

Stay tuned!

by Olivier Hallot ( at March 02, 2021 12:11 PM

Jean Hollis Weber

LibreOffice 7.0 Getting Started and Impress Guides

Two more volumes of LO 7.0 user guides were published in January: Getting Started Guide and Impress Guide. They are available in free PDF downloads and in low-cost print editions. See this page for links.

by Jean at March 02, 2021 12:54 AM

LibreOffice 7.1 Community released

On 3 February, The Document Foundation announced the release of LibreOffice 7.1 Community, the volunteer-supported version of the office suite. The Community label emphasises the fact that the software is not targeted at enterprises, and not optimised for their support needs. Blog post with more information.

For enterprise-class deployments, TDF has strongly recommended the LibreOffice Enterprise family of applications from ecosystem partners—for desktop, mobile and cloud—with long-term support options, professional assistance, custom features and other benefits. See LibreOffice in business.

by Jean at March 02, 2021 12:43 AM

March 01, 2021

Tomaž Vajngerl

Built-in "Xray" like UNO object inspector – Part 2

Since my last blog post I've been continuing the work on DevTools and since then a lot of things have progressed. Point & click has been implemented and the object inspector view has been greatly improved to show current object’s properties and methods. In this part I will mainly talk about the point & click and a bit about the current state, and in the next blog I will extensively talk about the object inspector.

Point & click

Figure 1: Current selection button

The idea of this functionality is to provide a way to inspect selected objects in the document, for example an image or a shape. For this, I have implemented a selection change listener (sfx2/source/devtools/SelectionChangeHandler.hxx), whose purpose is to listen to the selection changes that happen in the document and store the latest selection object. It is started when the DevTools docking window is instantiated and shown. I have added a new toggle button “Current Selection” (see Figure 1) to the UI. When the button is selected, it automatically shows the current selected object (gathered with the selection change listener) in the object inspector. 

Figure 2: Current selected shape's properties shown in the object inspector

In the example shown in Figure 2, we can see the shape is selected in the document and its properties are shown in the object inspector. If the "Current Selection" button wouldn't be toggled, then the document top-level object would be shown in the object inspector or the selected object in the DOM tree view.

While the "Current Selection" button is toggled, selecting any object in the DOM tree view (left-hand side tree view) has no effect, however if the current selected object is also present in the current DOM tree view, it will be selected. Note that if the object is not present in the tree, it won't be selected, because the DOM tree view will not force creation of on-demand object because of performance considerations.

Figure 3: "Inspect Object" command in "Customize" dialog 

In addition to showing the selected object, I have added a UNO command named “Inspect Object” (.uno:InspectSelectedObject), which can be added to context menus for objects (See Figure 3). The purpose of this command is to provide a way to open the DevTools docking window and automatically show the current selected object. If a user regularly uses the object inspector, this may be a more convenient way for them to access DevTools. Note that by default the command isn't added to any context menu, this is up to the user. However, if there will be demand to add this to context menus, it can be easily added. 

Figure 4: "Inspect Object" context menu entry on a shape object

The example in Figure 4 shows the context menu of a shape object, where the selected entry is the added "Inspect Object". 

From the implementation standpoint, it was necessary to move the whole DevTools from svx to sfx2 module. This was mainly necessary to get .uno:InspectSelectedObject to work, because we need to signal to DevTools that we want to show the current selection and not the document root in the object inspector. Because the svx depends on sfx2 module, it is not possible to access svx from sfx2 (only the other way around). 

Improvements to object inspector

The object inspector was previously a single tree view only, which had services, interfaces, properties and methods categories as root tree entries. This has now been changed so that the categories are now pages in a tab view, and each category has its own tree view (can be seen in Figure 2). The main problem with one tree view is that columns for each of the categories are different. For example, the properties category has object, value and type categories but the same columns make no sense for methods (which has return type and input parameters). 

For methods it now shows the method name, return type and parameters. The types are currently simplified types, which are easier to read (instead of exact type name of the object it just writes "object"), but the user will want to know the exact type too, so this is a WIP.

For properties it shows the type and value of the property, and it is possible to expand a property if the type is a complex type (object, struct) so it lists nested properties. If the value is an enum, then we get the name of the enum value automatically and show the name instead. 

Support for sequences was also added, so the sequence can be expanded and a list of indices and values is presented. If the current object supports XNameAccess or XIndexAccess, the names and indices are added into the property list, so the user can navigate to those. 

With this additions, it is already easier to inspect objects than it previously was using the Xray tool, and I'm sure it will get even better when it is finished. 

Next steps

The object inspector is already in a very good shape so I encourage everyone to try it and give feedback, what can be improved, changed or added - especially if you use Xray or MRI regularly. 

For the next steps the major focus will be to fix a couple of bugs and crashes (mainly due to missing checks if objects are available), work on the UI, object stack (so it is possible to go back to the previous object) and finalizing all the features of the object inspector. 


Many thanks to TDF and users that support the foundation by providing donations, to make this work possible. 

To be continued...

by Tomaž Vajngerl ( at March 01, 2021 12:49 PM

Official TDF Blog

Community Member Monday: Rafael Lima

Today we’re talking to Rafael Lima, who helps the LibreOffice project by updating its documentation…

To start with, tell us a bit about yourself!

I am a university professor in Brazil, and I teach and research optimization applied to management sciences. In my work I often need to write papers and prepare spreadsheets to analyze data, and for that I’ve been using LibreOffice for over a year now. I have been working with supply chain optimization problems such as vehicle routing, network design and facility location.

I have always been an enthusiast of Open Source, since my undergraduate days in 2001. At the time I started using Linux and most of my current research work is done using FOSS tools. The dynamics of how open source software is developed is a topic that has always caught my attention.

Outside of work, I like to spend my free time practicing sports (mostly playing tennis) and whenever I have the opportunity I like to travel to new places. And obviously, like many tech enthusiasts, I like gaming too!

What are you working on in the documentation project right now?

The Documentation Team is currently working on the guides for the LibreOffice 7 series, and I am helping update and review some chapters in these guides. I have recently updated the Getting Started Guide chapters on Math and Macros.

Besides that, I have recently started writing a Macro tutorial focused on LibreOffice Calc, to help Calc users to get started with Basic programming and develop their own macros and functions. I hope to cover many aspects of Basic programming in Calc, ranging from reading and writing data from cells, formatting, dialog creation and writing extensions. If all goes well, I hope to finish the tutorial by February and release it to the community. If anyone wants to follow the development of the tutorial, it is available on my GitHub page.

How did you get started in the LibreOffice community? What was the experience like?

I started contributing to the Documentation Team after I read a blog post by TDF saying that they were looking for volunteers to help update the guides for LibreOffice 7. Then I joined the mailing list and I was welcomed and instructed by Olivier Hallot on the workflow of the Documentation Team.

After going over the Wiki and the Contributor’s Guide, I started updating the Math Guide. It was a very nice experience, because all questions I had were promptly answered by other members of the team and I was able to learn quickly how work gets done.

After finishing the Math guide I kept on contributing with other guides, mainly the Getting Started Guide and the Writer’s Guide.

Anything you’d recommend to newcomers in the docs project?

My work in the Documentation Team was my first real experience with an open source project, and it was a great opportunity to learn how open source really works. It’s amazing to see how the LibreOffice community is capable of delivering high-quality applications and documentation.

As a newcomer I was afraid I was not going to be able to tackle the complexities of such a huge project as LibreOffice. However, being a large project means that LibreOffice has a large community to support new contributors.

From a more practical standpoint, my recommendation for newcomers is to start by reading the Contributor’s Guide, and then choose one of the LibreOffice applications to which you would like to contribute. Also, join the mailing list, introduce yourself and more experienced members will be glad to explain how contributions can be made.

Many thanks to Rafael for all his contributions! And for everyone reading this who wants to build up skills for a potential career in technical writing, join our community, gain experience, and meet new people!

by Mike Saunders at March 01, 2021 11:23 AM

February 26, 2021

Michael Meeks

2021-02-26 Friday

  • Short TDF board call; partner / sales call, admin. Out for a run with J.
  • Finally got around to posting my FOSDEM slides, first an update for the Collaboration dev-room on integrating (with video)
  • And also for the work we did to integrate COOL into an app-image for easy installation as part of Nextcloud Hub (with video)

February 26, 2021 04:58 PM

February 25, 2021

Michael Meeks

2021-02-25 Thursday

  • TDF budget ranking, calls, day of admin. COOL community roundup. Some perf / profiling of COOL - nice N^3 algorithm in writer affecting huge docs found.
  • Idle Freeze Pane fix, product management pieces, late partner call.

February 25, 2021 09:00 PM

Marius Popa Adrian

Firebird 3.0 Language Reference (English) Released

The Firebird Documentation Team is proud to announce the first release of the English Firebird 3.0 Language Reference (HTML, PDF). You can also find it on the Documentation page. This new Language Reference covers all SQL syntax of Firebird 3.0.The new English Firebird 3.0 Language Reference is based in part on the Russian Firebird 3.0 Language Reference, but is not a direct translation (though

by Popa Adrian Marius ( at February 25, 2021 09:00 AM

February 24, 2021

Michael Meeks

2021-02-24 Wednesday

  • Sales calls with Eloy, Kara, Miklos. Planning call, catch-up with Philippe. Poked at a bug.

February 24, 2021 09:00 PM

February 23, 2021

Michael Meeks

2021-02-23 Tuesday

  • Early morning blood-letting at the hospital. Catch up with Kendy, mail chew & admin. Interview.
  • Cut out a rather rough letterbox in the new door; cheap pendulum jigsaw produces rather a different on the other side; hmm.

February 23, 2021 09:00 PM

Official TDF Blog

Getting Started with LibreOffice 7.0 Guide Just Arrived!

Get the LibreOffice introductory Guide and start producing professional documents.

The Documentation Team is happy to announce the immediate availability of the LibreOffice 7.0 Getting Started Guide, updated to include all LibreOffice 7.0 features.

The guide is written for anyone who wants to get up to speed quickly with LibreOffice. Readers may be new to office software, or may be familiar with another office suite. This guide is a valuable asset for all users.

LibeOffice Getting started Guide 7.0

The book introduces the main components of LibreOffice:

  • Writer (word processing)
  • Calc (spreadsheets)
  • Impress (presentations)
  • Draw (vector graphics)
  • Base (database)
  • Math (equation editor)

It also covers some of the features common to all components, including setup and customization, styles and templates, macro recording, digital signature, and printing.

The guide is an effort of the documentation team, and in special thanks to Jean Hollis Weber, Leo Moons and Kees Kriek. Meet the documentation team page!

Happy documenting!


by Olivier Hallot at February 23, 2021 02:13 PM

February 22, 2021

Michael Meeks

2021-02-22 Monday

  • Planning call, status report, worked through E-mail. Enjoyed some nice data from Lubos tracing COW page duplications in Online.
  • Catch up with Thorsten, worked on bug analysis & started slowly getting through the E-mail mountain.

February 22, 2021 09:00 PM

February 21, 2021

Dennis Francis

Mocha tests in Collabora Online

We have many data structure classes in Collabora Online. Most of them are complex enough to warrant unit tests for their correctness. We already have cypress tests in Online which does integration testing, but we need unit tests for the internal data structure classes too. Mocha testing framework is a good match for this. With this we can do asserts via its BDD interface. In fact we could use any assertion library like Chai or Expect.js. You can now add Mocha tests in Online to test its any existing typescript classes or functions.

Here is a sample mocha test written for CPointSet typescript class:

/// <reference path="../src/layer/vector/CPoint.ts" />
/// <reference path="../src/layer/vector/CPointSet.ts" />

var assert = require('assert');

describe('CPointSet empty() tests', function () {

	describe('new CPointSet()', function () {
		it('should be empty', function () {

How to add a new Mocha test to Online?

Lets write a new test for the function CBounds.parse() as an example:

  • Create a new test file for tests related to CBounds class under loleaflet/mocha_tests/. Lets name it CBounds.test.ts
  • Reference the needed types from CBounds.ts by adding these lines.
/// <reference path="../src/layer/vector/CPoint.ts" />
/// <reference path="../src/layer/vector/CBounds.ts" />
  • Import Nodejs assert.
var assert = require('assert').strict;
  • Add a BDD style description of the set of tests we are going to write for CBounds.parse().
describe('CBounds parse() tests', function () {
    // Write unit tests here.
  • Inside that add a few test cases with descriptions like below:
describe('CBounds.parse() call with an empty string argument',
    function () {
	it('should return undefined', function () {
		assert.equal(CBounds.parse(''), undefined);
  • Now run ‘make check’ inside the loleaflet/ dir to see these tests in action. In current master branch you should see something like below along with the results for the new test you have added.

If interested, do take a look at the commit 8b2eae423cf77e7c725843061898c3968a72c547 that integrated Mocha framework to Online.

by Dennis Francis at February 21, 2021 08:43 AM

February 20, 2021

February 19, 2021

February 18, 2021

Mike Kaganski

Reading from MySQL data with BLOBs dumped to CSV

As part of my recent work in upgrading our partner & customer ticketing system to make things sweeter for all our users I have been assigned a task involving importing data from a CSV that was generated using MySQL’s SELECT ... INTO OUTFILE. The problem was that the source table contained BLOB fields.

The resulting CSV was quite non-standard. MySQL simply does not allow to produce CSVs conforming to RFC 4180: it would not escape double quotes by duplicating them, but would use a dedicated escapement symbol (backslash \ by default); and when using that escapement symbol, it will escape byte 0x00 as two characters: \0 (backslash + character “0”). This needs a non-standard processing – e.g., Python’s csv module can’t restore the binary from such a file, no matter which encoding (like latin_1) you use to read file (Python’s csv module only works with files opened in text mode), or which settings you pass to reader. MySQL may be instructed to not use the escapement symbol (using FIELDS ESCAPED BY ''), and then zero bytes will be output as is, but then the double quotes (byte 0x22) inside all fields (including blobs) will be completely not escaped, making the CSV invalid and unreadable. MySQL should just duplicate double-quotes in this case, and it would work out of the box… But for now, I needed to read from the file with escaping by \ and all the quirks.

I hadn’t had time to look for a CSV reader capable of dealing with such a syntax (actually, I did a brief search, but of course not exhaustive). So I had to come with a home-grown Python code for this:

def readMySQL_CSVLine(binfile):
    rec = []
    field = bytearray()
    is_quoted = False # inside quoted field
    is_escaped = False # immediately after "\"
    is_after_quote = False # inside a quoted field, immediately after
                           # a double quote that is not an opening
                           # quote of a field
    while True:
        ch =
        if len(ch) == 0: # EOF
            if (is_after_quote): # There was an opening quote, then
                                 # closing quote, then EOF; the field
                                 # must be added, even if empty
            elif is_quoted or is_escaped: # Missing closing quote or a
                                          # character following "\"
                if is_escaped: # Invalid last "\"
                    field += b'\\'
            elif len(rec) > 0 or len(field) > 0: # Don't return records
                                                 # for empty last line
            return rec
        if is_escaped:
            is_escaped = False
            if ch == b'0':
                ch = b'\x00'
            elif ch not in b'\n"\\,': # "\" should only escape:
                                      # FIELDS ESCAPED BY,
                                      # FIELDS [OPTIONALLY] ENCLOSED BY,
                                      # FIELDS TERMINATED BY,
                                      # LINES TERMINATED BY,
                                      # and ASCII NUL.
                field += b'\\'
            field += ch
        if ch == b'\n' and (not is_quoted or is_after_quote): # EOL
            return rec
        if ch == b',' and (not is_quoted or is_after_quote): # End of field
            is_quoted = False
            is_after_quote = False
            field = bytearray() # no .clear() here, or else it will clear
                                # content inside rec
        if ch == b'"':
            if is_after_quote: # Normal case of two two consequent quotes -
                               # one escapes the other
                is_after_quote = False
                field += ch
            elif is_quoted:
                is_after_quote = True
            else: # not is_quoted
                if len(field) == 0: # First character in a field
                    is_quoted = True
                else: # a quote in the middle of a field that didn't
                      # start with quotes
                    field += ch
        if is_after_quote: # An invalid non-closing lonely quote in the
                           # middle of a quoted field
            is_after_quote = False
            field += b'"' # Add it as usual character
        if ch == b'\\':
            is_escaped = True
        field += ch

It is used like this:

with open('dumped_table.csv', 'rb') as csv_file:
    while True:
        rec = readMySQL_CSVLine(csv_file)
        if not rec:
        numeric_field, text_field, blob_field = rec
        numeric_field = numeric_field.decode('ascii')
        text_field = text_field.decode('utf-8')
        with open('path/to/file', 'w+b') as outfile:

This worked for me. Of course, it may easily be converted to be a proper iterator, but I just leave it here as is. Hope that this could be useful for someone, until MySQL implement an option to produce a standards-compliant export.

by mikekaganski at February 18, 2021 08:48 PM

February 17, 2021

Rizal Muttaqin

elementary Theme for LibreOffice 7.1: Following Upstream's Brand More Closely

[Please see every image in this posting in new browser tab or window to see a more crisp and clear appearance]

Not having a coherent and consistent design system has been a big problem for LibreOffice Community. But a branding guideline could help to fill the empty room. At least with a brand guideline, I can be grateful that our products are not designed carelessly.

Talking about branding, TDF as the organization behind LibreOffice is not too strict in terms of technical implementation. In fact, LibreOffice has always carried the vision of having an interface that blends with the operating system. Something that sounds very familiar to the FLOSS desktop world. With this kind of vision, it feels like the brand's approach to many design elements - like the interface, for example - on the proprietary operating system becomes a bit strange in my opinion. Obviously, in the world of Windows and macOS, applications usually have their own unique design characteristics without even trying to pretend to be part of the operating system. For example, Microsoft Office, the 2007 version does not have the same interface approach (except maybe the Office button which looks like the Windows Start button) with the Windows XP and Windows Vista interfaces. MS 2010 is the same, even though MS 2013 both adopted a flat appearance like the era of Windows 8 and 8.1 but in terms of interface even icons and background knick-knacks in their windows are different. MS Office 2019 and 365 actually use an interface that has no resemblance to Windows 10 at all (except for the flat part which is trending).

The same is true for the macOS version of MS Office, each version no one really wants to appear like Finder. Before the era of MS Office 2019/365, the skeuomorphism characteristics were indeed maintained, but we can easily say that MS Office looks like MS Office completely.

In contrast to LibreOffice, which until now still wants to carry its FLOSS vision so that it looks like a Win32 application using a flat "skin". Fortunately the Colibre is quite helpful for Windows environment.

OK back to branding. After three years ago, the elementary icon theme was getting quite a massive update. I just realized one thing, it turned out that the icons I made used a color that I had taken out of nowhere. To be sure, I utilized some of the previous elementary icon colors and the rest from the Internet. Arriving at one of the bug report Heiko Tietze gave me a link to the elementary OS branding page which immediately got my attention:

Sweety Color Naming Scheme

I immediately realized that elementaryOS has been providing a collection of brand colors that have very unique and interesting names since when. Notice, to name a bunch of yellows they use the word "banana", for the purple they use the word "grapes". What a clever and very intriguing naming. Without saying what color people should have imagined the color in question. Something LibreOffice should adopt.

Here come one example of random color choices:

Why does the line chart have a lighter green color than the plus sign on the Insert Image icon?

Apart from that, there were many icons that turned out to be unsatisfied in my eye. Like suppose the shape is not elementaryi-ish, for example the Navigator icon: Look at the flat red white needle (or what anything you can say) in the center. Flat is not elementary characteristic!

or the confusing choice of color pairs:

Why did I choose this blue and purple? Was it just because the blue export icon and purple import upstream? Yes, it is true, but from a usability point of view it is not very useful but it actually makes it lame.

In addition, there is also a color selection that makes it even more confusing. Please look at the green color in the table header below and take a look at the icons for inserting those columns and rows in the first left group:

Especially when the size is small like this

The use of orange in the selected table, column and row above is also very unsightly.

After all, there are a number of updates already occurring on this elementary upstream. Suppose thisand this. So, the current icon theme is a bit less relevant.

So, some time ago I decided to massively update the elementary icon theme back and here is the result.

tdf#139219: Proposal to remove green header row part in table icon:

tdf#139048: Update Pencil Element to Be Yellow


tdf#139020: Proposal to Revert All Blue-Violet Color Arrow Pair to One Coherent Color
also, many icon with multiple line elements are now thicker even for small size 


Other updates:

Save icon now use red indicator instead of arrow's shape color change to indicate an unsaved work

New Macro icons


New Indexes and Tables (e.g. for Table of Contents) icons:

New Track Change icons

New Navigator icons

New Thesaurus icons

New Show Draw Functions icons

New Image Color icons

New zoom slider and Writer's status bar icons

New Comments icons

Background fill color icons are now using more balance size
New Pivot Table icons

More consistent arrow element usage

Shape icons now using "Grape" purple color instead of previous white.

Per module view: