19 May 2022

Interacting with the Review Bot on Gerrit

Have you received “A polite ping, still working on this bug?” message on one of your Gerrit submissions? You can simply send an arbitrary reply to avoid the patch being abandoned within a month. Here we discuss more about Review bot, which is one of the QA (Quality Assurance) tools for the LibreOffice QA team to manage old submissions.

Interacting with the Review bot

You may have received messages from some bots, including Review bot. This bot checks Gerrit to find the older submissions, and abandon the old ones that no one actively work on them.

If it has been several months after the last change on a submission, the bot adds a comment and asks:

A polite ping, still working on this bug?

Then, you can do one of these things, according to your choice:

    1. Reply with whatever you want, and the Review bot will not longer try to abandon your submission. Do this if you want to continue work on the submission.
    2. Mark the patch as “work in progress”. This would be helpful if you want to prevent the bot from monitoring the submission.
    3. Leave it as is. Then, after 1 month your patch will be automatically abandoned with this message:

Abandoned

Abandoning this for the moment due to inactivity. Be aware it can be reopened anytime if you still want to continue working on it. Do not forget to rebase it first.

Even in this case, you don’t have to worry! As the message says, you can simply click on the RESTORE button on the top right of the page to restore the patch and continue working on it.

Please note that if you have restored an old submission, you have to do a re-base to get the latest changes in the LibreOffice code, pushed while your submission was remaining intact. If there is not a merge conflict, you can do this easily by clicking on the REBASE button on the top right of the page. Otherwise, you have to download the patch and resolve the merge conflict manually.

More information

You can find more information about

Also, you can read this previous post on how to use Gerrit code review.

5 May 2022

How to write a good commit message

If you have started your journey to become an experienced developer, you already know that you have to describe what you have done when you change the code and submit it to be merged in the master branch. In git and many other source code management systems, this description is called a commit message.

The commit message has a title, and can have a detailed description. You should separate the description from the title by adding a blank line after the title.

Why it matters to write a good commit message

Some may argue that the code itself is the most important thing, and you should provide a readable clean code. This is true, and you should care most for the code. But, on the other hand, when you are working on a big project with hundreds of developers, it is also important to write descriptive commit message that is easy to read for other developers who work on the same project.

In order to be able to search and find the relevant historical information about different aspects in the code, a good way would be searching in the commit messages. You can invoke:

$ git log

You can press “/” for search, then type a search phrase. By pressing “Enter”, you will get a match, and then the next match by pressing the key “n”. This happens if matches are found.

This is only possible if you and others have previously provided good information on what each change does, providing enough details and keywords, so that others could be able to search efficiently.

If you have added your changes to the staging area of the git, then you can invoke this command to commit the changes.

$ git commit

You should provide a good title and description. Here’s how.

Information Beyond the Commit Message

Git commits also have other information, that are automatically generated. For example, the “Author” field comes from your git settings. You should use your complete first name and surname, and a valid email. Your timezone also comes from your system settings.

The Change-Id is generated when you commit, and it is used to identify a submission across different patch sets. Gerrit adds “Reviewed-on”, “Reviewed-by” and “Tested-by” fields automatically. For example, consider this commit:

Author: Miklos Vajna <vmiklos@collabora.com>
Date: Wed Apr 27 20:12:52 2022 +0200

sd theme: add PPTX import for shape fill color effects

This is always direct formatting, so FillProperties::pushToPropMap()
always has the needed info at hand.

Change-Id: I3317b618e0e8bb7688d0f0fbfe4546e2e8b4e947
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133525
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>

Use an informative title with 50 characters or less

You should describe what you have done in a commit in the commit title. The suggested maximum length for the commit title is 50 characters. Also, you should limit the amount of work in a single commit to only one thing. There are many reasons for that; one of them is to be able to roll back your changes with a single git revert.

For LibreOffice commits, you should provide the issue id at the first of the title. For example, tdf#xyz refers to the bug number xyz in the Bubzilla:

Another abbreviation, cid#xyz refers to the Coverity scan report number xyz:

For other abbreviations, please refer to this Wiki article:

You can refer to the module with its abbreviation (sw, sc, etc.) to emphasize the module that the patch is related to. Here is an overview of the modules of LibreOffice.

It is important to keep the title short, because other people can get the whole idea of the change that you have done at a glance. You can see the list of recent changes in this page:

Also, you can pull the latest changes, and use information from git locally, using these commands:

$ ./g pull -r
$ git log --oneline --since=1week

The above command lists the title of commits from the previous week.

Provide a Detailed Description

Beyond the title, you should provide detailed description of what you have done in the current commit. You can link to other commits with the commit hash if needed.

Using lists with *, +, – or characters like that can help to provide a better formatting for the texts. For example, consider this commit:

Author: Miklos Vajna <vmiklos@collabora.com>
Date: Thu Apr 21 09:08:03 2022 +0200

sw content controls: add insert UI

- add an SwWrtShell::InsertContentControl() to put the current selection
into a content control
- if there is no selection, add a non-empty placeholder
- expose this as a new .uno:InsertContentControl uno command
- add this new command to the bottom of the form menu -- probably we can
have a sub-menu there once there will be more types

Various details are provided as a list. The syntax is mostly similar to the Markdown. Some people argue that the width of the lines should be limited to 72 characters, but there is no consensus on the exact maximum width for line wrapping.

What to Include in the Commit Message?

Include relevant information that can help other developers, including but not limited to:

  • Affected modules
  • history of the problem, and the solution
  • cause of the regression, if this is a fix for a regression
  • backtrace (or parts of it), if needed
  • references
  • any relevant information

How Much Should I Write?

It all depends on you, but please describe what you are doing! Remember that what you write will be read in the future by the others, thus it should describe the changes that you have done in the commit.

Writing a paragraph is the minimum thing that is expected, so the suggestion is that you avoid submitting patches with blank description.

26 Apr 2022

Supporting metafile formats: WMF/EMF/EMF+

LibreOffice supports many file formats, and among them are some raster and vector image formats from Microsoft. Metafile formats WMF, EMF and EMF+ are among the vector formats usable in Microsoft products, and also in LibreOffice. Here we discuss the implementation of the  support for these file formats in LibreOffice.

We call these file formats metafiles, as they are means of storing drawing commands that are calls to the Windows API that draws shapes and text on the screen. It is possible to replay these metafiles to have a graphical output in an appropriate context.

It is possible to create complex shapes using metafiles. For example, if you take a look at the odk/examples/basic/forms_and_controls folder in the LibreOffice source code, you will see some nice examples. Here is one of them: A delicious burger created using vector primitives.

berger.wmf

berger.wmf

The oldest metafile format is WMF, which goes back to Windows 3.1 during 1990s, but EMF and EMF+ are newer formats and support many new features.

LibreOffice can open these file formats. It is also possible to use them as the images inside another formats. For example, you can have WMF inside a DOC or DOCX file, or in native ODT format of LibreOffice.

Code Structure for Metafile Support

The emfio module of LibreOffice handles reading of the metafile records. It essentially translates these records into the mataactions. Then, vcl and drawinglayer display them. You can take a look at emfio/source/reader to see the main source files, wmfreader.cxx and emfreader.cxx in which rely on mtftools.cxx.

An important class which is used here is the GDIMetaFile class, which is described in the vcl/README.GDIMetaFile.md as:

The GDIMetaFile class reads, writes, manipulates and replays metafiles via the VCL module.

A typical use case is to initialize a new GDIMetaFile, open the actual stored metafile and read it in via GDIMetaFile::Read( aIStream ). This reads in the metafile into the GDIMetafile object – it can read in an old-style VCLMTF metafile (back in the days that Microsoft didn’t document the metafile format this was used), as well as EMF+ files – and adds them to a list (vector) of MetaActions. You can also populate your own GDIMetaFile via AddAction(), RemoveAction(), ReplaceAction(), etc.

Once the GDIMetafile object is read to be used, you can “play” the metafile, “pause” it, “wind forward” or “rewind” the metafile.

Other than reading, LibreOffice can write metafile formats as the output. For the output filter, vcl/source/filter/wmf is the place to look at.

Tools for Working with Metafile Formats

As the metafile formats are binary files, you will need tools to be able to work with these formats. We discuss three useful tools among others: mso-dumper, limerest and mtf-demo.

Mso-dumper

The mso-dumper is an in-house developed tool created and used by LibreOffice developers to dump information from the Microsoft binary formats. It reads the binary files WMF, EMF, EMF+ in addition to DOC, PPT, XLS and other Microsoft formats, and dumps it as xml.

To be able to dump a metafile, you should do this:

$ git clone https://git.libreoffice.org/mso-dumper
$ cd mso-dumper
$ ./wmf-dump.py burger.wmf
$ ./emf-dump.py computer_mail.emf

Please note that the burger.wmf and computer_mail.emf files are available inside the LibreOffice source. You should replace the burger.wmf and computer_mail.emf with the path of the file you want to dump its structure.

Limereset

Re-lab provides this tool which had the former name of OLEToy. It is a graphical tool that is suitable for understanding the binary file formats including the metafiles, and investigating the contents of the sample binary files. In addition to the visual display of records and their contents, it has a nice hex viewer that is very handy when debugging binary formats.

You can download this tool from here:

https://gitlab.com/re-lab-project/limerest

Mtf-demo

The mtf-demo is also a useful tool for displaying the metafiles WMF, EMF/EMF+, and also dumping the metaactions.

A demo renders of a metafile using vcl be seen by:

./bin/run mtfdemo odk/examples/basic/forms_and_controls/burger.wmf

This opens the burger.wmf as displays it in a window. You should have built the LibreOffice from sources to be able to run the above command from the LibreOffice source folder.

For debugging purposes, it is also possible to dump metaactions created as the intermediary format before rendering the metafile using -d option:

./bin/run mtfdemo -d odk/examples/basic/forms_and_controls/burger.wmf

If the command is successful, this message will be shown, and metadump.xml will be put in the current folder. The output will be:

Dumped metaactions as metadump.xml

DrawingLayer Primitives

The actual drawing is done using vcl and drawinglayer. One can dump the drawinglayer primitives for debugging purposes. We don’t have a dedicated tool to dump the primitives, but if you look at the tests inside emfio/qa/cppunit/emf/EmfImportTest.cxx, you can add this code snippet to do this:
Primitive2DSequence aSequence = parseEmf(u"emfio/qa/cppunit/wmf/data/stockobject.emf");
drawinglayer::Primitive2dXmlDump dumper;
Primitive2DContainer aContainer(aSequence);
dumper.dump(aContainer, "/tmp/drawinglayer.xml");

Then, after invoking make CppunitTest_emfio_emf, /tmp/drawinglayer.xml will be the dump of the drawinglayer primitives to the /tmp/drawinglayer.xml.

Status of Metafile Support in LibreOffice

Support of metafile formats in LibreOffice is not complete. Some unimplemented records, and some bugs remaining. If you want to help, you can refer to the emfio documentation to see the list of unimplemented records in WMF and EMF/EMF+. Please look at the “Limitations” section.

Recently, Bartosz Kosiorek implemented SETARCDIRECTION record of the EMF. He added the support for this specific record to the LibreOffice core with this commit:

His implementation consists of several changes, including a change in emfio/source/reader/emfreader.cxx to read the record from the file and create tools::Polygon aPoly with additional parameter IsArcDirectionClockWise(). Also, change in emfio/source/reader/mtftools.cxx to set the mbClockWiseArcDirection member variable of the MtfTools class, adding setter/getter for this variable, and also changes in tools/source/generic/poly.cxx to change Polygon::Polygon() and ImplPolygon::ImplPolygon() to add support for the extra parameter, a boolean variable bool bClockWiseArcDirection.

This commit also contains a sample document and a new unit test, TestSetArcDirection() to make sure that the support for this record does not break easily in the future.

Final Notes

For a detailed tutorial on how to fix regressions, you can refer to this blog post:

Regression Fix: Missing Lines in DOCX

19 Apr 2022

Using cmake to build LibreOffice C++ SDK examples

These days, many C++ projects are built using build tools like cmake and meson in addition to GNU make (gmake). In this blog, I have already written on how to compile and run LibreOffice SDK examples using gmake. Now I want to discuss instructions for compiling and running C++ examples using cmake as the build tool. For the previous instructions using gmake, see this older post:

Working with LibreOffice SDK Examples

Compiling and Running using cmake

Using Official LibreOffice Binaries and SDK

To be able to compile and run the C++ examples using cmake, you should have installed LibreOffice and LibreOffice SDK, then you should set LOROOT in CMakeLists.txt to appropriate folder. For LibreOffice 7.3 SDK, you should use this line:

set (LOROOT /opt/libreoffice7.3)

Compiling and running the C++ programs would be easy. For some of the examples, you need to run an instance of LibreOffice to listen for the incoming connections. So, you have to invoke:

$ libreoffice7.3 "--accept=socket,port=2083;urp;"

and then just open the project file in Qt Creator (or any other IDE of your choice that supports cmake), and click Build and then Run.

Local Build

If you have built LibreOffice yourself, use the instdir path for LOROOT:

set(LOROOT = /home/hossein/Projects/libreoffice/core/instdir)

If you use a local build, you may need a running instance of LibreOffice. For this purpose, invoke:

$ ./instdir/program/soffice.bin "--accept=socket,port=2083;urp;"

And execute the project from your IDE.

Building and Running from Command Line using cmake

Here I assume that the project is named example. To build and run the example from the command line using cmake, go to the source folder, and then invoke:

$ mkdir build
$ cd build
$ cmake ..
$ make
$ ./example

The CMakeLists.txt file containing the instructions for building the the example project can be as following:

cmake_minimum_required(VERSION 3.5)

project(example LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(LOROOT /opt/libreoffice7.3)

add_executable(example main.cpp)

SET(CMAKE_INCLUDE_CURRENT_DIR ON)

include_directories(
    ${CMAKE_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}/com/sun/star
    ${LOROOT}/sdk/include
    )
target_link_directories(example PRIVATE
    ${LOROOT}/program
    ${LOROOT}/sdk/lib
    )
target_link_libraries(example
    -luno_sal
    -luno_cppu
    -luno_cppuhelpergcc3
    -luno_salhelpergcc3
    -lunoidllo
    -lxmlreaderlo
    -lreglo
    -lmergedlo
    )

add_definitions(-DLINUX)
execute_process(COMMAND ${LOROOT}/sdk/bin/cppumaker -Gc -O. ${LOROOT}/program/types.rdb ${LOROOT}/program/types/offapi.rdb)

Essentially, the above file specifies these:

1) Include directories: sdk/include, com/sun/star and also the source directory.

2) Library directories: sdk/lib and program.

3) Name of the linked libraries: -luno_sal -luno_cppu -luno_cppuhelpergcc3 -luno_salhelpergcc3 -lunoidllo -lxmlreaderlo -lreglo -lmergedlo

4) Using cppumaker utility to generate UNO headers from the binary description offapi.rdb. You can read more about LibreOffice SDK utilities in LibreOffice DevGuide chapter 4.

Important Environment Variables

Several environment variables are set when you use the original scripts provided by the LibreOffice SDK. When using cmake, you may have to set these environment variables:

On Linux:

export UNO_PATH=/opt/libreoffice7.3/program
export URE_BOOTSTRAP=vnd.sun.star.pathname:/opt/libreoffice7.3/program/fundamentalrc

and on Windows:

SET UNO_PATH=C:/Progra~1/LibreOffice/program
SET URE_BOOTSTRAP=vnd.sun.star.pathname:C:/Progra~1/LibreOffice/program/fundamental.ini

LibOCon 2021 Presentation

I have previously talked about using cmake to build LibreOffice SDK examples in LibOCon 2021. You can see the presentation below:

Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.

YouTube privacy policy

If you accept this notice, your choice will be saved and the page will refresh.

Presentation: LibreOffice SDK Examples OverhaulHossein Nourikhah

This talk was presented in the LibreOffice Conference 2021 (LibOCon 2021) (Slides)

LibreOffice Conference 2021

LibreOffice Conference 2021

11 Apr 2022

How to use Gerrit code review effectively

Any code submission to LibreOffice should pass Gerrit code review in order to get merged into the LibreOffice codebase. This is possible using the code review tool Gerrit.

To understand more, refer to these articles:

For getting started with LibreOffice development in general, watch this video.

Here, I assume that you have read those articles, you have created your account, and you have done your first contributions to the LibreOffice – but you want to know more about how to effectively use Gerrit. This is what I am discussing in this article.

LibreOffice Gerrit

LibreOffice Gerrit

How to Find Reviewers

If you are a newcomer, possibly I (Hossein) and Ilmari can help you. You can add us as the reviewers, and we will review your submissions. Just search for our names in front of the “Reviewers” part in your submission, and you can easily add me or Ilmari as the reviewer.

If you want to work on more complicated tasks, you can also refer to this page to find experts in different areas.

We have experts in these areas:

Access2Base, Automated tests, BASIC, Bugzilla, build system (gbuild), Calc, Chart, Database, Debian, adding dictionaries, documentation, Draw, General UI problems, git⁠ and Writer RTF filters, gerrit⁠, GUI design questions, headless (–without-x build switch), i18nlangtag, i18npool, Impress presentation, KDE, Libcdr and Corel Draw import, libvisio and Visio import, localization fixes / l10n / non-English bug description, localization fixes / l10n tools, Mac, ODF filter, Pebble, PostgreSQL integration, QA, ScriptForge, Translation, Ubuntu, UI, UNO, sal, configmgr, VCL, Weblate, Wiki, Wiki Extension, Wiki Config, Editing, Windows, Windows Installer, Writer, writerfilter, X11-specific

Quite a lot of topics!

But, as you can read in that Wiki page, please “Please do not email these developers personally with your personal pet bug”. Just add them as the CC or the reviewer of a relevant submission.

Handling Problems with the Jenkins builds

Sometimes it happens that Jenkins can not build your submission. This can happen for several reasons. It can be because of a problem in your code, or a problem with the build system itself.

If the problem is from your side, then fix the problem and re-submit your code as a new patch set, and Jenkins will try to build it again.

But, if the problem is with Jenkins, you can either ask on #tdf-infra and someone with appropriate access will resume your build. Another solution would be doing a re-base and then Jenkins will build your submission again. For doing this, you do not need any special permissions.

Please be patient, and keep in mind that CI is a limited resource, so you should use it carefully. Please note that you should build (using make) and test (using make check) on your computer locally before submitting the code to the Gerrit.

Working on Multiple Gerrit Submissions

Sometimes you want to work simultaneously on multiple submissions. Then, you have to create a branch for each of these submissions to be able to work on them.

A tool named git review can help you manage your submissions easily. It is a review tool, but you can use it both for submissions from others (for reviewing), and also your own submissions.

To download a submission with the id of 1234, you can easily do:

git review -d 1234

The id (1234 here) is the number you see in the end of the submission URL, for example: https://gerrit.libreoffice.org/c/core/+/1234. Then, your patch is downloaded, and a new branch is created for that submissions.

If you want to do a re-base, do this:

./g pull -r

If you face a merge conflict, you have to download your changes using the above method, do a re-base, and then try to resolve the conflicts. Then, you have to use git add to stage the changed source files.

When you have finished fixing your submission, you can do:

git commit --amend
./logerrit submit master

If you want to go back to the master branch, just use:

git checkout master

Handling Requested Changes From the Reviewers

In the review process, you should do the changes requested from the reviewers. Sometimes, you may disagree with the reviewers, but then you should provide good reasons for not doing the requested changes in order to convince the reviewers.

Anyway, you should know that your code must conform to certain requirements in order to be eligible for merging. So, try to convince the reviewers that your code deserves to get merged into the code.

For the code conventions and coding style, it is suggested that you refer to these links:

For newer files, you may have to use clang-format, to re-format the code, and convince the CI that your code is fine!

There are many rules in the above links. Among them, this list on variable name prefixes is very useful. The list is extracted and suggested by Mike and Heiko:

  • (Smart) pointer/reference to an UNO interface -> xName
  • (Smart) pointer to anything else -> pName
  • Reference to anything else -> rName
  • Integer value -> nName
  • Floating-point number -> fName
  • Boolean -> bName, or isName, or canName
  • String -> optionally sName (for char * -> pName; for OUString -> aName)
  • Another object -> aName

Other conventions are gathered as extensive set of rules. If you had any doubts, you can refer to the appropriate section that discuss design, implementation, testing and other aspects.

On the other hand, you should know that the easiest part of the change is the coding style! There are many things related to good design and implementation that you should take care to be able to pass the code review and get a +2.

Search Among the Gerrit Submissions

By clicking on the name of each person in the Gerrit, you can see their contributions. But, this is not the whole story! Gerrit has a powerful query language that you can use inside the search box. For example:

owner:self: My own contributions

reviewer:self: Submissions that I am reviewing

owner:self status:merged: My merged contributions

owner:self status:open: My open contributions

You can use boolean operators between the queries:

AND -(negation) OR

If you do not specify anything, then AND is used.

You can do a lot of complicated searches among the submissions using its manual.

Final Remarks on Gerrit Code Review

Gerrit is a powerful tool, and you can use many features of it to work more effectively. But, keep in mind that your focus should be on fixing the possible problems of your code, and improving your code quality.

Don’t worry! Reviewers usually help you on the road to fix the problems. Although in the end, it is your responsibility to address the concerns and do the recommendations – and eventually fix your code.

To get more help, you can always refer to its manuals.

I hope that you will get the best out of this review tool!

10 Mar 2022

Use std::hypot for Pythagorean Addition – EasyHack

There are many places in the code that calculating the Pythagorean addition is needed. (more…)

8 Mar 2022

Use Range Based For Loops – EasyHack

Because for loops are a powerful tool in C/C++, they are one of the desirable tools when you want to do something repeatedly, or process elements of a data structures. But there many ways to write a for loop. Some forms of it are easier to use, read, write and understand, and some are not. Range based for loops are discussed in this article. They can be good if you know where to use them. (more…)

23 Feb 2022

Adding a new UNO command

What are UNO commands, and why would you need them? If you want to add some feature to the LibreOffice UI, you may need to add or modify a UNO command, so it would be help much to learn more about these commands, and in general, the dispatch framework. So, stay tuned! (more…)

10 Feb 2022

Working with LibreOffice SDK Examples

Do you want to write a program that uses LibreOffice to convert different formats, or otherwise work with LibreOffice from another process? A solution would be using LibreOffice SDK. (more…)

26 Jan 2022

Regression Fix: Missing Lines in DOCX

Interoperability is a very important aspect of the LibreOffice. Today, LibreOffice can load and save various file formats from many different office applications from different companies across the world. But, bugs (specially regression bugs) are inevitable parts of every software. In fact, there are situations where the application does not behave as it should, and a developer should take action and fix it, so that it will behave according to the expectation of the user. (more…)