Cédric Bosdonnathttps://bosdonnat.fr/2021-04-02T10:46:00+02:00A geek's perspectiveBuilding a Language Server for Salt States2021-04-02T10:46:00+02:002021-04-02T10:46:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2021-04-02:/hackweek-lsp.html<h1>Salt States</h1>
<p><a href="https://saltproject.io/">SaltStack</a> is a configuration management software like Ansible or Puppet which allows you to configure your machines via so-called salt states. Salt states are YAML documents with support for Jinja2 templates: </p>
<div class="highlight"><pre><span></span><code><span class="nt">mysql</span><span class="p">:</span>
<span class="nt">pkg.installed</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
<span class="nt">service.running</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
<span class="nt">web_server</span><span class="p">:</span>
<span class="nt">pkg.installed</span><span class="p">:</span>
<span class="p p-Indicator">{</span><span class="err">%</span> <span class="nv">if grains</span><span class="p p-Indicator">[</span><span class="s">'os_family'</span><span class="p p-Indicator">]</span> <span class="nv">== 'RedHat' %</span><span class="p p-Indicator">}</span>
<span class="p p-Indicator">-</span> <span class="nt">name …</span></code></pre></div><h1>Salt States</h1>
<p><a href="https://saltproject.io/">SaltStack</a> is a configuration management software like Ansible or Puppet which allows you to configure your machines via so-called salt states. Salt states are YAML documents with support for Jinja2 templates: </p>
<div class="highlight"><pre><span></span><code><span class="nt">mysql</span><span class="p">:</span>
<span class="nt">pkg.installed</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
<span class="nt">service.running</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">mysql</span>
<span class="nt">web_server</span><span class="p">:</span>
<span class="nt">pkg.installed</span><span class="p">:</span>
<span class="p p-Indicator">{</span><span class="err">%</span> <span class="nv">if grains</span><span class="p p-Indicator">[</span><span class="s">'os_family'</span><span class="p p-Indicator">]</span> <span class="nv">== 'RedHat' %</span><span class="p p-Indicator">}</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">httpd</span>
<span class="p p-Indicator">{</span><span class="err">%</span> <span class="nv">elif grains</span><span class="p p-Indicator">[</span><span class="s">'os_family'</span><span class="p p-Indicator">]</span> <span class="nv">== 'Debian' %</span><span class="p p-Indicator">}</span>
<span class="p p-Indicator">-</span> <span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">apache2</span>
<span class="p p-Indicator">{</span><span class="err">%</span> <span class="nv">endif %</span><span class="p p-Indicator">}</span>
</code></pre></div>
<p>Note that in contrast to Ansible, salt states support Jinja2 templates in arbitrary places. In fact, the Jinja2 templates are first rendered and the resulting document is then fed into the YAML parser.</p>
<h1>What is it all about?</h1>
<p>A language server is a piece of software that speaks a <a href="https://microsoft.github.io/language-server-protocol/">JSON protocol (called the Language Server Protocol, abreviated LSP)</a> to provide text editors with code completion, diagnostics, documentation, etc. There are <a href="https://microsoft.github.io/language-server-protocol/implementors/servers/">several editors and numerous language servers</a> already implementing this protocol.</p>
<p>While already two extensions providing Salt support for VSCode like <a href="https://github.com/korekontrol/vscode-saltstack">the one from korekontrol</a> for syntax hightlighting and <a href="https://github.com/warpnet/vscode-salt-lint">one for linting</a> exist, none leverages LSP for Salt's SLS files.</p>
<p>Since <a href="https://www.suse.com">SUSE</a> provides one week to its employees every now and then to work on any project they like, both <a href="https://twitter.com/defolosdc">Dan Čermák</a> and I decided to give it a try during <a href="https://hackweek.suse.com/20/projects/language-server-protocol-implementation-for-salt-states">hackweek #20</a>.</p>
<h1>The hackweek outcome</h1>
<p>The code of the started server can be found in <a href="https://github.com/dcermak/salt-lsp">Dan's github repo</a>.
After a week of coding the server provides:</p>
<ul>
<li>Completion of salt state names with their doc extracted using the <a href="https://docs.saltproject.io/en/latest/ref/modules/all/salt.modules.baredoc.html">baredoc module</a>.</li>
</ul>
<p><img alt="completion of state name" src="https://bosdonnat.fr/data/salt/completion-state.png"></p>
<ul>
<li>Completion of include paths</li>
</ul>
<p><img alt="completion of include path" src="https://bosdonnat.fr/data/salt/completion-include.png"></p>
<ul>
<li>Go to definition for identifiers in requisites.</li>
</ul>
<p><img alt="Go to definition" src="https://bosdonnat.fr/data/salt/goto-definition.gif"></p>
<p>In order to provide an accurate completion, the SLS file content is parsed using a home-brewed parser based on the <a href="https://pyyaml.org/wiki/PyYAMLDocumentation#tokens">PyYAML scanner</a>.
This parser creates an abstract syntax tree (AST) that makes it easy to know the context of the SLS files currently being edited.</p>
<p>What originally motivated us to write a parser was that the existing YAML parsers were not fault tolerant enough... and when writing an SLS file there are often states where the file is not yet a valid YAML file!</p>
<p>The AST will also help to provide other features like syntax highlighting or symbol details.</p>
<p>Note that so far only SLS file with a more or less valid YAML content are supported.
This means that SLS files containing Jinja blocks or maybe even jinja <code>{{ }}</code> content will not be parsed properly.</p>
<h1>What next?</h1>
<p>Since neither Dan no I have dedicated time to contribute to this new language server, it will only progress slowly...</p>
<p>That being said we would welcome any pull request!</p>
<p>Among the main big challenges and features:</p>
<ul>
<li>Parse files with Jinja2 templates</li>
<li>Enhance completion, for instance on state names or parameters</li>
<li>Implement syntax highlighting</li>
<li>Dan is currently adding support for <a href="https://github.com/dcermak/salt-lsp/pull/2">document symbols</a>. These allow an editor to render <a href="https://code.visualstudio.com/Docs/editor/editingevolved#_breadcrumbs">breadcrumbs</a></li>
</ul>Virt-bootstrap 1.0.0 released2017-09-08T09:24:00+02:002017-09-08T09:24:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2017-09-08:/virt-bootstrap-100.html<p>Yesterday, <a href="https://github.com/virt-manager/virt-bootstrap">virt-bootstrap</a> came to life. This tool aims at
simplifying the creation of root file systems for use with libvirt's
LXC container drivers. I started prototyping it a few months ago and
<strong>Radostin Stoyanov</strong> wonderfully took it over during this year's
<a href="https://www.redhat.com/archives/virt-tools-list/2017-August/msg00248.html">Google Summer of Code</a>.</p>
<p>For most users, this tool …</p><p>Yesterday, <a href="https://github.com/virt-manager/virt-bootstrap">virt-bootstrap</a> came to life. This tool aims at
simplifying the creation of root file systems for use with libvirt's
LXC container drivers. I started prototyping it a few months ago and
<strong>Radostin Stoyanov</strong> wonderfully took it over during this year's
<a href="https://www.redhat.com/archives/virt-tools-list/2017-August/msg00248.html">Google Summer of Code</a>.</p>
<p>For most users, this tool will just be used by <a href="https://virt-manager.org/">virt-manager</a>
(since version 1.4.2). But it can be used directly from any script or
command line.</p>
<p>The nice thing about virt-bootstrap is that will allow you to create
a root file system out of existing docker images, tarballs or <a href="http://libguestfs.org/virt-builder.1.html">virt-builder</a>
templates. For example, the following command will get and unpack the official
openSUSE docker image in <code>/tmp/foo</code>.</p>
<div class="highlight"><pre><span></span><code><span class="gp">$</span> virt-bootstrap docker://opensuse /tmp/foo
</code></pre></div>
<p>Virt-bootstrap offers options to:</p>
<ul>
<li>generate qcow2 image with backing chain instead of plain folder</li>
<li>apply user / group ID mapping</li>
<li>set the root password in the container</li>
</ul>
<p>Enjoy easy containers creation with libvirt ecosystem, and have fun!</p>System container images2017-03-08T16:37:00+01:002017-03-08T16:37:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2017-03-08:/system-container-images.html<p>As of today creating libvirt lxc system container root file system is a pain.
Docker's fun came with its image sharing idea... why couldn't we do the same
for libvirt containers? I will expose here is an attempt at this.</p>
<p>To achieve such a goal we need:</p>
<ul>
<li>container images</li>
<li>something …</li></ul><p>As of today creating libvirt lxc system container root file system is a pain.
Docker's fun came with its image sharing idea... why couldn't we do the same
for libvirt containers? I will expose here is an attempt at this.</p>
<p>To achieve such a goal we need:</p>
<ul>
<li>container images</li>
<li>something to share them</li>
<li>a tool to pull and use them</li>
</ul>
<h2>Container images</h2>
<p><a href="http://openbuildservice.org/">OpenBuildService</a> thanks to <a href="https://opensuse.github.io/kiwi/">kiwi</a> knows how to create images,
even container images. There even are <a href="https://build.opensuse.org/project/subprojects/Virtualization:containers:images">openSUSE Docker images</a>.
To use them as system container images, some more packages need to be added
to those. I thus forked the project on github and branched the OBS projects
to get system container images for <a href="http://download.opensuse.org/repositories/home:/cbosdonnat:/branches:/Virtualization:/containers:/images:/openSUSE-42.1/images/">42.1</a>, <a href="http://download.opensuse.org/repositories/home:/cbosdonnat:/branches:/Virtualization:/containers:/images:/openSUSE-42.2/images/">42.2</a> and <a href="http://download.opensuse.org/repositories/home:/cbosdonnat:/branches:/Virtualization:/containers:/images:/openSUSE-Tumbleweed/images/">Tumbleweed</a>.</p>
<p>Using them is as simple as downloading them, unpacking them and use them as a
container's root file system. However, sharing them would be so fun!</p>
<h2>Sharing images</h2>
<p>There is no need to reinvent the wheel to share the images. We can just
consider them like any docker image. With the following commands we can
import the image and push it to a remote registry.</p>
<div class="highlight"><pre><span></span><code>docker import openSUSE-42.2-syscontainer-guest-docker.x86_64.tar.xz system/opensuse-42.2
docker tag system/opensuse-42.2 myregistry:5000/system/opensuse-42.2
docker login myregistry:5000
docker push myregistry:5000/system/opensuse-42.2
</code></pre></div>
<p>The good thing with this is that we can even use the <code>docker build</code> and
<code>Dockerfile</code> magic to create customized images and push them to the remote
repository.</p>
<h2>Instanciating containers</h2>
<p>Now we need a tool to get the images from the remote docker registry. Hopefully
there is a tool that helps a lot to do this: <a href="https://github.com/projectatomic/skopeo">skopeo</a>. I wrote a small
<a href="https://github.com/cbosdo/virt-bootstrap">virt-bootstrap</a> tool using it to instanciate the images as
root file systems.</p>
<p>Here is how instanciating a container looks like with it:</p>
<div class="highlight"><pre><span></span><code>virt-bootstrap.py --username myuser <span class="se">\</span>
--root-password <span class="nb">test</span> <span class="se">\</span>
docker://myregistry:5000/system/opensuse-42.2 /path/to/my/container
virt-install --connect lxc:/// -n <span class="m">422</span> --memory <span class="m">250</span> --vcpus <span class="m">1</span> <span class="se">\</span>
--filesystem /path/to/my/container,/ <span class="se">\</span>
--filesystem /etc/resolv.conf,/etc/resolv.conf <span class="se">\</span>
--network <span class="nv">network</span><span class="o">=</span>default
</code></pre></div>
<p>And voila! Creating an openSUSE 42.2 system container and running it with libvirt
is now super easy!</p>SLES, Raspberry PI and GPIO2017-02-28T11:22:00+01:002017-02-28T11:22:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2017-02-28:/sles-rpi-gpio.html<p><a href="https://hackweek.suse.com">SUSE Hackweek 15</a> just finished. This time I wanted to come up
with a tool and hardware to control my window shutters. The good thing is
that they are already motorized and have wired command. Thus I could
easily hack a GPIO-based solution.</p>
<p>Obviously I bought some hardware in advance …</p><p><a href="https://hackweek.suse.com">SUSE Hackweek 15</a> just finished. This time I wanted to come up
with a tool and hardware to control my window shutters. The good thing is
that they are already motorized and have wired command. Thus I could
easily hack a GPIO-based solution.</p>
<p>Obviously I bought some hardware in advance to have it on time: I mostly
needed a relay board. I chose the <a href="http://www.sainsmart.com/16-channel-12v-relay-module-for-pic-arm-avr-dsp-arduino-msp430-ttl-logic.html">16 modules one from Sainsmart</a>,
with a 12V 2A power supply for it. I could be argued that 16 relays is way
too much to handle one shutter motor, but I need two relays for it (one for
each direction) and my final goal is to control 8 window shutters.</p>
<p>To add some salt to this hackweek, I deciced to run a
<a href="https://www.suse.com/products/arm/raspberry-pi/">SLES 12 SP2 for Raspberry Pi</a> on my Raspberry Pi 3.
The fact is that none of the GPIO library was working on SLES as they were
expecting some rasbian-specific things.</p>
<p>Thus this hackweek was a nice opportunity to get <a href="https://sourceforge.net/p/raspberry-gpio-python/wiki/Home/">RPi.GPIO</a> and
<a href="https://github.com/intel-iot-devkit/mraa/">mraa</a> to work on SLES. The patches are pending upstream review
<a href="https://sourceforge.net/p/raspberry-gpio-python/tickets/149/">here</a>, <a href="https://sourceforge.net/p/raspberry-gpio-python/tickets/150/">here</a> and <a href="https://github.com/intel-iot-devkit/mraa/pull/655">here</a>. The patched packages
for openSUSE Tumbleweed and SLES are pending review as well.</p>
<p>Just not to forget the final goal of my hackweek, here are some pictures
of how I hacked the shutter to detect the end positions:</p>
<p><img alt="detector setup" src="https://bosdonnat.fr/data/photos/detector.jpg"></p>
<p><img alt="end detection system" src="https://bosdonnat.fr/data/photos/end_detected.jpg"></p>
<p>The code for the prototype can be found on <a href="https://github.com/cbosdo/shutter">github</a>, but
it's going to change a lot sooner or later. I also had to create a
<a href="http://fritzing.org">fritzing</a> part for the relay board: those in need can find it
<a href="http://forum.fritzing.org/t/sainsmart-16-channels-relay-board/3170">here</a>.</p>Media Center with Raspberry Pi2016-11-16T20:00:00+01:002016-11-16T20:00:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2016-11-16:/rpi-media-center.html<p>I know there are already tons of media center uses of raspberry pi,
so is different with this one? I wanted to replace the old mini CD
player by something I could easily hack. Thus my requirements were:</p>
<ul>
<li>a media center able to read audio CDs and DVDs (I know …</li></ul><p>I know there are already tons of media center uses of raspberry pi,
so is different with this one? I wanted to replace the old mini CD
player by something I could easily hack. Thus my requirements were:</p>
<ul>
<li>a media center able to read audio CDs and DVDs (I know I'm a dinosaur)</li>
<li>easily operated by young kids</li>
</ul>
<p>Thus I came to a solution with a USB DVD drive, a few buttons connected
to GPIO, and a sound amplifier. Finding a nice and rather small box for
all these pieces needed quite some thinking, and I came up with a wooden
box of Port wine.</p>
<h2>Stuffs I needed:</h2>
<ul>
<li>a raspberry pi 2</li>
<li>an audio amp. The <a href="http://www.velleman.eu/products/view/?country=be&lang=en&id=387602">Velleman MK190 kit</a> graciously provided by
<a href="http://www.hadess.net/2015/09/philips-wireless-modernised.html">Bastien</a> does work, just needs 12V power</li>
<li>a power adapter producing 12V and 5V. I got one from an old hard drive
external case.</li>
<li>an USB DVD drive, just had to care about power and noise to choose it</li>
<li>an HDMI extension cable</li>
<li>an ethernet extension cable</li>
<li>a remote control: I chose the MX3 air mouse</li>
<li>various cables</li>
<li>spare push buttons and soldering tools</li>
<li>a sound plug (taken from the old CD player device)</li>
</ul>
<h2>Putting it together</h2>
<p>I cut the buttons in some pine board I had, and to get them bump back
to their original position after being pushed I used the plastic thing
used for keyboard keys. Here is how it looks like: </p>
<p><img alt="Front of the buttons piece" src="https://bosdonnat.fr/data/rpi-player/buttons.jpg"></p>
<p>The circuit for the GPIO is rather simple, just that I needed four buttons.
The board is then fixed on the buttons holder medium board. See the
assembled result here:</p>
<p><img alt="Assembled buttons circuitry" src="https://bosdonnat.fr/data/rpi-player/buttons_back.jpg"></p>
<p>Then I had to carve the wood with chisels to get the wholes for the
buttons, the DVD tray and various outputs (HDMI, ethernet, audio).</p>
<p>The volume button from the MK190 kit couldn't fit in the whole setup, thus I
had to make one with some old round pieces of wood (a chair foot typically).</p>
<p>A few nails are maintaining the DVD player in place to avoid it to slide
when inserting a disk in it. I also screwed the buttons board and then wired
it all. Here is the whole thing from various angles:</p>
<p>Inside:</p>
<p><img alt="Inside view" src="https://bosdonnat.fr/data/rpi-player/inside.jpg"></p>
<p>Front (you will see that I still haven't painted anything on the buttons):</p>
<p><img alt="Front side" src="https://bosdonnat.fr/data/rpi-player/front.jpg"></p>
<p>Back:</p>
<p><img alt="Back side" src="https://bosdonnat.fr/data/rpi-player/back.jpg"></p>
<h2>Software</h2>
<p>For the media center it was rather clear to me that I'll use <a href="https://kodi.tv">Kodi</a>, I just
had to decide for the distro. I chose OSMC for the while rather than minimal
ones like <a href="https://libreelec.tv/">LibreElec</a> or <a href="http://openelec.tv/">OpenElec</a> as it is easier to hack the software
on it without having to rebuild it all.</p>
<p>I hit a few problems with Kodi:</p>
<ul>
<li>auto playing audio CDs and DVDs wasn't that straight forward, I had to write
a small udev rule for it</li>
<li>Some audio CDs aren't playing with Kodi's native player. I had to setup
<a href="http://www.videolan.org/">VLC</a> as an external player. I know it's rather hacky, but at least it
works for the time beeing</li>
</ul>
<p>And of course I had to write some python code for the GPIO buttons. It's so
ugly at the moment, that I won't release it as is... and I still hope to be
able to fix that libcdio usage bug to get rid of the external player.</p>
<p>After some time using it, I also discovered that I need to add a power switch
to gracefully turn the raspberry pi on or off. So the project is not yet
finished.</p>
<p><strong>EDIT: </strong> I purchased a <a href="http://www.mausberrycircuits.com/collections/frontpage/products/shutdown-circuit-use-your-own-switch">Mausberry USB port use-your-own-switch shutdown
circuit</a>. At least the whole system can now be turned off easily.</p>LibreOffice GSoC 2015 wrap-up2015-10-19T10:00:00+02:002015-10-19T10:00:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2015-10-19:/gsoc-2015-wrap-up.html<p>This year, I'll manage to write a wrap up post on the Google Summer of Code at
LibreOffice. On the 12 students initially selected, 10 hacked on cool things
for our favorite office suite.</p>
<p>The completed projects are:</p>
<ul>
<li>Haskell UNO Language Binding from <strong>Jorge Mendes</strong></li>
</ul>
<p>LibreOffice's Universal Network Objects (UNO …</p><p>This year, I'll manage to write a wrap up post on the Google Summer of Code at
LibreOffice. On the 12 students initially selected, 10 hacked on cool things
for our favorite office suite.</p>
<p>The completed projects are:</p>
<ul>
<li>Haskell UNO Language Binding from <strong>Jorge Mendes</strong></li>
</ul>
<p>LibreOffice's Universal Network Objects (UNO) API, can already be accessed by
C/C++, Java, and Python, among other languages/frameworks. Jorge wrote the glue
code for UNO to be used from Haskell code.</p>
<p>Two main artefacts were defined: a code generator to provide an interface to
the UNO API at compile time, and a library to provide access to essential
information, like basic type mapping between UNO and Haskell. The former is
provided as an executable, run during the developed program configuration phase,
and the latter is provided as a Cabal package <code>hs-uno</code>, as most Haskell
software is.</p>
<p>The result of this project provides a simple way to develop software for the
LibreOffice ecosystem using Haskell, and includes some examples on how to use
this binding. See the code on <a href="https://github.com/jorgecunhamendes/haskell-uno-binding">github</a></p>
<p><img alt="Haskell code using UNO API" src="https://bosdonnat.fr/data/libreoffice/gsoc15-jorge.png"></p>
<ul>
<li>Calc formula error checking from <strong>Ben Ni</strong></li>
</ul>
<p>Ben worked on the validity check feature to get hands on the code. Then he
implemented checking for discontinuous formula groups as well as expanding the
formula wizard to evaluate subformulas to allow for easier error checking.
He also started collaborating with <a href="http://erack.org/blog/">Eike</a> on the unit feature currently
under development, to move unit evaluation to <code>ScInterpreter</code>.</p>
<p><img alt="Imput values in formula editor" src="https://lh3.googleusercontent.com/-KocSOlNE_m4/VZg5hLdzE2I/AAAAAAAAA64/f1CRYiKeFD8/w887-h873-no/wizard.png"></p>
<ul>
<li>Unifiying Calc units from <strong>Krisztian Pinter</strong></li>
</ul>
<p>Krisztian worked on unifying the internal drawing units in Calc to make the
code easier to work with in the future.</p>
<ul>
<li>CMIS user experience improvements from <strong><a href="http://eszkadev.blogspot.com/">Szymon Kłos</a></strong></li>
</ul>
<p>The CMIS features was pretty well hidden so far. Szymon worked together with
the UX team to make it easier to use. A new dialog for opening remote files
was created and can be accessed from the Start Center. It helps the user to
explore popular services like Google Drive, OneDrive, Alfresco or FTP servers.
User can configure many of them and simply switch current service using
dropdown menu. It is also possible to remember authorization data for each
service.</p>
<p>Szymon also fixed a few CMIS bugs, including the most annoying bug where the
password was always stored, even if it was wrong. Several users can now access
the same repository in one session.</p>
<p><img alt="New remote file picker" src="https://bosdonnat.fr/data/libreoffice/gsoc15-szymon.png"></p>
<ul>
<li>Mozilla update system for LibreOffice from <strong>Nathan Yi</strong></li>
</ul>
<p>Although Nathan did not have time to fully implement the UI and server-side backend
components of the project, he managed to do in-place upgrades of LibreOffice using
full and partial (version-to-version) patches. These patches can optionally be
signed for secure transport over the Internet.</p>
<p><img alt="Update done with Nathan's work" src="https://bosdonnat.fr/data/libreoffice/gsoc15-nathan.png"></p>
<ul>
<li>LibreOffice GTK3 widget from <strong><a href="http://pranavk.github.io/">Pranav Kant</a></strong></li>
</ul>
<p>Want to use LibreOffice in your applications ? Yes, its quite possible now with
the help of a gtk3 widget, LOKDocView, that Pranav worked on this summer. The widget
wraps all the LibreOffice functionality and exposes a very simple API to
interact with it. Consumer applications just need to embed this widget inside a
scroll bar, and that's it. Further, user experience can be enhanced thanks to
the API allowing simple text formatting or zooming of the opened document.
Those can also be opened in both view and edit mode.</p>
<p>The special thing about this widget is that you can use it from any programming
language, and this is possible using GObject Introspection. You can see the
widget being used from GNOME Documents using GObject Introspection's javascript
bindings in below screencast.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/bxh4k0rFMc0" frameborder="0" allowfullscreen></iframe>
<p>LOKDocView, and the necessary introspection files will be shipped with 5.1.</p>
<ul>
<li>Tests improvement from <strong>Varun Dhall</strong></li>
</ul>
<p>Varun added more easy-to-debug unit tests through CppUnit. He have also ported
some old Java unit tests to C++ and re-factored some tests that do remote control
of an existing instance. His goal was to improve the LibreOffice test coverage
to reduce the number of regression bugs. Of course there is still room for
future development in this project.</p>
<ul>
<li>Sidebar improvements from <strong>Rishabh Kumar</strong></li>
</ul>
<p>Rishabh has been improving the user interface of sidebar and its functionalities.
The major part of the project included adding some of most commonly used controls
to the sidebar. The project had impacts to Writer, Calc, Impress and Draw.
Rishabh changed quite a lot of things in the sidebar, but among the most
important ones, he added a few tabs, like the slide background or page tab ones.
He also improved the selection analizer to show only the tabs related to the
current selection, e.g. showing the area tab when a line is selected didn't make
sense.</p>
<p><img alt="New page sidebar tab" src="https://bosdonnat.fr/data/libreoffice/gsoc15-rishabh.png"></p>
<ul>
<li>Expert configuration improvements from <strong>Mihaly Palenik</strong></li>
</ul>
<p>The main part of the project was to convert the dialog from a fixed
tree filled at load time from all options, which was incredibly slow
and unusable with accessibility enabled, to a tree which was progressively and
dynamically loaded when the user expanded a level or searched for
certain keys.</p>
<p>That was a great success in the sense that the dialog now opens and
displays entries almost immediately, while previous to the changes it
could take up to 8 minutes to load with accessibility enabled.</p>
<p><img alt="Search and edit a configuration key" src="https://bosdonnat.fr/data/libreoffice/gsoc15-mihaly.png"></p>
<ul>
<li>Dynamic text chaining and hyphenation in Draw from <strong><a href="http://gsoc15-draw.logdown.com/">Matteo Campanelli</a></strong></li>
</ul>
<p>Matteo continued working on the text chaining implementation for Draw. This year,
he add support for text transfer while editing or resizing the boxes, cursor motion,
box chain persistence in file and text underflow handling.</p>
<p><img alt="Text flow comparison in draw" src="https://bosdonnat.fr/data/libreoffice/gsoc15-matteo.png"></p>Easy sandboxed apps2015-08-25T09:54:00+02:002015-08-25T09:54:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2015-08-25:/easy-sandboxed-apps.html<p>These days, I wanted to build some SUSE documentation, but <a href="http://opensuse.github.io/daps/">daps</a> drags quite a
few dependencies. Thus I decided to use that occasion to move it to a sandbox.
The idea is very similar to what was detailled in my post on <a href="https://bosdonnat.fr/libvirt-container-for-guiapps.html">containers for
GUI apps</a>, but will be made …</p><p>These days, I wanted to build some SUSE documentation, but <a href="http://opensuse.github.io/daps/">daps</a> drags quite a
few dependencies. Thus I decided to use that occasion to move it to a sandbox.
The idea is very similar to what was detailled in my post on <a href="https://bosdonnat.fr/libvirt-container-for-guiapps.html">containers for
GUI apps</a>, but will be made much easier thanks to the recent progresses
in <a href="http://sandbox.libvirt.org">virt-sandbox</a>.</p>
<p><strong>Note that this is only possible with recent virt-sandbox. To make sure you
have virt-sandbox with all features, install it from the <a href="https://software.opensuse.org/ymp/Virtualization/openSUSE_13.2/virt-sandbox.ymp?base=openSUSE%3A13.2&query=virt-sandbox">OBS Virtualization
repository</a>.</strong></p>
<h2>Creating the disk image</h2>
<p>Most of this part will be simplified, as I reused the <code>test-base.qcow2</code> image
created in the <a href="https://bosdonnat.fr/libvirt-container-for-guiapps.html">previous post</a>. I only added it a non-root user. Doing this
is pretty straight forward thanks to qemu-img's commit feature.</p>
<p>First create a working overlay image based on <code>test-base.qcow2</code>:</p>
<div class="highlight"><pre><span></span><code><span class="err">qemu-img create -f qcow2 \</span>
<span class="err"> -o backing_file=$PWD/test-base.qcow2 \</span>
<span class="err"> daps.qcow2</span>
</code></pre></div>
<p>As a non-privileged user, boot a sandbox running this disk image:</p>
<div class="highlight"><pre><span></span><code><span class="err">virt-sandbox -n daps \</span>
<span class="err"> --privileged \</span>
<span class="err"> -m host-image:/=$PWD/daps.qcow2,format=qcow2 \</span>
<span class="err"> -- \</span>
<span class="err"> /bin/sh</span>
</code></pre></div>
<p>Note that the <code>--privileged</code> parameter keeps you as root in the sandbox.
Otherwise you would be logged in as a user with the same UID as the one you ran
<code>virt-sandbox</code> with. You can do the changes you need in the base image. In our
case, I will add an unprivileged user.</p>
<div class="highlight"><pre><span></span><code><span class="err">useradd -m myuser</span>
</code></pre></div>
<p>As we want this change to propagate to the base image, please refrain from
installing <code>daps</code> or doing other things that you don't want to see in the base
image. Exit the shell to exit the sandbox and get back to your host command.</p>
<p>In order to have working network later in the sandboxes, we have to install
<code>util-linux-systemd</code> and <code>dhcp-client</code> as it wasn't done in when creating the
base image. For this we need to switch to root and mount the image with
<code>libguestfs tools</code> since zypper can't get any network so far.</p>
<div class="highlight"><pre><span></span><code><span class="err">sudo guestmount -a $PWD/daps.qcow2 -m /dev/sda:/ /mnt</span>
<span class="err">sudo zypper --root /mnt in dhcp-client util-linux-systemd</span>
<span class="err">sudo guestunmount /mnt</span>
</code></pre></div>
<p>We will now commit all the changes made in our overlay image to the base image:</p>
<div class="highlight"><pre><span></span><code><span class="err">qemu-img commit $PWD/daps.qcow2</span>
</code></pre></div>
<p>Note that you may have to get permissions to write on <code>test-base.qcow2</code> as we
created it as root in the previous post.</p>
<p>Now, we only have to install <code>daps</code> in our now-empty overlay image. To do so,
run the following command:</p>
<div class="highlight"><pre><span></span><code><span class="err">virt-sandbox -n daps \</span>
<span class="err"> --privileged \</span>
<span class="err"> -m host-image:/=$PWD/daps.qcow2,format=qcow2 \</span>
<span class="err"> -N dhcp \</span>
<span class="err"> -- \</span>
<span class="err"> /bin/sh</span>
</code></pre></div>
<p>Note the <code>-N dhcp</code> argument that will now run <code>dhclient</code> and will provide you
network in the sandbox. This network is limited, since it is user networking.
For more details on it, report to <a href="http://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29">this page</a>.</p>
<p>In the sandbox, we can now install <code>daps</code> normally:</p>
<div class="highlight"><pre><span></span><code><span class="err">zypper ar http://download.opensuse.org/repositories/Documentation:/Tools/openSUSE_13.2/Documentation:Tools.repo</span>
<span class="err">zypper in daps</span>
</code></pre></div>
<p>Exit the shell to end the sandbox: your disk image is ready.</p>
<h2>Running daps</h2>
<p>In order to have a smooth user experience with daps, better create a script to
run virt-sandbox for you. Create executable <code>~/bin/daps</code> with content similar to
this one:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="highlight"><pre><span></span><code><span class="ch">#!/bin/sh</span>
virt-sandbox <span class="se">\</span>
-n daps <span class="se">\</span>
-m host-image:/<span class="o">=</span>/path/to/daps.qcow2,format<span class="o">=</span>qcow2 <span class="se">\</span>
-m host-bind:/home/myuser<span class="o">=</span>/home/myuser <span class="se">\</span>
-m ram:/tmp<span class="o">=</span>100MiB <span class="se">\</span>
-m ram:/run<span class="o">=</span>100MiB <span class="se">\</span>
-- <span class="se">\</span>
/usr/bin/daps <span class="nv">$@</span>
</code></pre></div>
</td></tr></table>
<p>You can add options to mount your host folders in your sandbox. For example,
this will mount <code>/home/myuser</code> at the same place in the sandbox:</p>
<div class="highlight"><pre><span></span><code><span class="err">-m host-bind:/home/myuser=/home/myuser</span>
</code></pre></div>
<p>Make sure that your documentation sources will be mounted in the sandbox.</p>
<p>When running the <code>daps</code> command on your machine, you will run the daps command
within a super tiny KVM machine running with your UID. Note that I didn't add
the <code>-N dhcp</code> option in the script since daps doesn't need it, but you may need
it for other applications or to update your packages.</p>Libvirt container for GUI apps2015-05-06T10:13:00+02:002015-05-06T10:13:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2015-05-06:/libvirt-container-for-guiapps.html<p>I recently tried to get the <a href="https://en.opensuse.org/openSUSE:Openfate">openFATE</a> client working in a container. I know
it may sound stupid, but I didn't want to pollute my Gnome machine with KDE
libraries (end of troll) and wanted to use this to seriously play with
application containers. My constraints were:</p>
<ul>
<li>minimize the duplication …</li></ul><p>I recently tried to get the <a href="https://en.opensuse.org/openSUSE:Openfate">openFATE</a> client working in a container. I know
it may sound stupid, but I didn't want to pollute my Gnome machine with KDE
libraries (end of troll) and wanted to use this to seriously play with
application containers. My constraints were:</p>
<ul>
<li>minimize the duplication of the root file system. I know docker already does
this, but I'm a libvirt hacker after all.</li>
<li>get the application show up on the host display for a smooth use.</li>
</ul>
<h2>Creating the root file system</h2>
<p>To minimze the file system duplication, I went with a qcow2 disk image with a
backing file. The first step is to create the base image with the file system to be
reused by other containers.</p>
<p>Create the disk image:</p>
<div class="highlight"><pre><span></span><code><span class="err">qemu-img create -f qcow2 test-base.qcow2 15G</span>
</code></pre></div>
<p>Create the nbd device from the disk image, format it and mount it. Depending on
your linux distribution you may even need to load the nbd kernel module, hence
the first line.</p>
<div class="highlight"><pre><span></span><code><span class="err">modprobe nbd</span>
<span class="err">/usr/bin/qemu-nbd --format qcow2 -n -c /dev/nbd0 $PWD/test-base.qcow2</span>
<span class="err">mkfs.ext3 /dev/nbd0</span>
<span class="err">mount /dev/nbd0 /mnt</span>
</code></pre></div>
<p>Populate the image with the openSUSE 13.2 Minimal_base pattern:</p>
<div class="highlight"><pre><span></span><code><span class="err">zypper --root /mnt ar http://download.opensuse.org/distribution/13.2/repo/oss/ main</span>
<span class="err">zypper --root /mnt ar http://download.opensuse.org/update/13.2/ updates</span>
<span class="err">zypper --root /mnt in -t pattern Minimal_base</span>
</code></pre></div>
<p>Unmount and clean up the nbd device:</p>
<div class="highlight"><pre><span></span><code><span class="err">umount /mnt</span>
<span class="err">pkill qemu-nbd</span>
</code></pre></div>
<p>Now, we will create an overlay image on top of the one we just created. In this
image, we will only install fate, and create an unprivileged user to run it.</p>
<p>Create the image. Note the <code>backing_file</code> and <code>backing_fmt</code> options as they
will actually setup the backing chain of qcow2 images.</p>
<div class="highlight"><pre><span></span><code><span class="err">qemu-img create -f qcow2 \</span>
<span class="err"> -o backing_fmt=qcow2,backing_file=$PWD/test-base.qcow2 \</span>
<span class="err"> myapp.qcow2</span>
</code></pre></div>
<p>Mount the new image via <code>qemu-nbd</code> again. Note that there is no need to format
that new image: it is really only a diff with the <code>test-base.qcow2</code> file.</p>
<div class="highlight"><pre><span></span><code><span class="err">/usr/bin/qemu-nbd --format qcow2 -n -c /dev/nbd0 $PWD/myapp.qcow2</span>
<span class="err">mount /dev/nbd0 /mnt</span>
</code></pre></div>
<p>Install the application (fate in this example):</p>
<div class="highlight"><pre><span></span><code><span class="err">zypper --root /mnt ar http://download.opensuse.org/repositories/FATE/openSUSE_13.2/ FATE</span>
<span class="err">zypper --root /mnt in fate</span>
</code></pre></div>
<p>Add an unprivileged user:</p>
<div class="highlight"><pre><span></span><code><span class="err">useradd -m myuser</span>
</code></pre></div>
<p>For the application to find the X server display, set the DISPLAY in the user's
profile. The <code>localhost:0</code> value here can be adjusted depending on the network
settings of the container. In this case, I will use a container without the
netns namespace to simplify, but with the default libvirt network the value
would be <code>192.168.122.1:0</code>.</p>
<div class="highlight"><pre><span></span><code><span class="err">echo 'export DISPLAY=localhost:0' > ~myuser/.profile</span>
</code></pre></div>
<p>Unmount and clean up the nbd device:</p>
<div class="highlight"><pre><span></span><code><span class="err">umount /mnt</span>
<span class="err">pkill qemu-nbd</span>
</code></pre></div>
<h2>Setting up the container</h2>
<p>Sadly, there is no other possible way to create the container than by manually
feeding the XML definition to libvirt. Here is a template for the definition:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><domain</span> <span class="na">type=</span><span class="s">'lxc'</span><span class="nt">></span>
<span class="nt"><name></span>myapp<span class="nt"></name></span>
<span class="nt"><memory</span> <span class="na">unit=</span><span class="s">'MiB'</span><span class="nt">></span>256<span class="nt"></memory></span>
<span class="nt"><vcpu</span> <span class="na">placement=</span><span class="s">'static'</span><span class="nt">></span>1<span class="nt"></vcpu></span>
<span class="nt"><resource></span>
<span class="nt"><partition></span>/machine<span class="nt"></partition></span>
<span class="nt"></resource></span>
<span class="nt"><os></span>
<span class="nt"><type</span> <span class="na">arch=</span><span class="s">'x86_64'</span><span class="nt">></span>exe<span class="nt"></type></span>
<span class="nt"><init></span>/usr/bin/su<span class="nt"></init></span>
<span class="nt"><initarg></span>-<span class="nt"></initarg></span>
<span class="nt"><initarg></span>myuser<span class="nt"></initarg></span>
<span class="nt"><initarg></span>-c<span class="nt"></initarg></span>
<span class="nt"><initarg></span>/usr/bin/fate<span class="nt"></initarg></span>
<span class="nt"></os></span>
<span class="nt"><clock</span> <span class="na">offset=</span><span class="s">'utc'</span><span class="nt">/></span>
<span class="nt"><on_poweroff></span>destroy<span class="nt"></on_poweroff></span>
<span class="nt"><on_reboot></span>restart<span class="nt"></on_reboot></span>
<span class="nt"><on_crash></span>destroy<span class="nt"></on_crash></span>
<span class="nt"><devices></span>
<span class="nt"><controller</span> <span class="na">type=</span><span class="s">'ide'</span> <span class="na">index=</span><span class="s">'0'</span><span class="nt">/></span>
<span class="nt"><filesystem</span> <span class="na">type=</span><span class="s">'file'</span><span class="nt">></span>
<span class="nt"><driver</span> <span class="na">type=</span><span class="s">'nbd'</span> <span class="na">format=</span><span class="s">'qcow2'</span><span class="nt">/></span>
<span class="nt"><source</span> <span class="na">file=</span><span class="s">'/path/to/myapp.qcow2'</span><span class="nt">/></span>
<span class="nt"><target</span> <span class="na">dir=</span><span class="s">'/'</span><span class="nt">/></span>
<span class="nt"></filesystem></span>
<span class="nt"><filesystem</span> <span class="na">type=</span><span class="s">'mount'</span><span class="nt">></span>
<span class="nt"><source</span> <span class="na">dir=</span><span class="s">'/home/myuser/.Xauthority'</span><span class="nt">/></span>
<span class="nt"><target</span> <span class="na">dir=</span><span class="s">'/home/myuser/.Xauthority'</span><span class="nt">/></span>
<span class="nt"></filesystem></span>
<span class="nt"><filesystem</span> <span class="na">type=</span><span class="s">'ram'</span><span class="nt">></span>
<span class="nt"><source</span> <span class="na">usage=</span><span class="s">'10240'</span> <span class="na">units=</span><span class="s">'KiB'</span><span class="nt">/></span>
<span class="nt"><target</span> <span class="na">dir=</span><span class="s">'/run'</span><span class="nt">/></span>
<span class="nt"></filesystem></span>
<span class="nt"><filesystem</span> <span class="na">type=</span><span class="s">'ram'</span><span class="nt">></span>
<span class="nt"><source</span> <span class="na">usage=</span><span class="s">'102400'</span> <span class="na">units=</span><span class="s">'KiB'</span><span class="nt">/></span>
<span class="nt"><target</span> <span class="na">dir=</span><span class="s">'/tmp'</span><span class="nt">/></span>
<span class="nt"></filesystem></span>
<span class="nt"><console</span> <span class="na">type=</span><span class="s">'pty'</span><span class="nt">/></span>
<span class="nt"></devices></span>
<span class="nt"><seclabel</span> <span class="na">type=</span><span class="s">'dynamic'</span> <span class="na">model=</span><span class="s">'apparmor'</span> <span class="na">relabel=</span><span class="s">'yes'</span><span class="nt">/></span>
<span class="nt"></domain></span>
</code></pre></div>
<p>In this template, the memory, vcpu and paths to images need to be adapted to
your setup. Note that the qcow2 image is mounted in the container using the
filesystem nbd driver.</p>
<p>The host user's .Xauthority file is mounted in the container's user home. This
is needed for the X applications to connect to the host display.</p>
<p>For the application to be automatically launched as the unprivileged user, the
definition init command is set to</p>
<div class="highlight"><pre><span></span><code><span class="err">/usr/bin/su - myuser -c /usr/bin/fate</span>
</code></pre></div>
<h2>Running the application</h2>
<p>Before being able to connect to the host Xorg server, we need to have it listen
for TCP connection. In openSUSE, this can be achieved by changing
<code>DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN</code> to <code>yes</code> in
<code>/etc/sysconfig/displaymanager</code>.</p>
<p>The application needs to be able to authenticate on the host Xorg server. For
my tests I manually crafted the .Xauthority using xauth. Just remember that
the cookie will change, so either regenerate it before each start or mount
<code>$XAUTHORITY</code> directly to the container's <code>.Xauthority</code>.</p>
<div class="highlight"><pre><span></span><code><span class="err">xauth extract - $DISPLAY | xauth -f $HOME/.Xauthority merge -</span>
</code></pre></div>
<p>Running the application is as easy as starting the container:</p>
<div class="highlight"><pre><span></span><code><span class="err">virsh -c lxc:/// start --console myapp</span>
</code></pre></div>
<p>Of course it would be much more convenient to have it wrapped in a script with
proper sudo configuration to let normal users run the container without needing
to become root.</p>
<h2>Limitations</h2>
<p>This approach is still pretty complex and not that easy for newcomers.</p>
<ul>
<li>The image creation process will be simplified as part of
<a href="http://qemu-project.org/Google_Summer_of_Code_2015#Running_docker_containers_using_virt-sandbox">Google Summer of Code 2015 with libvirt</a>.</li>
<li>The container definition and start could be done with <a href="http://sandbox.libvirt.org/">virt-sandbox</a>, but the
host-image mount parameter should first be able to take qcow2 images.</li>
<li>libvirt doesn't stop the <code>qemu-nbd</code> process when the container is stopped, but
hey, that's a bug I can work on!</li>
</ul>Hackweek 122015-04-17T13:50:00+02:002015-04-17T13:50:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2015-04-17:/hackweek-12.html<p>This week was <a href="https://hackweek.suse.com">hackweek 12</a> at SUSE. I decided to do whatever was needed to get
the <a href="http://openbuildservice.org">open build service (aka OBS)</a> able to create <a href="http://libguestfs.org/virt-builder.1.html">virt-builder</a> images repositories.
OBS is already able to create VM images using kiwi, but it is not able to generate the
signed index file and …</p><p>This week was <a href="https://hackweek.suse.com">hackweek 12</a> at SUSE. I decided to do whatever was needed to get
the <a href="http://openbuildservice.org">open build service (aka OBS)</a> able to create <a href="http://libguestfs.org/virt-builder.1.html">virt-builder</a> images repositories.
OBS is already able to create VM images using kiwi, but it is not able to generate the
signed index file and publish the compressed images.</p>
<p>I owe many thanks to <a href="http://www.adrian-schroeter.de">Adrian</a> for setting me on the right tracks to get this done.
In short, there are two pieces needed to reach the goal:</p>
<ul>
<li>a kiwi hook script running after the kiwi build. How to do this is largely described
in the <a href="https://github.com/openSUSE/containment-rpm/blob/master/README.rst">containment-rpm README</a>.</li>
<li>a patch for the bs_publisher script to create the index from the parts generated for
each image, sign it and publish it together with the compressed images.</li>
</ul>
<p>So far a project is ready in openSUSE's build service in the <a href="https://build.opensuse.org/project/show/home:cbosdonnat:Builder">home:cbosdonnat:Builder</a>
project. It only waits for the <a href="https://github.com/openSUSE/open-build-service/pull/909">PR#909</a> to land on this instance of OBS.</p>
<p>With this, I hope we will soon be able to provide official openSUSE images for our
openSUSE virt-builder users.</p>Hackweek 112014-10-25T18:03:00+02:002014-10-25T18:03:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2014-10-25:/hackweek-11.html<p>Last week was <a href="https://hackweek.suse.com">hackweek 11</a> at SUSE. I chose to work on starting an Android
client application for libvirt. I know there is already something like this on
the Google play, but it's closed source and seems unmaintained... and anyway it
helped me dive in Android NDK and native code …</p><p>Last week was <a href="https://hackweek.suse.com">hackweek 11</a> at SUSE. I chose to work on starting an Android
client application for libvirt. I know there is already something like this on
the Google play, but it's closed source and seems unmaintained... and anyway it
helped me dive in Android NDK and native code building.</p>
<p>As of today, the application can connect to a remote server using libssh2 and list
the domains on it. The good thing is that the hard work to get libvirt.so, JNA
and the Java code running together is solved.</p>
<p>The code can be found on <a href="https://github.com/cbosdo/libvirt-droid">github.com/cbosdo/libvirt-droid</a> even if it still
needs a huge bunch of love!</p>LibreOffice can now reach CMIS servers through HTTPS2014-07-17T22:07:00+02:002014-07-17T22:07:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2014-07-17:/libreoffice-reaches-cmis-https.html<p>LibreOffice CMIS server connection feature suffered a severe disease since the
begining: it was not able to connect to servers using HTTPS. First a workaround
was added for invalid certificates, but the problem also existed for valid ones
as described by <a href="https://bugs.freedesktop.org/show_bug.cgi?id=72277">fdo#72277</a>.</p>
<p>After several months of inactivity, I finally …</p><p>LibreOffice CMIS server connection feature suffered a severe disease since the
begining: it was not able to connect to servers using HTTPS. First a workaround
was added for invalid certificates, but the problem also existed for valid ones
as described by <a href="https://bugs.freedesktop.org/show_bug.cgi?id=72277">fdo#72277</a>.</p>
<p>After several months of inactivity, I finally managed to grab enough courage to
dive into curl and NSS. From 4.3.1, LibreOffice built with internal curl
library, will be able to use the mozilla certificates database to validate CMIS
connections.</p>
<p>For those wanting to know the gore details, LibreOffice internal curl library
is built with NSS support. To read the certificates database, curl needs to
find libnssckbi: so <strong><a href="http://opengrok.libreoffice.org/xref/core/xmlsecurity/source/xmlsec/nss/nssinitializer.cxx#nsscrypto_initialize">NSSInitializer</a></strong> UNO service was here to do that job. But
using that service is not enought: curl doesn't know how to read the PKCS
certificates stored in the database... and needs libnsspem to do that. After
some digging, I uncovered it on <a href="https://git.fedorahosted.org/cgit/nss-pem.git">fedorahosted</a> and added it as a patch to
LibreOffice internal NSS library.</p>
<p>Thanks Caolan and Michael Stahl for pointing me to the right direction to fix
that one.</p>Migrating an LXC container to libvirt lxc2014-07-17T15:41:00+02:002014-07-17T15:41:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2014-07-17:/migrate-lxc-container-to-libvirt.html<p>I am now working on libvirt and the tools gravitating around it for almost a
year and still haven't blogged about anything related to it. As a first post on
virtualization, I'll tell you how to migrate your LXC container to use the
libvirt goodness.</p>
<p>In order to achieve the …</p><p>I am now working on libvirt and the tools gravitating around it for almost a
year and still haven't blogged about anything related to it. As a first post on
virtualization, I'll tell you how to migrate your LXC container to use the
libvirt goodness.</p>
<p>In order to achieve the migration, the host machine needs to be upgraded to
openSUSE 13.1 or later. Quite some of the required features are only in
Factory, so those of you running 13.1 will need to add the Virtualization
repository like this:</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# zypper ar -f http://download.opensuse.org/repositories/Virtualization/openSUSE_13.1/Virtualization.repo</span>
</code></pre></div>
<p>The first thing to do is to install <strong>libvirt-daemon-lxc</strong>, to drag all the
needed packages to run containers on libvirt. Of course, installing
<strong>virt-manager</strong> will also provide you a convenient GUI to handle them.</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# zypper in libvirt-daemon-lxc</span>
</code></pre></div>
<p>The LXC container files are usually living in the <strong>/var/lib/lxc/</strong> folder.
Let's assument for this example, that we have an lxc container named
<strong>mycontainer</strong> to migrate.</p>
<p>To avoid the boring task of creating a similar configuration for the libvirt
container, use the <strong>virt-lxc-convert</strong> to generate an equivalent libvirt domain
configuration for the container.</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# virt-lxc-convert /var/lib/lxc/mycontainer/config >mycontainer.xml</span>
</code></pre></div>
<p>The dumped configuration file, needs to be reviewed before feeding it to
libvirt. Most of the configuration will be OK, but the network configuration may
need some adjustments. For example, for now, libvirt doesn't have any equivalent
to <strong>lxc.network.ipv*</strong>.</p>
<p>When the configuration is ready, define the libvirt container using the
following command:</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# virsh -c lxc:/// define mycontainer.xml</span>
</code></pre></div>
<p>To be able to connect as root on the console, <strong>/dev/pts/0</strong> needs to be added
to the container <strong>securetty</strong>:</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# echo "pts/0" >> /var/lib/lxc/mycontainer/rootfs/etc/securetty</span>
</code></pre></div>
<p>Due to <a href="https://bugzilla.redhat.com/show_bug.cgi?id=966807">rhbz#966807</a>, the kernel 3.14 or later is required to be able to
login on the container.</p>
<p>After this you should be able to start and connect to the container console
using <strong>virsh</strong> or <strong>virt-manager</strong>.</p>
<h2>Updating the openSUSE in the container</h2>
<p>This is just normal zypper manipulation, just that the --root parameter needs to
be added to tell zypper to work on the container's root file system. In the
following command this will just be aliased as <em>zypper-mycont</em>.</p>
<p>The following example commands will just replace the container repositories by
openSUSE 13.1 repositories, refresh them and run a dist upgrade.</p>
<div class="highlight"><pre><span></span><code><span class="err">host ~# alias zypper-mycont="zypper --root=/var/lib/lxc/mycontainer/rootfs"</span>
<span class="err">host ~# zypper-mycont lr</span>
<span class="err"># | Alias | Name | Enabled | Refresh</span>
<span class="err">--+----------+----------+---------+--------</span>
<span class="err">1 | repo-oss | repo-oss | Yes | No</span>
<span class="err">2 | update | update | Yes | No</span>
<span class="err">host ~# zypper-mycont rr repo-oss</span>
<span class="err">host ~# zypper-mycont rr update</span>
<span class="err">host ~# zypper-mycont ar http://download.opensuse.org/distribution/13.1/repo/oss repo-oss</span>
<span class="err">host ~# zypper-mycont ar http://download.opensuse.org/update/13.1/ udpate</span>
<span class="err">host ~# zypper-mycont ref</span>
<span class="err">host ~# zypper-mycont dup</span>
</code></pre></div>CMIS changes merged in master2013-09-02T13:42:00+02:002013-09-02T13:42:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2013-09-02:/cmis-changes-merged-in-master.html<p>I just rebased the feature/cmis branch hosting <a href="http://anonymousquark.com/">Cuong</a>'s great work and some other
interesting improvements of the existing CMIS feature. Concretely, this means
that with master builds you can now:</p>
<ul>
<li>Connect to Google Drive through the CMIS feature. The UI for the connection
may still need to be …</li></ul><p>I just rebased the feature/cmis branch hosting <a href="http://anonymousquark.com/">Cuong</a>'s great work and some other
interesting improvements of the existing CMIS feature. Concretely, this means
that with master builds you can now:</p>
<ul>
<li>Connect to Google Drive through the CMIS feature. The UI for the connection
may still need to be improved</li>
<li>See and edit the CMIS properties of your documents.</li>
<li>Decide what to do with invalid SSL certificates when initiating a CMIS
connection</li>
</ul>
<p><img alt="branching tree" src="https://bosdonnat.fr/data/photos/branching-tree.jpg"></p>libcmis 0.4.0 released2013-08-07T09:54:00+02:002013-08-07T09:54:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2013-08-07:/libcmis-0-4-0-released.html<p>After quite a long time alternating intensive hacking and inactivity, libcmis
0.4.0 is finally out and brings quite a number of great new features. The
hightlight of this release is of course the introduction of the Google Drive
protocol as a CMIS binding by <strong><a href="http://anonymousquark.com/">Cao Cuong Ngo</a></strong> for …</p><p>After quite a long time alternating intensive hacking and inactivity, libcmis
0.4.0 is finally out and brings quite a number of great new features. The
hightlight of this release is of course the introduction of the Google Drive
protocol as a CMIS binding by <strong><a href="http://anonymousquark.com/">Cao Cuong Ngo</a></strong> for his Google Summer of
Code project with LibreOffice. This allows to connect to
your Google Drive documents in the same way than with any CMIS server.</p>
<p>However there are quite some other important improvements:</p>
<ul>
<li>Support for OAuth2 authentication for the CMIS servers. This allows libcmis to
connect to <a href="http://www.alfresco.com/products/cloud">Alfresco cloud</a>. Most of this feature comes from <strong><a href="http://anonymousquark.com/">Cao Cuong
Ngo</a></strong>'s work.</li>
<li>Allow to provide custom HTTP proxy configuration.</li>
<li>Handle invalid SSL certificates instead of simply failing them. This feature
depends if libcurl was built with OpenSSL or not.</li>
<li>Provide repository capabilities</li>
<li>Implement renditions support</li>
</ul>
<p>And it's not a feature, but a great improvements from libcmis hackers: I removed
the Atom binding unit tests depending on Apache Chemistry InMemory server and
switched them to a unit test framework using a <a href="https://bosdonnat.fr/testing-libcurl-based-http-clients.html">libcurl mockup</a>. It heavily
reduced the unit test execution time, but the WebService binding unit test still
have to be migrated to completely get rid of the InMemory server.</p>
<p>You can download libcmis 0.4.0 on <a href="https://sourceforge.net/projects/libcmis/">SourceForge.net</a> as usual. The package for
openSUSE will shortly available on <a href="http://software.opensuse.org">software.opensuse.org</a></p>Screenshots of CMIS in Nautilus2013-08-01T11:24:00+02:002013-08-01T11:24:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2013-08-01:/screenshots-of-cmis-in-nautilus.html<p>Michael asked me this week to provide some screenshots of my <a href="https://bosdonnat.fr/cmis-for-gnome.html">hackweek work</a> on a GVFS
backend for CMIS. Sadly I had none and switched to <a href="http://software.opensuse.org/developer/en">openSUSE Factory</a> in the mean time so
I had to update my code for gvfs master branch. I also had an annoying bug when …</p><p>Michael asked me this week to provide some screenshots of my <a href="https://bosdonnat.fr/cmis-for-gnome.html">hackweek work</a> on a GVFS
backend for CMIS. Sadly I had none and switched to <a href="http://software.opensuse.org/developer/en">openSUSE Factory</a> in the mean time so
I had to update my code for gvfs master branch. I also had an annoying bug when browsing
a CMIS repository in Nautilus... so I had to fix that.</p>
<p>After quite some hours searching, debugging, adding g_print in nautilus, gtk+ and glib, I
finally found the culprit: <code>g_vfs_encode_uri</code> was leaving the <code>':'</code> unencoded in the hostname.</p>
<p>Now I have screenshots to show here:</p>
<p>One from an Alfresco server:</p>
<p><img alt="Alfresco shown in Nautilus" src="https://bosdonnat.fr/data/ecm/nautilus-alfresco.png"></p>
<p>One showing the SharePoint 2013 repositories:</p>
<p><img alt="SharePoint 2013 repositories" src="https://bosdonnat.fr/data/ecm/nautilus-sharepoint_2013.png"></p>CMIS for GNOME2013-04-22T13:23:00+02:002013-04-22T13:23:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2013-04-22:/cmis-for-gnome.html<p>At <a href="http://suse.com">SUSE</a>, we recently had a <a href="http://hackweek.suse.com">Hackweek</a>. It’s one week for all developers employed
by SUSE to hack on any innovative open source project they want. Last years, I
worked on <a href="http://sourceforge.net/projects/libcmis/">libcmis</a> and libcmis-c. And this year, I started implementing a GVFS
backend for CMIS using libcmis-c. GVFS is …</p><p>At <a href="http://suse.com">SUSE</a>, we recently had a <a href="http://hackweek.suse.com">Hackweek</a>. It’s one week for all developers employed
by SUSE to hack on any innovative open source project they want. Last years, I
worked on <a href="http://sourceforge.net/projects/libcmis/">libcmis</a> and libcmis-c. And this year, I started implementing a GVFS
backend for CMIS using libcmis-c. GVFS is the one of the low-level layers of
<a href="http://www.gnome.org">GNOME</a> to access files. A backend is a set of features like mount, unmount, read
a document, writ a document, navigate in folders, etc. Currently GVFS has
backends for FTP, SSH, WebDAV, Trash, Audio CDs, and quite a lot of other useful
things. Having a CMIS backend would allow any Gnome application to access
documents stored on a CMIS-enabled server.</p>
<p>What I achieved in one week:</p>
<ul>
<li>mount and unmount a CMIS repository</li>
<li>read a document</li>
<li>provide the content of the folders and repositories</li>
<li>provide some of the CMIS properties</li>
</ul>
<p>To have a complete backend to upstream, I will need to implement:</p>
<ul>
<li>creating / writing files</li>
<li>deleting / moving items</li>
<li>creating folders</li>
<li>setting properties</li>
</ul>
<p>The code can be found on a <a href="http://cgit.freedesktop.org/~cbosdo/gvfs-cbosdo/">gvfs git clone in my freedesktop home</a>. I want to
thank the Gnome hackers who kindly answered my beginner questions during this
week.</p>Testing libcurl-based HTTP clients2013-02-14T14:48:00+01:002013-02-14T14:48:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2013-02-14:/testing-libcurl-based-http-clients.html<p>Since the last blog post, quite some nice things happened: I moved to a new
house, we released <a href="http://www.libreoffice.org">LibreOffice 4.0.0</a> fantastic release and <a href="http://mmohrhard.wordpress.com/">Markus</a> helped me
write better unit tests for <a href="http://sourceforge.net/projects/libcmis/">libcmis</a>.In this post, I’ld like to give some
details on these new unit tests. To …</p><p>Since the last blog post, quite some nice things happened: I moved to a new
house, we released <a href="http://www.libreoffice.org">LibreOffice 4.0.0</a> fantastic release and <a href="http://mmohrhard.wordpress.com/">Markus</a> helped me
write better unit tests for <a href="http://sourceforge.net/projects/libcmis/">libcmis</a>.In this post, I’ld like to give some
details on these new unit tests. To understand the need of changing unit tests,
you need to know that libcmis test script was downloading, setting up and
starting an <a href="http://chemistry.apache.org/java/developing/repositories/dev-repositories-inmemory.html">Apache Chemistry InMemory</a> server to interact with. This system had
several drawbacks like slow unit tests and dependency on the test server
features and bugs for inventing new test cases. To work this around, Markus
helped me to setup a <a href="http://curl.haxx.se/libcurl/">libcurl</a> mockup library.</p>
<p>The principle is pretty simple: replace the normal libcurl used to send the
HTTP requests to the server by a mockup library. The mockup can then store the
sent requests and provide the responses we want (either valid ones or invalid
ones). The code of the mockup is still evolving and can be found in the
<a href="http://code.ohloh.net/project?pid=lGlZ5bFEHQc&did=qa%2Fmockup">qa/mockup</a> folder of libcmis source tree. One of the key functions to get it
working is <strong>curl_mockup_addResponse</strong>: it tells the mockup what response to
provide under which circumstances. This function may still need some more
parameters to cover all cases, but it will associate a response (body, headers,
status) with a request (URL, HTTP method). The other important function for
testing is <strong>curl_mockup_getRequest</strong>: it gives back the request content for a URL
and HTTP method. It helps making sure that our code sent the proper request.</p>
<p>As always, a small code snippet helps a lot to understand. Let’s take one
derived from libcmis unit tests.</p>
<div class="highlight"><pre><span></span><code><span class="kt">void</span> <span class="n">AtomTest</span><span class="o">::</span><span class="n">createDocumentTest</span><span class="p">(</span> <span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Reset the mockup configuration to avoid keeping other tests config</span>
<span class="n">curl_mockup_reset</span><span class="p">(</span> <span class="p">);</span>
<span class="c1">// Add a response to match. In this case, a POST request with a URL like</span>
<span class="c1">// http://mockup/mock/children?id=root-folder&amp;somethingelse will fit</span>
<span class="c1">// The response will have:</span>
<span class="c1">// - the body: "Response body up to server"</span>
<span class="c1">// - the HTTP status: 201</span>
<span class="c1">// - the HTTP Headers with Location defined</span>
<span class="n">curl_mockup_addResponse</span><span class="p">(</span> <span class="s">"http://mockup/mock/children"</span><span class="p">,</span> <span class="s">"id=root-folder"</span><span class="p">,</span> <span class="s">"POST"</span><span class="p">,</span>
<span class="s">"Response body up to server"</span><span class="p">,</span> <span class="mi">201</span><span class="p">,</span> <span class="nb">false</span><span class="p">,</span>
<span class="s">"Location: http://mockup/mock/id?id=create-document</span><span class="se">\r\n</span><span class="s">"</span> <span class="p">);</span>
<span class="c1">// Set the authentication credentials needed to fake the server</span>
<span class="n">curl_mockup_setCredentials</span><span class="p">(</span> <span class="n">SERVER_USERNAME</span><span class="p">,</span> <span class="n">SERVER_PASSWORD</span> <span class="p">);</span>
<span class="c1">// Create the CURL handle (in the session for libcmis)</span>
<span class="n">AtomPubSession</span> <span class="n">session</span> <span class="o">=</span> <span class="n">getTestSession</span><span class="p">(</span> <span class="n">SERVER_USERNAME</span><span class="p">,</span> <span class="n">SERVER_PASSWORD</span> <span class="p">);</span>
<span class="c1">// Do something with the CURL handle (the session for libcmis)</span>
<span class="p">...</span>
<span class="c1">// You can check that your code worked fine (thanks to the response you provided)</span>
<span class="p">...</span>
<span class="c1">// You can also check that the request was the expected one</span>
<span class="c1">// or matched some important criteria (beware of timestamps</span>
<span class="c1">// and variable bits in the requests)</span>
<span class="n">string</span> <span class="n">request</span><span class="p">(</span> <span class="n">curl_mockup_getRequest</span><span class="p">(</span> <span class="s">"http://mockup/mock/children"</span><span class="p">,</span>
<span class="s">"id=root-folder"</span><span class="p">,</span> <span class="s">"POST"</span> <span class="p">)</span> <span class="p">);</span>
<span class="n">CPPUNIT_ASSERT_EQUAL_MESSAGE</span><span class="p">(</span> <span class="s">"Wrong request sent"</span><span class="p">,</span> <span class="n">expectedRequest</span><span class="p">,</span> <span class="n">request</span> <span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>I hope this testing experience can help others testing their HTTP client
application based on libcurl. Of course, something similar can be done with
other HTTP client libraries.</p>LibreOffice GSoC 2012 wrap-up2012-10-15T14:59:00+02:002012-10-15T14:59:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2012-10-15:/libreoffice-gsoc-2012-wrap-up.html<p><img alt="GSoC 2012 Logo" src="http://code.google.com/images/GSoC2012_300x200.png">I know it's already late, but you know how
it is for hackers: we are delaying stuffs to continue hacking until we
can't delay anymore. It's only a week before Google mentor summit, and
the time for a LibreOffice GSoc 2012 wrap-up has come.<br>
This year we had 10 students …</p><p><img alt="GSoC 2012 Logo" src="http://code.google.com/images/GSoC2012_300x200.png">I know it's already late, but you know how
it is for hackers: we are delaying stuffs to continue hacking until we
can't delay anymore. It's only a week before Google mentor summit, and
the time for a LibreOffice GSoc 2012 wrap-up has come.<br>
This year we had 10 students and 9 successful projects.</p>
<p>The completed projects are:</p>
<ul>
<li>Calc performance improvement from <a href="http://dbank-libreoffice.blogspot.fr">Daniel Bankston</a></li>
</ul>
<p>Daniel improved the load time of both ODF and XLSX format in many
ways. Especially in the large XLSX files, the improvement can be as
big as loading in 6 seconds instead of more than 8 minutes!</p>
<ul>
<li>Enhanced Impress SVG export filter from Marco Cecchetti, see
<a href="http://users.freedesktop.org/~mcecchetti/svg-export/samples/">sample outputs</a></li>
</ul>
<p>Marco improved his previous work to export slides in SVG by adding
animations features to it. Thanks to his work, you will only need to
have Firefox around to play your presentations everywhere. You can check
a few of the results outputs to see how cool this feature is.</p>
<ul>
<li>A MS Publisher import filter from Brennan Vincent, see <a href="http://cgit.freedesktop.org/libreoffice/libmspub/">the code</a></li>
</ul>
<p>Brennan's work was particularly hard, because he had to reverse-engineer
the file format. Together with Valek Filipov, they managed to cover MS
Publisher format from 97 to 2010 - all shapes, fills, and text
properties that Open Document Graphics supports.</p>
<ul>
<li>A Java GUI to pick up files for LibreOffice on Android from Iain
Billett</li>
</ul>
<p>Iain's work is particularly important for the LibreOffice Android
port. While the porting efforts lead to displaying documents, the
entire viewer needs much more - particularly UI that allows you pick the
documents to show, move, zoom; and this is what Iain delivered, see the
screenshot below.</p>
<ul>
<li>A new templates selection UI from <a href="http://npcdoomlibreoffice.wordpress.com">Rafael Dominguez</a></li>
</ul>
<p>Rafael worked on creating a modern UI to pick-up a template to create a
new document. He also added support to connect to remote repositories of
templates which will soon help us to connect directly to the LibreOffice
templates site. This way LibreOffice will bring template's use to the
users.</p>
<ul>
<li>Signed PDF export from <a href="http://blog.yeredusuncedernegi.com">Gökçen Eraslan</a></li>
</ul>
<p>Thanks to Gökçen, we can now digitally sign the PDFs directly as they
are produced by LibreOffice. This is very important in the world where
security and trust of electronic documents needs to be maintained.</p>
<ul>
<li>Android impress remote control from <a href="http://www.ahunt.org/category/libreoffice/">Andrzej Hunt</a></li>
</ul>
<p>Andrzej's Android Remote Control allows you to control the slide show
directly from your Android mobile phone. Just connect your phone to
the presenting computer via network or bluetooth, and you will see
previews of the slides on the phone, and will be able to navigate that -
instead of using the computer's keyboard or usb remote control.</p>
<ul>
<li>Improved group session and UI for the collaborative editing of files
from Matúš Kukan</li>
</ul>
<p>Matúš progressed the <a href="http://people.gnome.org/~michael/blog/2012-03-26-collaboration.html">Calc collaboration</a> demo further - added user
interface, and continued on the core work. This work, once completed,
will allow you to collaboratively edit one spreadsheet with your
colleague conveniently, as if you chatted with them on an instant
messenger, without the need to send files around.</p>
<ul>
<li>Unit tests improvements from Artur Dorda</li>
</ul>
<p>Unit tests are extremely important for LibreOffice. They are the tests
that are run during the build time, and consequently are run by every
developer that builds LibreOffice. Unit tests help you to make sure
that the functionality hasn't regressed over time, and if it does, help
you to discover the regression quickly. Artur did great job extending
the unit tests mainly in the area of Calc.</p>
<p>Their code is is already in the LibreOffice master branch either as
experimental feature or already in use. If you want to meet some of our
successful students in person and know more about these nice projects,
watch for the <a href="http://conference.libreoffice.org/program/thursday-secondary-track/gsoc-2012-results">"GSoC results" session</a> at LibreOffice conferences next
week. Here are a few screenshots for the lazy ones:</p>
<p><img alt="Android LibreOffice file picker" src="https://bosdonnat.fr/data/android-lo-fpicker.png"></p>
<p>Android LibreOffice file picker
</p>
<p><img alt="Impress and its Android remote control" src="http://www.ahunt.org/wp-content/uploads/2012/08/libo_remote_26_reduced_scaled.png"></p>
<p>Impress and its Android remote control</p>
<p><img alt="New templates picking UI" src="http://npcdoomlibreoffice.files.wordpress.com/2012/07/search_2.png"></p>
<p>New templates picking UI</p>
<p>Thanks a lot to Google and their friendly Open Source Program team for
organizing GSoC this year again and allowing us to participate!</p>libcmis 0.3.0 is out2012-09-13T15:16:00+02:002012-09-13T15:16:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2012-09-13:/libcmis-0-3-0-is-out.html<p>Libcmis 0.3.0 just hatched and will bring a whole lot of
change to the way you connect to your ECM. Here is are the cool new
features that were added in this version:</p>
<ul>
<li>WebService binding is implemented at the same level than the Atom
binding</li>
<li>The session factory …</li></ul><p>Libcmis 0.3.0 just hatched and will bring a whole lot of
change to the way you connect to your ECM. Here is are the cool new
features that were added in this version:</p>
<ul>
<li>WebService binding is implemented at the same level than the Atom
binding</li>
<li>The session factory has been improved to auto-guess the binding to
use based on the provided URL</li>
<li>libcmis-c provides a C wrapper API - <em>Thanks to SUSE hackweek</em></li>
<li>Object move method has been implemented - <em>Thanks to <a href="http://www.graudata.com/">Grau Data</a></em></li>
<li>Versions handling has been implemented with the checkOut, checkIn,
cancelCheckout and getAllVersions methods</li>
</ul>
<p>This new version of libcmis also comes with quite some fixes to support
<a href="http://code.google.com/p/xcmis/">XCMIS</a> and <a href="http://www.cloudoku.com/">Cloudoku</a> (thanks to GrauData) and SharePoint.</p>
<p>You can download libcmis 0.3.0 on <a href="https://sourceforge.net/projects/libcmis/">SourceForge.net</a> as usual, or get
it for your beloved openSUSE on
<a href="http://software.opensuse.org">http://software.opensuse.org</a>.</p>LibreOffice integration into your ECM2012-07-12T21:03:00+02:002012-07-12T21:03:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2012-07-12:/libreoffice-integration-into-your-ecm.html<p>Since already a few weeks I am hacking on getting LibreOffice
to integrate as smoothly as possible with ECMs. First Martin Richard and
Julien Levesy - students at <a href="http://if.insa-lyon.fr/">INSA Lyon</a> - reworked the LibreOffice
internal file picker dialog to integrate a places list. After a few more
work on it we had …</p><p>Since already a few weeks I am hacking on getting LibreOffice
to integrate as smoothly as possible with ECMs. First Martin Richard and
Julien Levesy - students at <a href="http://if.insa-lyon.fr/">INSA Lyon</a> - reworked the LibreOffice
internal file picker dialog to integrate a places list. After a few more
work on it we had a useable file picker to access local files, but also
FTP, WebDAV and Windows Shares. Together with that, a big effort on
<a href="http://sourceforge.net/p/libcmis">libcmis</a> and the Universal Content Provider using it made it possible
to connect also to CMIS enabled servers from the file picker.</p>
<p>What works now:</p>
<ul>
<li>Connection to a CMIS server using the internal file picker</li>
<li>Navigating in the CMIS server using the file picker like on a local
file system</li>
<li>Open, Save and Save As files on a CMIS server</li>
</ul>
<p>Even if this work has already nicely progressed it is still not ready
for end users and is thus enabled only with experimental features in
LibreOffice 3.6. Among the main problems:</p>
<ul>
<li>Getting the repository id to paste in the CMIS new place dialog is
not obvious. This is already fixed in the master branch and will be
available for 3.7</li>
<li>Check-in, Check-out and Cancel Check-out still need to be integrated
somehow in the UI in order to handle all cases. For example, saving
on a non-checked out document in SharePoint is not permitted.</li>
<li>Add WebService binding support as this would ease the SharePoint
connection configuration to the user</li>
<li>Get NTLM authentication to work with the curl and libcmis built with
LibreOffice. This is already partly fixed in master branch.</li>
</ul>
<p>Dave Largo, wrote a <a href="http://davelargo.blogspot.fr/2012/07/libreoffice-alfresco-connection.html">nice blog to help users configure the CMIS
connection on 3.6</a>, I won't be copying his work... but if you want to
connect to a SharePoint server using CMIS, you should read <a href="http://technet.microsoft.com/en-us/library/ff934619.aspx">this
documentation</a> first as it shows how to setup and enable CMIS on
SharePoint 2010 and what the binding URLs are.</p>
<p>Brave people can get a daily build or build master, but here are a few
screenshots of what is in the master branch for the inpatients.</p>
<p><img alt="CMIS place edit dialog" src="https://bosdonnat.fr/data/libreoffice/CMIS-place-edit.png"></p>
<p><img alt="CMIS File Picker" src="https://bosdonnat.fr/data/libreoffice/CMIS-fpicker.png"></p>LibreOffice Conference and fOSSa Slides2011-11-09T11:07:00+01:002011-11-09T11:07:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-11-09:/libreoffice-conference-and-fossa-slides.html<p>In October, I attended to several good conferences:</p>
<ul>
<li><a href="http://conference.libreoffice.org/">LibreOffice Conferences</a> in Paris, France</li>
<li>Google Mentor Summit in Mountain View, CA, USA</li>
<li><a href="http://fossa.inria.fr/">fOSSa</a> in Lyon, France</li>
</ul>
<p>Meeting nice people, exchanging on interesting topics was fun... but I
delayed my slides publication until now due to an important work load.
Finally they …</p><p>In October, I attended to several good conferences:</p>
<ul>
<li><a href="http://conference.libreoffice.org/">LibreOffice Conferences</a> in Paris, France</li>
<li>Google Mentor Summit in Mountain View, CA, USA</li>
<li><a href="http://fossa.inria.fr/">fOSSa</a> in Lyon, France</li>
</ul>
<p>Meeting nice people, exchanging on interesting topics was fun... but I
delayed my slides publication until now due to an important work load.
Finally they are here:</p>
<p><strong>LibreOffice Conference</strong></p>
<ul>
<li>Google Summer of Code de LibreOffice panel <a href="https://bosdonnat.fr/data/libreoffice/loconf_gsoc_panel.odp">ODP</a></li>
<li>What's next in Writer? <a href="https://bosdonnat.fr/data/libreoffice/loconf_what_next_writer.odp">ODP</a></li>
<li>Lightning talk on CMIS in LibreOffice <a href="https://bosdonnat.fr/data/libreoffice/loconf_lightning_talk_cmis.odp">ODP</a></li>
</ul>
<p><strong>fOSSa</strong></p>
<ul>
<li>Easy-to-go-live demo on CMIS in LibreOffice <a href="https://bosdonnat.fr/data/libreoffice/fossa-cmis.odp">ODP</a></li>
</ul>
<p>The next and last FOSS event of the year for me will be <a href="http://www.jdll.org/">JDLL</a> in Lyon
where I will share a talk with Jean-Baptiste Faure on the end of the war
between QA and developers inside the LibreOffice community. See you all
in Lyon on November, 18-19th!</p>Hackweek 7: CMIS connection for LibreOffice2011-10-03T13:04:00+02:002011-10-03T13:04:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-10-03:/hackweek-7-cmis-connection-for-libreoffice.html<p>Last week at <a href="http://www.suse.com/">SUSE</a> we had a <a href="http://en.opensuse.org/Portal:Hackweek">hackweek</a>... For those who
don't know what it is, the idea is to have us developers work during one
work week on any project we want. Earlier in the year the idea has been
raised to implement a LibreOffice connector for <a href="http://alfresco.org">Alfresco</a> as …</p><p>Last week at <a href="http://www.suse.com/">SUSE</a> we had a <a href="http://en.opensuse.org/Portal:Hackweek">hackweek</a>... For those who
don't know what it is, the idea is to have us developers work during one
work week on any project we want. Earlier in the year the idea has been
raised to implement a LibreOffice connector for <a href="http://alfresco.org">Alfresco</a> as our
documentation team uses it. We even had a meeting with Alfresco people,
but the conclusion was obvious: LibreOffice needs to handle the <a href="http://en.wikipedia.org/wiki/Content_Management_Interoperability_Services">CMIS</a>
interface... that's what I started during that hackweek.</p>
<p>Of course I didn't have time to have a feature-complete support of CMIS
in only one week, but at least I managed to read some document on an
<a href="http://chemistry.apache.org/">Apache Chemistry</a> InMemory test server at the end of the week. To
make it easier, I started to write a C++ library to handle CMIS that can
be found on <a href="http://sf.net/p/libcmis/">http://sf.net/p/libcmis/</a>. In order for LibreOffice to
handle CMIS, I started writing a new Universal Content Provider (UCP)
and created a fake URL scheme to access the documents. For example on
master, you can open the content of the node #133 using the AtomPub
CMIS binding with that kind of URL:
<strong>cmis+atom://localhost:8080/inmemory/atom/?repo-id=A1&id=133</strong>.</p>
<p>The only way to get a CMIS document that works for sure at the moment is
to provide the URL to the soffice.bin process... but of course this will
need some more love to get a proper UI for it.</p>Writer headers and footers revisited2011-09-16T20:42:00+02:002011-09-16T20:42:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-09-16:/writer-headers-and-footers-revisited.html<p>I was busy hacking a cool new feature the last weeks... and
that I would like to show and will land in LibreOffice Writer 3.5:
headers and footers editing has been greatly improved. The history of
that feature is pretty simple: it all started with a customer document
with …</p><p>I was busy hacking a cool new feature the last weeks... and
that I would like to show and will land in LibreOffice Writer 3.5:
headers and footers editing has been greatly improved. The history of
that feature is pretty simple: it all started with a customer document
with a huge background picture that was selected every now and then
instead of the main text over it. That lead me to a new header/footer
editing mode in Writer, but Christoph Noack and a few others on the
UX-advise mailing list pointed me to a few problems and helped me to
make it even better.</p>
<p>Among the cool changes in the headers footers:</p>
<ul>
<li>Headers, footers and the body text are clearly separated by a dashed
line and a label showing the page style name.</li>
<li>This separation hides when editing the text body.</li>
<li>The popup menu of the label give quick access to header/footer
edition and removal: no need any more to go through the <strong>Format >
Page</strong> Style menu.</li>
<li>Leave the mouse over the area of a header or footer and it will show
the header/footer indicators: this is convenient to quickly add a
new header or footer.</li>
</ul>
<p>The main body, header, footer, footnotes bounds indicators have been
changed as well and are now indicating which area is being edited. Due
to these changes, I also changed the way the manual page breaks are
indicated (this is still not perfect any may change soon):</p>
<ul>
<li>The default color is now red</li>
<li>A small text explains what that red line is meaning</li>
<li>It's shown only with the non-printing characters (which are shown by
default now)</li>
</ul>
<p>As usual, here are a few screenshots for you to see what happens, but
you can also <a href="http://dev-builds.libreoffice.org/daily/">grab a daily build</a> from the master branch (note that
there were still some important fixes on Sept. 16th).</p>
<p><a href="https://bosdonnat.fr/data/hdft-edit.png"><img alt="Editing Header/Footer" src="https://bosdonnat.fr/data/hdft-edit.png"></a></p>
<p>Editing Header/Footer</p>
<p><a href="https://bosdonnat.fr/data/hdft-mouse-over.png"><img alt="Mouse over header area" src="https://bosdonnat.fr/data/hdft-mouse-over.png"></a></p>
<p>Mouse over header area</p>
<p><a href="https://bosdonnat.fr/data/hdft-popup-menu.png"><img alt="Popup menu on header/footer separator" src="https://bosdonnat.fr/data/hdft-popup-menu.png"></a></p>
<p>Popup menu on header/footer separator</p>
<p><a href="https://bosdonnat.fr/data/hdft-pagebreak.png"><img alt="New page break indicator" src="https://bosdonnat.fr/data/hdft-pagebreak.png"></a></p>
<p>New page break indicator</p>
<p>I would like to thank all the ones who helped me on that feature. First
the customer for triggering this but also Christoph Noack and Astron for
the UI improvements ideas and Cor Nouws and Jean-Baptiste Faure for
their continuous testing and bug reporting.</p>GSoC 2011, Community bounding period2011-05-05T11:00:00+02:002011-05-05T11:00:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-05-05:/gsoc-2011-community-bounding-period.html<p>I was away when the news has been published by Google, so I'll
congratulate all our selected students now.</p>
<ul>
<li><strong>Miklos Vajna</strong>: RTF tokenizer for writerfilter (rewrite of the RTF
import)</li>
<li><strong>Anurag Jain</strong>: multi-line editing in the Calc bar</li>
<li><strong>Eilidh McAdam</strong>: first version of a Visio import filter</li>
<li><strong>Matúš Kukan</strong>: performance …</li></ul><p>I was away when the news has been published by Google, so I'll
congratulate all our selected students now.</p>
<ul>
<li><strong>Miklos Vajna</strong>: RTF tokenizer for writerfilter (rewrite of the RTF
import)</li>
<li><strong>Anurag Jain</strong>: multi-line editing in the Calc bar</li>
<li><strong>Eilidh McAdam</strong>: first version of a Visio import filter</li>
<li><strong>Matúš Kukan</strong>: performance improvements</li>
<li><strong>Marco Cecchetti</strong>: SVG export filter enhancements</li>
<li><strong>Xisco Fauli</strong>: migration of Java wizards to Python</li>
<li><strong>Timo</strong>: conversion of the wiki help to platform specific files</li>
</ul>
<p>The have until may, 23rd to get more deeply integrated in the community
before coding. I wish them an intense summer hacking and good results at
the end!</p>How many frequent contributors to LibreOffice?2011-04-21T22:03:00+02:002011-04-21T22:03:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-04-21:/how-many-frequent-contributors-to-libreoffice.html<p>As I promised it from the first developers stats I published,
I worked on gitdm to extract some metrics to show how many persons are
actively contributing to LibreOffice and how many are providing patches
and vanishing right after. As usual the tool and not-yet-upstreamed
patches to gitdm are located …</p><p>As I promised it from the first developers stats I published,
I worked on gitdm to extract some metrics to show how many persons are
actively contributing to LibreOffice and how many are providing patches
and vanishing right after. As usual the tool and not-yet-upstreamed
patches to gitdm are located on <a href="http://cgit.freedesktop.org/~cbosdo/gitdm-lo-config/">this git repository</a>. To extract
those data I needed to set some definition of an active contributor...
which isn't so easy. Here are the rules I used to produce the stats:</p>
<ul>
<li>The time between the first and last commit should be more than a
day, or for sure it's a one shot contribution.</li>
<li>The number of patches should be greater than 10. I decided that
value empirically but it's not that bad as LibreOffice has
approximately 20 git repos.</li>
<li>The last commit should date from less than 2 months.</li>
</ul>
<p>These rules can be discussed of course, but they give a fairly good idea
of what is happening. The raw data can be found on <a href="https://bosdonnat.fr/data/libreoffice/hackers-2011-16.ods">that file</a>.</p>
<p><a href="https://bosdonnat.fr/data/hackers-2011-16.png"><img alt="Hackers stats on week 16" src="https://bosdonnat.fr/data/hackers-2011-16.png"></a></p>
<p>Hackers stats on week 16</p>
<p>What is interesting in this graph is that 16% of the 223 new developers
(35 persons) are contributing regularly. This is encouraging because it
shows that quite a number of new developers joined us, but it also
reminds us that we need to strive keeping more new developers.</p>
<p>I just presented those stats at a <a href="http://www.jcos.fr/">conference at SupInfo Lyon</a>
today... but there wasn't a lot of people there listening. The slides
are available <a href="https://bosdonnat.fr/data/libreoffice/jcos-2011.odp">here</a> in french.</p>Testing Writer documents rendering2011-04-07T14:01:00+02:002011-04-07T14:01:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-04-07:/testing-writer-documents-rendering.html<p>Checking whether documents are looking the same when they are
loaded in Writer has been a problem and needs a lot of manual
verifications. When discussing with Florian Reuter more than a year ago,
I discovered that he wrote a patch to dump the writer layout as an XML
file …</p><p>Checking whether documents are looking the same when they are
loaded in Writer has been a problem and needs a lot of manual
verifications. When discussing with Florian Reuter more than a year ago,
I discovered that he wrote a patch to dump the writer layout as an XML
file. This patch helped him to debug layout problems, but Thorsten
quickly had the idea to use it to test documents rendering. I finally
found some time to improve that layout dumping patch and create a filter
for it: it has been pushed yesterday to the master branch (see commits
<a href="http://cgit.freedesktop.org/libreoffice/writer/commit/?id=16431d950e573101ff8eb31c054346422d18c516">16431d9</a>, <a href="http://cgit.freedesktop.org/libreoffice/writer/commit/?id=2ef2ae4fd058cfb51f9a07da7d7dc3d0db55503f">2ef2ae4</a> in writer repo and <a href="http://cgit.freedesktop.org/libreoffice/filters/commit/?id=51398babdbe880c93ad4940d0b4a515a09aa0557">51398ba</a> in filters
repo).</p>
<p>From now LibreOffice can be run from the command line using
the<strong>--convert-to 'xml:writer_layout_dump'</strong> and <strong>--outdir</strong> options
to dump an XML representation of the Writer internal layout objects. The
<a href="http://wiki.services.openoffice.org/wiki/Writer_Core_And_Layout">Core And Layout</a> OpenOffice.org wiki page will help you to understand
the resulting XML file, but that one will probably have different
pointer values when dumping the same document a second time. In order to
fix that, you can normalize the document using some bash script like
this one:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
<span class="nv">id</span><span class="o">=</span><span class="m">0</span>
<span class="k">for</span> ptr in <span class="sb">`</span>xmllint --format <span class="nv">$1</span> <span class="p">|</span> grep <span class="s1">'ptr='</span> <span class="p">|</span> tr <span class="s2">" "</span> <span class="s2">"\n"</span> <span class="p">|</span> grep <span class="s1">'ptr='</span> <span class="p">|</span> sed -e <span class="s1">'s/ptr="\(0x[0-9a-z]\+\)"/\1/'</span><span class="sb">`</span><span class="p">;</span> <span class="k">do</span>
<span class="nb">let</span> id++
sed -i <span class="nv">$1</span> -e <span class="s2">"s/</span><span class="nv">$ptr</span><span class="s2">/</span><span class="nv">$id</span><span class="s2">/g"</span>
<span class="k">done</span>
<span class="nb">unset</span> i
</code></pre></div>
<p>After having normalized the files, running diff on the two files should
show the real differences in the layout... and help the
testing.</p>GSoC 2011, apply now!2011-03-30T11:22:00+02:002011-03-30T11:22:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2011-03-30:/gsoc-2011-apply-now.html<p><img alt="" src="http://www.google-melange.com/soc/content/2-0-20110329-p2/images/v2/gsoc/logo-banner.jpg" title="GSoC 2011 banner">Considering the quite low amount of proposals already filed on
<a href="http://www.google-melange.com/">Google Melange</a> for LibreOffice, I'ld like to remind you all that the
application period has started on March 28th and will end up on April,
8th... which means very soon! Don't hesitate to spend a nice summer
hacking on funny …</p><p><img alt="" src="http://www.google-melange.com/soc/content/2-0-20110329-p2/images/v2/gsoc/logo-banner.jpg" title="GSoC 2011 banner">Considering the quite low amount of proposals already filed on
<a href="http://www.google-melange.com/">Google Melange</a> for LibreOffice, I'ld like to remind you all that the
application period has started on March 28th and will end up on April,
8th... which means very soon! Don't hesitate to spend a nice summer
hacking on funny stuffs in LibreOffice: <a href="http://www.google-melange.com/gsoc/org/google/gsoc2011/libreoffice">apply now</a>!</p>
<p>I already received several emails from students wanting to work on the
new RTF tokenizer or the persisting the autocompletion words list, but
there is a nice feature to be worked on: adding borders to characters in
Writer. Hack on that and you'll be praised by loads of users awaiting
this for more than 8 years! The idea is pretty simple: Word files and
HTML can both have borders around runs of characters, but LibreOffice
doesn't have that feature. The job here consists in:</p>
<ol>
<li><strong>Enhance the UI</strong> for the character style: you will simply need to
add the already existing border editing tab to the dialog.</li>
<li><strong>Enhance the Writer core</strong> by adding one character attribute to the
data structure.</li>
<li>Use that attribute to <strong>enhance the Writer layout</strong> and actually
draw the borders on the screen and PDFs / printing.</li>
<li>Persist the new feature in the different formats handled by Writer.
This means <strong>improving the import and export filters</strong> like the ones
for Word files, RTF, HTML and even ODF.</li>
<li><strong>Propose an ODF enhancement</strong> to standardize the use of
<em>fo:borders</em> attributes in the <em>\<style:text-properties></em> elements.</li>
</ol>
<p>I hope to see loads of rock-solid applications to make free software
progress while introducing students to LibreOffice
hacking.</p>GSoC - 2011 edition started!2011-03-19T20:42:00+01:002011-03-19T20:42:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-03-19:/gsoc-2011-edition-started.html<p>Just a short post to update you that LibreOffice has been
accepted as a Google Summer of Code 2011 organization (<a href="http://www.google-melange.com/gsoc/org/show/google/gsoc2011/libreoffice">See on melange</a>). Don't hesitate
to spread the news and to contact us for more informations to start on a
project. All our project ideas are sitting on <a href="http://wiki.documentfoundation.org/Development/Gsoc/Ideas">this page …</a></p><p>Just a short post to update you that LibreOffice has been
accepted as a Google Summer of Code 2011 organization (<a href="http://www.google-melange.com/gsoc/org/show/google/gsoc2011/libreoffice">See on melange</a>). Don't hesitate
to spread the news and to contact us for more informations to start on a
project. All our project ideas are sitting on <a href="http://wiki.documentfoundation.org/Development/Gsoc/Ideas">this page</a> and are
waiting for you to pick them. I hope this term will be full of
interesting projects and fun between LibreOffice students and
mentors!</p>Rounded Pi day story2011-03-15T15:38:00+01:002011-03-15T15:38:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-03-15:/rounded-pi-day-story.html<p>I discovered yesterday that there was a <a href="http://en.wikipedia.org/wiki/Pi_Day">Pi day</a>... and I
happened to have some interesting bug around it fixed today. Rotating
the (1,0) vector of a 90 degrees angle didn't provide (0,1) but
something really approaching. This tiny error was clearly visible
because some borders weren't properly …</p><p>I discovered yesterday that there was a <a href="http://en.wikipedia.org/wiki/Pi_Day">Pi day</a>... and I
happened to have some interesting bug around it fixed today. Rotating
the (1,0) vector of a 90 degrees angle didn't provide (0,1) but
something really approaching. This tiny error was clearly visible
because some borders weren't properly drawn due to some clipping
problem. After quite a long time trying to understand what was going on,
I finally saw that there were [two constants for Pi in LibreOffice][]
(and OpenOffice.org) code: in the tools and basegfx modules... and they
had different precision. My problem came that the F_PI value in my code
lying in the svx module was the one from the tools module... which is
deprecated. In order to avoid that trouble later, I added an <a href="http://wiki.documentfoundation.org/Easy_Hacks#Remove_F_PI_definition_from_solar.h">easy hack
to remove the tools definitions for F_PI</a> and friends: don't be
afraid and hack it!</p>
<p>For the curious ones, this problem was introduced by new code for the
borders drawing to handle the Calc rotated cells borders. Here are some
screenshots of how the borders were drawn before and after the hack.</p>
<p><a href="https://bosdonnat.fr/data/slanted-borders-before.png"><img alt="Ugly rotated borders" src="https://bosdonnat.fr/data/slanted-borders-before.png"></a></p>
<p>Before</p>
<p><a href="https://bosdonnat.fr/data/slanted-borders-after.png"><img alt="Nicely drawn rotated cell borders" src="https://bosdonnat.fr/data/slanted-borders-after.png"></a></p>
<p>After</p>
<p>The code is still hanging in <a href="http://cgit.freedesktop.org/~cbosdo/">my personal git repositories</a> on
freedesktop.org... but not for long as I plan to integrate this work
before 3.4 feature freeze..</p>LibreOffice applied for GSoc 20112011-03-03T19:04:00+01:002011-03-03T19:04:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-03-03:/libreoffice-applied-for-gsoc-2011.html<p><a href="http://google-opensource.blogspot.com/"><img alt="Gsoc 2011 logo" src="http://1.bp.blogspot.com/-61a6mHfP1bU/TWbmtb5TAAI/AAAAAAAAABo/w56YXLjXDGY/s400/GSOC_2011_300x200px.png"></a>I just have filed the form for
LibreOffice to be part of the next edition of Google Summer or Code. The
list of the selected organizations will be out on March 18th. This will
be a nice adventure to help us improve our mentoring skill and help
students getting introduced …</p><p><a href="http://google-opensource.blogspot.com/"><img alt="Gsoc 2011 logo" src="http://1.bp.blogspot.com/-61a6mHfP1bU/TWbmtb5TAAI/AAAAAAAAABo/w56YXLjXDGY/s400/GSOC_2011_300x200px.png"></a>I just have filed the form for
LibreOffice to be part of the next edition of Google Summer or Code. The
list of the selected organizations will be out on March 18th. This will
be a nice adventure to help us improve our mentoring skill and help
students getting introduced to an open source community. All the details
of the application are available on the <a href="http://wiki.documentfoundation.org/Development/GSoc">GSoc wiki page</a>.</p>
<p>Last year, with Go-oo we found very useful to ask the students to solve
some easy hacking exercise as it forces them to build before the coding
period. It also allows us to evaluate their capabilities to interact
with the developers, read code and provide a clear patch. This year we
are asking for some hacking proof to select the students, but not on
the basis of an exercise. We simply want the student to fix one of the
bugs marked as <a href="http://bugs.freedesktop.org/buglist.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&product=LibreOffice&content=EasyHack">EasyHacks in our bugzilla</a>: this will be more useful
than switching shortcuts!</p>
<p>The <a href="http://wiki.documentfoundation.org/Development/Gsoc/Ideas">page listing the ideas</a> has just been created with last year's
remaining ideas. Feel free to add your ideas here, but don't forget that
they will need to fit in a summer for students. Code pointers or links
to useful documents would be really nice to help students understand
your ideas. Once you added an idea, please notify the <a href="http://lists.freedesktop.org/mailman/listinfo/libreoffice">development
mailing list</a> about it.</p>Updated LibreOffice contributions stats2011-02-14T16:13:00+01:002011-02-14T16:13:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-02-14:/updated-libreoffice-contributions-stats.html<p>I haven't provided any update of the LibreOffice contributions
stats <a href="https://bosdonnat.fr/libreoffice-contributions-stats.html">until the end of October</a>... but I am about to fix that in this
post. Like before the stats have been generated using gitdm and its
configuration located in <a href="http://cgit.freedesktop.org/libreoffice/contrib/gitdm-config/">this git repo</a>. Here are the same two graphs
updated (the …</p><p>I haven't provided any update of the LibreOffice contributions
stats <a href="https://bosdonnat.fr/libreoffice-contributions-stats.html">until the end of October</a>... but I am about to fix that in this
post. Like before the stats have been generated using gitdm and its
configuration located in <a href="http://cgit.freedesktop.org/libreoffice/contrib/gitdm-config/">this git repo</a>. Here are the same two graphs
updated (the file with the data can be found <a href="https://bosdonnat.fr/data/libreoffice/git-data-2011-07.ods">here</a>). Here are a few
points to understand the graphs:</p>
<ul>
<li>The activity cut that can be seen at the end of 2010 is mostly due
to the fact that loads of developers were away celebrate Christmas
and the end of the year. The other fact explaining this is that
almost all the remaining developers were working hard to make 3.3
out.</li>
<li>The data are extracted from the master branch of all the LibreOffice
git repositories. Then all the work happening in features branches
that has still not be merged can't be revealed here.</li>
<li>The formula to compute the line changes has been changed... instead
of adding the deleted and added lines, I'm now showing the maximum
of these two values. There is no real way to extract accurate data
for this, but it provides more meaningful figures.</li>
<li>Did you see that Canonical is now contributing code? Welcome to
Björn Michaelsen in the LibreOffice community!</li>
</ul>
<p><a href="https://bosdonnat.fr/data/gitdm-lo-2011-07-people.png"><img alt="Contributors to LibreOffice per week" src="https://bosdonnat.fr/data/gitdm-lo-2011-07-people.png"></a></p>
<p>Contributors to LibreOffice per week</p>
<p><a href="https://bosdonnat.fr/data/gitdm-lo-2011-07-changes.png"><img alt="Lines changed on LibreOffice per week" src="https://bosdonnat.fr/data/gitdm-lo-2011-07-changes.png"></a></p>
<p>Lines changed on LibreOffice per week</p>
<p>LibreOffice now counts 133 new hackers and 55 localizers (since the
fork). Let's hope that there figures will increase according to the
number of persons attending LibreOffice development talks at
FOSDEM.</p>Hacky new year2011-01-10T12:24:00+01:002011-01-10T12:24:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2011-01-10:/hacky-new-year.html<p>First I wish you a happy new year intensively hacking open
source projects (mostly LibreOffice I hope). This is a nice occasion to
show you what happened in 2010 on the LibreOffice development front. I
ran again gource on the git logs again to create a new video showing the …</p><p>First I wish you a happy new year intensively hacking open
source projects (mostly LibreOffice I hope). This is a nice occasion to
show you what happened in 2010 on the LibreOffice development front. I
ran again gource on the git logs again to create a new video showing the
activity around the source code in 2010, and this time I managed to add
some sound... thought not easily.</p>
<p>The recipe to create to video:</p>
<ul>
<li>I reused the python script I did last time to merge all git repos</li>
<li>To extract the video from gource I used a desktop recorder: the
quality was much better</li>
<li>I spent time to find a music on <a href="http://www.jamendo.com/">Jamendo</a></li>
<li><a href="http://www.openshot.org/">OpenShot</a> helped the newbie that I am to edit the final video</li>
</ul>
<iframe src="http://player.vimeo.com/video/18616103" width="400" height="300" frameborder="0"></iframe>
<p><a href="http://vimeo.com/18616103">LibreOffice development in 2010</a> from <a href="http://vimeo.com/user792889">Cédric Bosdonnat</a> on
<a href="http://vimeo.com">Vimeo</a>.</p>
<p>It's great to see so many people helping LibreOffice to
live...</p>LibreOffice Contributions stats2010-10-23T20:00:00+02:002010-10-23T20:00:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-10-23:/libreoffice-contributions-stats.html<p>We had a really important amount of new contributions, but
people tends to prefer figures to see it. I used the <a href="http://cgit.freedesktop.org/libreoffice/">git
repositories</a> logs and <a href="http://lwn.net/Articles/290957/">gitdm</a> to get the data and produce some
graphs showing the intense activity around LibreOffice. The gitdm
configuration and scripts to extract the data can …</p><p>We had a really important amount of new contributions, but
people tends to prefer figures to see it. I used the <a href="http://cgit.freedesktop.org/libreoffice/">git
repositories</a> logs and <a href="http://lwn.net/Articles/290957/">gitdm</a> to get the data and produce some
graphs showing the intense activity around LibreOffice. The gitdm
configuration and scripts to extract the data can be found <a href="http://cgit.freedesktop.org/libreoffice/contrib/gitdm-config/">on
freedesktop.org</a>. The first graph is showing the
number of contributors increasing each week. There are a few interesting
points to note:</p>
<ul>
<li>The number of new contributors grew quickly. The graph don't show
it, but there are now more than 60 new contributors.</li>
<li>The contributors counted in this graph are either developers or
people working on localization.</li>
<li>Oracle is contributing: LibreOffice merges OpenOffice.org changes.</li>
</ul>
<p><a href="https://bosdonnat.fr/data/contributors-week42.png"><img alt="Contributors by week graph" src="https://bosdonnat.fr/data/contributors-week42.png"></a></p>
<p>Contributors by week graph</p>
<p>The second graph show the number of changed lines over the past few
weeks. These data are based on the number of added and removed lines of
the git commit diffs. Having a relevant number of changed lines is
pretty hard. Thus I decided to sum the number of added and removed
lines: this provides fair data, even though the big numbers aren't
really meaningful. To read these values, we need to keep in mind the
following points:</p>
<ul>
<li>Adding the mode lines for emacs and vim generated a lot of added
lines</li>
<li>Cleaning up the header guards also generated a lot of lines removed:
the script to remove them has been written by a new contributor and
has been run by Petr Mladek</li>
<li>Changing a single tiny thing in a line adds one added and one
removed line.</li>
</ul>
<p><a href="https://bosdonnat.fr/data/changes-week42.png"><img alt="Changes by week graph" src="https://bosdonnat.fr/data/changes-week42.png"></a></p>
<p>Changes by week graph</p>
<p>The gitdm stats on po and sdf files are reporting 34 persons (27 new
contributors) working on the localization... though I'm counted in them
due to a small typo fixed in a po file. Among the new contributors
working on localization, there are probably person who worked or are
working on the OpenOffice.org project.</p>
<p>Here are the full data in <a href="https://bosdonnat.fr/data/libreoffice/stats/git-data.csv">CSV</a> format and <a href="https://bosdonnat.fr/data/libreoffice/stats/git-data.ods">with the graphs in ODS</a>.
The full data for the localization can be found <a href="https://bosdonnat.fr/data/libreoffice/stats/git-l10n-data.csv">here</a>.</p>
<p>Many thanks to all of the contributors, newcomers and
others!</p>Which OOo bugs are fixed in LibreOffice?2010-10-11T16:24:00+02:002010-10-11T16:24:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-10-11:/which-ooo-bugs-are-fixed-in-libreoffice.html<p>Laurent asked me quite a good question this afternoon: should
we add some comment in <a href="http://qa.openoffice.org/issues/query.cgi">IssueZilla</a> to indicate that a bug has been
fixed in LibreOffice? It's pretty obvious to me that it's politically
incorrect to do that... but we can extract the bug numbers from the
LibreOffice git logs …</p><p>Laurent asked me quite a good question this afternoon: should
we add some comment in <a href="http://qa.openoffice.org/issues/query.cgi">IssueZilla</a> to indicate that a bug has been
fixed in LibreOffice? It's pretty obvious to me that it's politically
incorrect to do that... but we can extract the bug numbers from the
LibreOffice git logs. First I started with some simple shell script to
generate the list of the bug numbers, then I created my first
<a href="http://www.greasespot.net/">GreaseMonkey</a> script to change the IZ page for these bugs.</p>
<ul>
<li>The script to extract the bug numbers is running from times to
times and the result put on the web. The end user doesn't need it,
but only that the result is at the expected place.</li>
<li>The GreaseMonkey script can be found on <a href="http://userscripts.org/scripts/show/87923">http://userscripts.org</a>.
You need to install GreaseMonkey Firefox extension and then this
script: that's the one actually doing the job.</li>
</ul>
<p>The only thing now to make it reliable is that developpers need to add
the number of the fixed bugs in they git commit messages like
<strong>i#12345</strong>.</p>
<p>For those how want to see what it looks like before installing, here is
a sample result in IssueZilla.</p>
<p><a href="https://bosdonnat.fr/data/IZ_fixed_LO.png"><img alt="Preview of LibreOffice hack on IZ" src="https://bosdonnat.fr/data/IZ_fixed_LO-300x116.png"></a></p>
<p>I owe many thanks to the authors of that nice <a href="http://commons.oreilly.com/wiki/index.php/Greasemonkey_Hacks/Getting_Started">GreaseMonkey
Getting started tutorial</a>.</p>
<p><strong>EDIT:</strong> The script now shows also the bugs formatted in the
<strong>#i12345#</strong> way and the commits from OpenOffice.org that are merged
into LibreOffice.</p>How to pronounce LibreOffice2010-10-08T09:24:00+02:002010-10-08T09:24:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-10-08:/how-to-pronounce-libreoffice.html<p>Yesterday on IRC, we had an interesting question: "<strong>How
should I pronounce LibreOffice?</strong>". The easy answer is to pronounce
Libre as the french word and Office as the english one... but what about
people that never studied french? Thanks to <a href="http://swac-collections.org">Shtooka free pronounciation
dictionary</a>, you can learn LibreOffice pronounciation easily …</p><p>Yesterday on IRC, we had an interesting question: "<strong>How
should I pronounce LibreOffice?</strong>". The easy answer is to pronounce
Libre as the french word and Office as the english one... but what about
people that never studied french? Thanks to <a href="http://swac-collections.org">Shtooka free pronounciation
dictionary</a>, you can learn LibreOffice pronounciation easily:</p>
<ul>
<li><strong><a href="http://packs.shtooka.net/fra-balm-frank/ogg/fra-b74c4435.ogg">Libre</a></strong></li>
<li><strong><a href="http://packs.shtooka.net/eng-wcp-us/ogg/En-us-office.ogg">Office</a></strong></li>
</ul>
<p>Now that you can pronounce it, go and spread LibreOffice around the
world!</p>Strong support for the first week of The Document Foundation (french version)2010-10-06T17:29:00+02:002010-10-06T17:29:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-10-06:/strong-support-for-the-first-week-of-the-document-foundation-french-version.html<p>Laurent Godard helped me to translate today press release in
french. The original text can be read <a href="http://standardsandfreedom.net/index.php/2010/10/06/strong-support-for-the-first-week-of-the-document-foundation-official-pr/">in english on Charles' blog</a>.</p>
<blockquote>
<p>Internet, le 6 Octobre 2010 - Une semaine entière s'est écoulée
depuis l'annonce de la fondation "The Document Foundation" et nous
aimerions partager quelques chiffres avec les personnes qui …</p></blockquote><p>Laurent Godard helped me to translate today press release in
french. The original text can be read <a href="http://standardsandfreedom.net/index.php/2010/10/06/strong-support-for-the-first-week-of-the-document-foundation-official-pr/">in english on Charles' blog</a>.</p>
<blockquote>
<p>Internet, le 6 Octobre 2010 - Une semaine entière s'est écoulée
depuis l'annonce de la fondation "The Document Foundation" et nous
aimerions partager quelques chiffres avec les personnes qui ont
décidé de nous suivre dès le le premier jour.</p>
<p>La version Beta de LibreOffice à été téléchargée plus de 80.000
fois. L'infrastructure s'est entendue de 25 à 45 miroirs dans 25 pays
sur tous les continents y compris les iles de l'océan pacifique. Ce
chiffre est proche de la moitié de celui atteint par OpenOffice.org
en 10 ans d'existence du projet.</p>
<p>Les volontaires ont commencé à contribuer du code, suggérer des
fonctionnalités, fournir des correctifs et remonter des bugs. En
juste une semaine, environ 80 contributions de code (patchs et
contributions directes) ont été acceptées dans LibreOffice pour un
total de 27 volontaires, beaucoup d'entre eux nouveaux venus, avec
environ 100 développeurs présents sur le canal IRC #libreoffice qui
fourmille d'activité (environ 14.000 messages échangés).</p>
<p>Du coté de la communauté plus large, 2000 personnes se sont
abonnées à la liste announce@ pour être informés des dernières
nouvelles de la fondation et 300 personnes à la liste discuss@ dont
l'activité moyenne a été de 100 messages par jour.</p>
<p>En arrondissant, il y a presque 600 personnes suivant les tweets TDF,
plus de 150 suivant le compte identi.ca de TDF et plus de 1000 fans
sur Facebook. Le trafic sur le serveur a été autour de 500 Go.</p>
<p>Dans sa seule réponse officielle à la création de la Fondation,
Oracle a déclaré: "Oracle investi des resources substantielles dans
OpenOffice.org. Avec plus d'un million d'utilisateurs, nous croyons
qu'OpenOffice.org est le plus avancé, l'implémentation open source
la plus riche en fonctionnalités et allons encourager la communauté
OpenOffice.org à continuer de contribuer au travers de
www.openoffice.org."</p>
<p>La Fondation en comprend qu'Oracle n'a pas de plans immédiats de
soutien à la Fondation, ou de transfert des biens de la communauté
comme la marque OpenOffice.org. Cependant la Fondation espère que
cette position changera lorsque l'entreprise verra la communauté
volontaire - un composant essentiel du succès passé d'OpenOffice -
fournir son support à la nouvelle Fondation. Pendant ce temps, la
Fondation continuera le développement du logiciel sous la marque
LibreOffice.</p>
</blockquote>LibreOffice intense coding activity2010-10-06T16:59:00+02:002010-10-06T16:59:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-10-06:/libreoffice-intense-coding-activity.html<p>Now a week after the announce of <a href="http://www.documentfoundation.org/">The Documentation
Foundation</a> and <a href="http://www.documentfoundation.org/download/">LibreOffice</a>, I found some time to show you that
amazing activity we had during that first week. I created a small script
to merge all the logs of the <a href="http://cgit.freedesktop.org/libreoffice">LibreOffice git repositories</a>. Then I
gave this log to <a href="http://code.google.com/p/gource/">gource …</a></p><p>Now a week after the announce of <a href="http://www.documentfoundation.org/">The Documentation
Foundation</a> and <a href="http://www.documentfoundation.org/download/">LibreOffice</a>, I found some time to show you that
amazing activity we had during that first week. I created a small script
to merge all the logs of the <a href="http://cgit.freedesktop.org/libreoffice">LibreOffice git repositories</a>. Then I
gave this log to <a href="http://code.google.com/p/gource/">gource</a> in order to produce a nice video. I really
hope this activity will continue and boost the project!</p>
<iframe src="http://player.vimeo.com/video/15596440" width="400" height="300" frameborder="0"></iframe>
<p><a href="http://vimeo.com/15596440">LibreOffice first week coding</a> from <a href="http://vimeo.com/user792889">Cédric Bosdonnat</a> on
<a href="http://vimeo.com">Vimeo</a>.</p>GSoc 2010 Wrap-Up2010-09-24T22:03:00+02:002010-09-24T22:03:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-09-24:/gsoc-2010-wrap-up.html<p><img alt="GSoc 2010 Logo" src="http://2.bp.blogspot.com/_p15UnEJyA1c/TFrz3e7YzdI/AAAAAAAAAaA/OkBiYJBCB-M/s320/GSOC2010_MedRect_YearURL.png" title="GSoc 2010 Logo">End of september: it's time for Go-oo GSoc
2010 wrap-up. This term again, 6 students have been working hard during
their summer holidays to improve Go-oo. This year, the students needed
to get rid of the building problem before applying. <a href="http://www.freedesktop.org/wiki/Software/ooo-build/SummerOfCode/2010#Theexercise">That tiny
exercise</a> helped us a lot to chose motivated …</p><p><img alt="GSoc 2010 Logo" src="http://2.bp.blogspot.com/_p15UnEJyA1c/TFrz3e7YzdI/AAAAAAAAAaA/OkBiYJBCB-M/s320/GSOC2010_MedRect_YearURL.png" title="GSoc 2010 Logo">End of september: it's time for Go-oo GSoc
2010 wrap-up. This term again, 6 students have been working hard during
their summer holidays to improve Go-oo. This year, the students needed
to get rid of the building problem before applying. <a href="http://www.freedesktop.org/wiki/Software/ooo-build/SummerOfCode/2010#Theexercise">That tiny
exercise</a> helped us a lot to chose motivated students: all of them
managed to accomplish their task. The only drawback we had with a
project was mostly our fault (I mean the mentors): nobody was really
comfortable with that part of the code and the student lost quite some
time to try to understand it.</p>
<p>The completed projects are:</p>
<ul>
<li>New and improved RTF export filter by Miklos Vajna (<a href="http://cgit.freedesktop.org/libreoffice/writer/commit/?id=db6af6a208ed578625ef2df23f50ec982b562ca6">the code</a>)</li>
<li>Maths editor improvements by Jonas Jensen (<a href="http://cgit.freedesktop.org/libreoffice/build/commit/?id=d6b73c9d63b02142b9d48d9fed1573912ee3705e">the code</a>)</li>
<li>Maths object baseline aligment by Michal Spisiak (<a href="http://cgit.freedesktop.org/libreoffice/build/commit/?id=bba02943fd850a1f5aad66f51346038d19e643c3">the code</a>)</li>
<li>Add effects to styles by Larisa Raicevic (<a href="http://cgit.freedesktop.org/libreoffice/build/commit/?id=a0866751f996613466f7e10619c3c3f2ff54c38d">the code</a>)</li>
<li>Connect the gallery with OpenClipart by Tijana Milijanovic (<a href="http://cgit.freedesktop.org/libreoffice/build/commit/?id=f3a517b005a31607b373393600ac41237a55b1f4">the
code</a>)</li>
<li>Calc usability improvements by Thomas Dziedzic (<a href="http://cgit.freedesktop.org/libreoffice/build/commit/?id=ccc534c27bc51526a291e21797ac337a7a695346">the code</a>)</li>
</ul>
<p>This was my second year as mentor, and first year as organization admin.
We had really brilliant students this year and two of them, <a href="http://conference.opensuse.org/indico//contributionDisplay.py?contribId=86&sessionId=28&confId=0">Jonas</a>
and <a href="http://conference.opensuse.org/indico//contributionDisplay.py?contribId=81&sessionId=28&confId=0">Miklos</a> will even join us at <a href="http://en.opensuse.org/openSUSE:Conference">openSUSE conferences</a> in
Nürnberg to present their work. This year we have a lot of code that
can be almost directly be integrated to Go-oo builds. My biggest concern
now is how to make students continue to contribute after the end of GSoc
term...</p>
<p>I owe many thanks to all our students, but also to all the mentors who
did a great job as well (<a href="http://eric.bachard.org/news/index.php">Eric</a>, <a href="http://fridrich.blogspot.com/">Fridrich</a>, <a href="http://artax.karlin.mff.cuni.cz/~kendy/blog">Kendy</a>,
<a href="http://kohei.us/">Kohei</a>,Radek and <a href="http://blog.thebehrens.net">Thorsten</a>). I would like to thank Google for
allowing us to participate in the Summer of Code for the second
year.</p>Holidays in China2010-09-08T22:02:00+02:002010-09-08T22:02:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-09-08:/holidays-in-china.html<p>This summer, I have spent a whole month traveling in China
with my wife. This experience was even better because we organized it
all by ourselves. Hopefully some friends and colleagues helped and
welcomed us. We arrived in Shanghai and did some round trip via famous
places like <a href="http://en.wikipedia.org/wiki/Hangzhou">Hangzhou</a>, the …</p><p>This summer, I have spent a whole month traveling in China
with my wife. This experience was even better because we organized it
all by ourselves. Hopefully some friends and colleagues helped and
welcomed us. We arrived in Shanghai and did some round trip via famous
places like <a href="http://en.wikipedia.org/wiki/Hangzhou">Hangzhou</a>, the <a href="http://en.wikipedia.org/wiki/Mount_Huang">yellow mountains</a>, <a href="http://en.wikipedia.org/wiki/Guilin">Guilin</a>,
<a href="http://en.wikipedia.org/wiki/Xi%27an">Xi'an</a>, <a href="http://en.wikipedia.org/wiki/Pingyao">Pingyao</a>, the <a href="http://en.wikipedia.org/wiki/Hanging_Temple">hanging temple</a>, the <a href="http://en.wikipedia.org/wiki/Yungang_Grottoes">Yungang grottoes</a>
and <a href="http://en.wikipedia.org/wiki/Beijin">Beijing</a>. Like every tourist in China (mostly Chinese people) we
took a lot of pictures (\~1400) and had to cut the number down to
something bearable (\~300).</p>
<p>There are a few tricks we learned or used for our trip:</p>
<ul>
<li>They don't have a centralized IT system for the train bookings.
Train tickets can be purchased maximum 10 days before the departure,
but don't rush to the next station or you could be fooled! First you
need to pay 5 RMB more for each train ticket leaving from another
station. Then, if you still want to buy your ticket here, keep in
mind that they have only a small set of places: not all. Due to this
we had to take sleepers in the afternoon and hard seats in the night
for 7 hours long trips. Before taking that latter train we met an
Australian guy who bought sleepers the day before... but in the very
same city!</li>
<li>You can see all the train schedules online to plan your trip before
leaving (but you need to read a few chinese words):
<a href="http://www.huochepiao.com">http://www.huochepiao.com</a></li>
<li>To book the hotels, we used mostly <a href="http://english.ctrip.com/">ctrip</a> and <a href="http://www.jinjianginns.com">JinJiang Inns</a>.
The latter one is a cheap hotel brand, but you'll need to read
chinese to look for the hotels and book them</li>
<li>The CITS is a local travel agency present in almost every city. You
need to pay attention before purchasing something from them: we had
a quite bad tour in Guilin with them and a nice one around Datong.</li>
<li>Don't forget that long distance busses are also an interesting
travel option inside the country. It would have saved us a day by
train to go from the yellow mountains to Hangzhou.</li>
</ul>Word binary files dumper2010-08-24T17:22:00+02:002010-08-24T17:22:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-08-24:/word-binary-files-dumper.html<p>I have been away quite a long time for vacation: a one month
trip around China with my wife. I wanted to write some blog post, but I
still couldn't find time for it... but I have something cooking here
that is worth talking about. I have started to write …</p><p>I have been away quite a long time for vacation: a one month
trip around China with my wife. I wanted to write some blog post, but I
still couldn't find time for it... but I have something cooking here
that is worth talking about. I have started to write a small command
line tool showing the internals of .doc files. Thanks to <a href="http://poi.apache.org/">apache POI</a>
and the <a href="http://msdn.microsoft.com/en-us/library/cc313153%28v=office.12%29.aspx">file format specs</a>, it currently outputs quite nicely the
paragraphs and their runs as well as the field descriptors. This helps
me a lot to understand what is going on in the OpenOffice.org WW8 import
filter, but is currently not complete.</p>
<p>The sources are available under GPL v3 on this gitorious repository:
<a href="http://gitorious.org/ww8dumper/ww8dumper">http://gitorious.org/ww8dumper/ww8dumper</a>, feel free to propose some
patches to make is progress!</p>Thanks for the dev workshop2010-07-10T09:58:00+02:002010-07-10T09:58:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-07-10:/thanks-for-the-dev-workshop.html<p>The OpenOffice.org and Go-oo hacking workshop has been run
smoothly with some persons already in french community, but also some
curious people. In this post, I would like to thank all of the attendees
for their courage and patience. I hope to see them soon hacking OOo and
try …</p><p>The OpenOffice.org and Go-oo hacking workshop has been run
smoothly with some persons already in french community, but also some
curious people. In this post, I would like to thank all of the attendees
for their courage and patience. I hope to see them soon hacking OOo and
try to motivate others to join us. This workshop wouldn't have been
possible without the help of <a href="http://aquinetic.org/en">@aquinetic</a>, an non-profit-making
association who kindly provided us four virtual machines running on
their brand new computing farm.</p>
<p>We started to think about how that help could continue in the future.
@quinetic would provide us two virtual machines on that very same
environment. This way, volunteers with slow machines would be able to
hack OpenOffice.org more easily.</p>OOo hacking workshop at LSM2010-06-21T09:28:00+02:002010-06-21T09:28:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-06-21:/ooo-hacking-workshop-at-lsm.html<p>For those who wanted to start hacking OOo, I will organize a
hacking workshop at LSM in Bordeaux (France) on July, 7th. All the
details are <a href="http://2010.rmll.info/Workshop-Hack-OpenOffice-org-without-pain-well-not-too-much.html">on the LSM agenda</a>. I hope to meet you there to practice
what has already been started here. I also hope that this would …</p><p>For those who wanted to start hacking OOo, I will organize a
hacking workshop at LSM in Bordeaux (France) on July, 7th. All the
details are <a href="http://2010.rmll.info/Workshop-Hack-OpenOffice-org-without-pain-well-not-too-much.html">on the LSM agenda</a>. I hope to meet you there to practice
what has already been started here. I also hope that this would be a
nice occasion to kick off the creation of a developer team in the french
OOo NL project.</p>Hacking OOo for dummies (2)2010-06-18T15:52:00+02:002010-06-18T15:52:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-06-18:/hacking-ooo-for-dummies-2.html<p>I hope that you all had the time to get your favourite OOo
flavour built before that post. We will now enter the real hacking part.
In order to have some kind of example hack, I will use the<a href="http://www.openoffice.org/issues/show_bug.cgi?id=2838">issue #2838
about auto-correction replacements and caps</a>. We will need the …</p><p>I hope that you all had the time to get your favourite OOo
flavour built before that post. We will now enter the real hacking part.
In order to have some kind of example hack, I will use the<a href="http://www.openoffice.org/issues/show_bug.cgi?id=2838">issue #2838
about auto-correction replacements and caps</a>. We will need the
following steps to fix the bug:</p>
<ol>
<li>Locate the concerned code</li>
<li>Understand it and fix it</li>
<li>Create a patch</li>
</ol>
<h3>Show me the code!</h3>
<h4>How is it organized?</h4>
<p>First of all, you need to globally understand how the OpenOffice.org and
Go-oo source code is organized. We will start with the organization of
the OpenOffice.org sources as these will be included in Go-oo. There is
a lot of code in OpenOffice.org and has all been split into what are
often called modules. These are coming from the CVS days and are the
root folders of the OOo sources. You probably won't go through all of
them, then here are some important ones:</p>
<ul>
<li><strong>sw, sd, sc, starmath</strong>: these are containing the sources of the
main applications of OOo, respectively Writer, Impress/Draw, Calc
and Math</li>
<li><strong>sfx2, svx, svtools, editeng, svl, framework</strong>: these are
containing some common code to all the apps. A lot of interesting
stuffs are sitting here</li>
<li><strong>offapi</strong>: contains all the IDL files for the UNO API definition</li>
<li><strong>xmloff</strong>: contains the ODF filters code</li>
<li><strong>instsetoo_native</strong>: is the top module needing all the others.
It's the one doing the final packaging</li>
<li><strong>solenv</strong>: contains the build macros and tools</li>
</ul>
<p>For the other modules, the best is to discover them once you'll need
them. There is a special folder named <strong>solver</strong> gathering all the build
results: of course this is not really a module. You can just ignore
everything in the <strong>binfilter</strong> as this is quite old and more or less
duplicated code.</p>
<p>On the Go-oo side, things are pretty much the same, expect that the
upstream sources are contained in the <strong>build</strong> directory. The folder
name is the milestone name and is looking like <strong>dev300-mXX</strong> or
<strong>oooXXX-mYY</strong>. Here are the important folders for Go-oo sources:</p>
<ul>
<li><strong>build</strong>: contains all the build results, including the upstream
sources unpacked and patched</li>
<li><strong>patches</strong>: contains the patches to apply. The
<strong>patches/dev300/apply</strong> file describes which patch to apply during
the build</li>
<li><strong>src</strong>: contains all the needed sources before unpacking them</li>
<li><strong>bin</strong>: contains the scripts used to build the sources as well as
some other useful tools</li>
<li><strong>doc</strong>: contains some hackers notes and patches to explain some
parts of the code</li>
</ul>
<h4>How do I find the code I need to hack?</h4>
<p>One of the easy ways to find some piece of code is to use the UI
strings. It's much better to use an en-US build (the default one) to
ease the task. In the case of the #2838 bug, here are a few steps
leading to useful infos:</p>
<ol>
<li>Run OpenOffice.org and open the <strong>Tools > Autocorrect options</strong>
menu. Then go to the <strong>Options</strong> tab. The string "<strong>Use replacement
table</strong>" is very likely to lead us to the option enabling the
replacement... and then to the replacement code itself.</li>
<li>In <a href="http://svn.services.openoffice.org/opengrok/">opengrok</a>, run a full search with that string. Don't forget
to add the double quotes to restrict the results. For the OpenGrok
search you need to specify the milestone of your sources; in most of
the cases there won't be any big difference... but who knows?</li>
<li>Spot the .src files in the results of the previous search: these are
containing the messages in en-US for the UI. In our case there are
two of them: one in sw and the other in cui (or svx for ooo320-mXX
milestones). A search of the identifier of the string
(<strong>ST_USE_REPLACE</strong> in our case) will help you to find in which
cxx file this string is used (<strong>cui/source/tabpages/autocdlg.cxx</strong>
in our case).</li>
<li>Now that we have some starting point in the code, we can read the
surrounding code to find out the interesting place to hack. In our
case, the UI string is used in the <strong>OfaSwAutoFmtOptionsPage</strong> class
representing the tab page of the dialog. This class is using
<strong>SvxSwAutoFmtFlags::bAutoCorrect</strong> and <strong>SvxAutoCorrect</strong> to store
the option: searching for them in the code will lead us to the code
actually doing the replacement.</li>
<li>Using that method we discovered that all the auto-corrections are
applied in <strong>SwAutoFormat::AutoCorrect</strong> and
<strong>SvxAutoCorrect::AutoCorrect</strong> methods. We now only have to
implement the changes in the methods
<strong>SwAutoCorrDoc::ChgAutoCorrWord</strong> and
<strong>SvxAutoCorrDoc::ChgAutoCorrWord</strong>.</li>
</ol>
<h3>Understanding the code and fixing it</h3>
<p><strong>If you are hacking Go-oo, you need to run some commands before
changing any line in the code. Jump to the next section to ease your
life!</strong></p>
<h4>ctags, opengrok and doxygen</h4>
<p>Understanding the code means being able to get the correct infos about
the surrounding code. There are several tools to help the developer in
that task. I'm mostly using ctags and the <a href="http://docs.go-oo.org/">go-oo doxygen
documentation</a> (and of course OpenGrok) to understand the OOo code. To
easily navigate in the source code, I usually create a ctags database
and use it in VIm (you can use it in Emacs as well but I don't know how
it works).</p>
<p>In any case installing ctags in mandatory:</p>
<div class="highlight"><pre><span></span><code>sudo zypper in ctags
</code></pre></div>
<p>To create your ctags database, on Go-oo:</p>
<div class="highlight"><pre><span></span><code>make tags
</code></pre></div>
<p>On OpenOffice.org you will need to do basically the same, but for this
you will need to <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/bin/create-tags">download the script</a> and run it from the root folder
of the sources.</p>
<p>Then in VIm you can use <strong>Ctrl+]</strong> to jump to the definition of the
selected type, and <strong>Ctrl+T</strong> to jump back to the previous place. The
command <strong>:ts SomeType</strong> will also give all the matching places found in
the ctags database. Generating the tags database will also allow you to
have automatic completion in VIm thanks to <a href="http://www.vim.org/scripts/script.php?script_id=1520">OmniCppComplete</a>. You
should search for the <a href="/tag/vim.html">previous VIm tips</a> I posted: they are really
useful when hacking OOo.</p>
<p>For VIm to find your tags file, don't forget to add this to your
<strong>\~/.vimrc</strong> file:</p>
<div class="highlight"><pre><span></span><code><span class="s2">" Tags files are searched first relative to the current file, then relative to</span>
<span class="s2">"</span> the current working directory, and last in the <span class="nv">$HOME</span> directory.
<span class="nb">set</span> <span class="nv">tags</span><span class="o">=</span>./tags,./../tags,./../../tags,./../../../tags,./../../../../tags,./../../../../../tags,tags,../tags,../../tags,../../../tags,../../../../tags,../../../../../tags,~/tags
</code></pre></div>
<h4>Hacking</h4>
<p>After the hack you will need to rebuild and test. There is no need to
rebuild everything as mentioned in the previous blog post. You will only
need to rebuild the modules you have changed. Of course some modules are
dependents and you may need to rebuild more modules. Before anything you
need to setup the environment variables for building OpenOffice.org. If
you are hacking Go-oo it all happens in the <strong>build/\<milestone></strong>
folder containing the upstream sources.</p>
<p>To setup the environment:</p>
<div class="highlight"><pre><span></span><code>. Linux*Env.Set.sh
</code></pre></div>
<p>Go into the module to rebuild and run the following command. Note that
the arguments provided here are useless is you aren't building with
icecream:</p>
<div class="highlight"><pre><span></span><code>build -P6 -- -P6
</code></pre></div>
<p>Now the hacked sources are built and the result have been generated in
the <strong>\$INPATH</strong> folder of the module. If you are hacking Go-oo there is
nothing more to do to test as the dev-install links to these folders. If
you are hacking vanilla OpenOffice.org you need to copy the .so and .res
files at the appropriate place in the installation (adding the writing
permission to your user on the existing files will certainly be needed).</p>
<p>In any case, if you want to be sure that all the dependent modules are
rebuilt, you need to run the following command in the
<strong>instsetoo_native</strong> module (and reinstall OOo for the upstream
version):</p>
<div class="highlight"><pre><span></span><code>build --all -P6 -- -P6
</code></pre></div>
<h4>Debugging</h4>
<p>Debugging is often necessary to see what is going wrong. As you may have
seen, we haven't used the configure options to build the debug symbols:
that was on purpose to avoid building loads of unnecessary build symbols
(they use place on the hard disk and take time during the build). Here
is how to get them for a given module.</p>
<p>First remove the output folder for the module</p>
<div class="highlight"><pre><span></span><code>rm -r <span class="nv">$INPATH</span>
</code></pre></div>
<p>Then rebuild with the debug symbols</p>
<div class="highlight"><pre><span></span><code>build <span class="nv">debug</span><span class="o">=</span>t -P6 -- -P6
</code></pre></div>
<p>Now that the symbols are generated, you will be able to use gdb to
actually debug. The goal of this tutorial isn't to make a master
debugger of you, but here are some useful commands and tips.</p>
<ul>
<li>You can find a <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/scratch/writer/gdbinit-cbosdo">copy of my .gdbinit file</a> on Go-oo git repository.
It contains useful functions grabbed here and there. Have a close
look at the <strong>ptu</strong> and pou functions: they will help you printing
OpenOffice.org strings (which aren't just <strong>char*</strong>).</li>
<li>To start gdb with OOo, go to the program folder of your install and
run <strong>gdb ./soffice.bin</strong>. If you are running a dev-install of
Go-oo, sourcing <strong>ooenv</strong> is mandatory before that.</li>
<li>To place a breakpoint, use the <strong>b</strong> command in gdb. The easiest way
is to give the filename and line where to stop, for example:<strong>b
doc.cxx:501</strong></li>
<li>The basic commands to know are <strong>run</strong>, <strong>step</strong>, <strong>next</strong>,
<strong>continue</strong> and <strong>print</strong>. I hope their names are clear enough for
you (or you will need to read gdb help).</li>
</ul>
<p>You can find a lot of debugging tricks on the <a href="http://www.freedesktop.org/wiki/Software/ooo-build/DebuggingIt">Go-oo DebuggingIt
page</a>.</p>
<h3>Creating the patch</h3>
<p>Now that you have hacked OOo to get your feature implemented, you will
need a patch to show to the other devs. This will be done differently
depending if you are hacking OpenOffice.org or Go-oo. Note that for
Go-oo users you need to run some commands before actually hacking.</p>
<h4>The OpenOffice.org way</h4>
<p>As the sources your have hacked are a local mercurial repository, you
simply need to go through the following steps:</p>
<div class="highlight"><pre><span></span><code>hg add path/to/each/new/file
hg commit <span class="c1">#You will need to type a message after that</span>
hg <span class="nb">export</span> tip >myhack.diff
</code></pre></div>
<p>The last command may need to vary if you ran several commits.</p>
<h4>The Go-oo way</h4>
<p>Before changing anything in the code, we need to create a new git
repository in the <strong>build/\<milestone></strong> folder: that will simplify the
patch creation later.</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> build/<milestone>
../../bin/create-gitignores.sh <span class="o">&&</span> git add . <span class="o">&&</span> git commit -m <span class="s2">"initial commit"</span> <span class="o">&&</span> git checkout -b myhack
</code></pre></div>
<p>Now everything is ready: you can hack quietly and continue with these
steps when your changes are ready to be shown to the world.</p>
<div class="highlight"><pre><span></span><code>git add path/to/each/new/file
git commit -a <span class="c1">#You will need to type a message after that</span>
git diff --no-prefix master >myhack.diff
</code></pre></div>
<p>In this case you will be working in a new branch and keep the master
branch untouched. You can commit as may times as you want the command to
create the diff will always be the same. There are plenty of ways to
handle the patches; a very nice one is described by <a href="http://freedesktop.org/wiki/ThorstenBehrens">Thorsten using
stg</a>.</p>
<p>The most complex task is left to you: getting familiar with the parts of
the OOo code interesting you. Of course nobody knows it all (or I would
really be impressed), but the more you hack, the more you will learn.
Don't forget to ask other developers on IRC or on mailing lists: others
can often have ideas to help you.</p>
<p>I still haven't really though about the next step, stay tuned...</p>Asian phonetic guide and doc export2010-06-16T17:57:00+02:002010-06-16T17:57:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-06-16:/asian-phonetic-guide-and-doc-export.html<p>In a <a href="https://bosdonnat.fr/asian-phonetic-guide-exported-in-docx.html">previous post</a> I was mentioning a bug in the asian
phonetic guide export to doc files. I finally fixed that one and
discovered that this is corresponding to upstream issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=79246">#79246</a>
(nearly 3 years old and 6 votes). The fix has been committed to the
<a href="http://cgit.freedesktop.org/ooo-build/ooo-build/commit/?id=0b5a7478bdd7fd1be304e9cb2b395ac7f42f9c61">master branch of …</a></p><p>In a <a href="https://bosdonnat.fr/asian-phonetic-guide-exported-in-docx.html">previous post</a> I was mentioning a bug in the asian
phonetic guide export to doc files. I finally fixed that one and
discovered that this is corresponding to upstream issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=79246">#79246</a>
(nearly 3 years old and 6 votes). The fix has been committed to the
<a href="http://cgit.freedesktop.org/ooo-build/ooo-build/commit/?id=0b5a7478bdd7fd1be304e9cb2b395ac7f42f9c61">master branch of the ooo-build</a> git repository and <a href="http://hg.services.openoffice.org/cws/cbosdo06/rev/9594519420b0">cbosdo06 CWS</a>.
This fix should be available in 3.3 for both ooo-build and
upstream.</p>Hackweek 2010 is over2010-06-14T11:25:00+02:002010-06-14T11:25:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-06-14:/hackweek-2010-is-over.html<p>Here at Novell, most of us developers were enjoying the
Hackweek #5 last week. I decided to continue improving the Evolution
maps integration I started some times ago. Last week I added the
following new features:</p>
<ul>
<li>Define a postal address as the location of a meeting / appointment</li>
<li>Show a meeting …</li></ul><p>Here at Novell, most of us developers were enjoying the
Hackweek #5 last week. I decided to continue improving the Evolution
maps integration I started some times ago. Last week I added the
following new features:</p>
<ul>
<li>Define a postal address as the location of a meeting / appointment</li>
<li>Show a meeting on a map if the location can be parsed as a postal
address</li>
<li>Show the selected contacts of an address book on a map</li>
<li>Show all the different addresses of a single contact on a map</li>
</ul>
<p>There are still some things to improve:</p>
<ul>
<li>The focus chain in the address dialog isn't completely correct</li>
<li>Only US-formatted addresses are parsed in the location string. I
started some generic parsing code based on regular expressions, but
this is still not finished. <strong>Don't hesitate to send me a regexp to
parse the postal addresses in your country!</strong></li>
</ul>
<p>Here are some screenshots for you to better see the features before they
arrive on your desktop.</p>
<p><a href="https://bosdonnat.fr/data/evomap-location-details.png"><img alt="Location details dialog" src="https://bosdonnat.fr/data/evomap-location-details-300x158.png"></a></p>
<p>Location details dialog</p>
<p><a href="https://bosdonnat.fr/data/evomap-popup-menu.png"><img alt="The action to show the map of a meeting" src="https://bosdonnat.fr/data/evomap-popup-menu-255x300.png"></a></p>
<p>The action to show the map of a meeting</p>
<p><a href="https://bosdonnat.fr/data/evomap-map-meeting.png"><img alt="Appointment location on a map" src="https://bosdonnat.fr/data/evomap-map-meeting-300x234.png"></a></p>
<p>Appointment location on a map</p>
<p><a href="https://bosdonnat.fr/data/evomap-map-contact.png"><img alt="Map showing the addresses of a contact" src="https://bosdonnat.fr/data/evomap-map-contact-294x300.png"></a></p>
<p>Map showing the addresses of a contact</p>Viewing doc, xls and ppt files in Vim2010-05-28T11:37:00+02:002010-05-28T11:37:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-05-28:/viewing-doc-xls-and-ppt-files-in-vim.html<p>As I was tired of always using some custom C program using
<em>libgsf</em> to dump each of the doc files I was studying before viewing it
in Vim, I decided to add some Vim configuration for it to do it
automatically. This post will explain how to do that.</p>
<p>In …</p><p>As I was tired of always using some custom C program using
<em>libgsf</em> to dump each of the doc files I was studying before viewing it
in Vim, I decided to add some Vim configuration for it to do it
automatically. This post will explain how to do that.</p>
<p>In your <strong>.vimrc</strong> file, add the following line:</p>
<div class="highlight"><pre><span></span><code>autocmd <span class="nb">BufReadCmd</span> *.doc<span class="p">,</span>*.xls<span class="p">,</span>*.ppt exe <span class="s2">":silent 1,$!gsf-dump %"</span> <span class="p">|</span> <span class="k">setlocal</span> <span class="nb">buftype</span><span class="p">=</span>nofile
</code></pre></div>
<p>This is calling a script <em>gsf-dump</em> on the currently edited file,
replaces the buffer content by the dump result and tells the buffer that
its not showing a file. This last part will avoid you to writer the dump
in the original file. The <em>gsf-dump</em> program was first a custom C
application using <em>libgsf</em>, but I replaced it by a bash script to
simplify the installation for you. On openSUSE 11.2, you need to install
the <strong>libgsf</strong> package (the name may vary for other distributions). Here
is the shell script to name <strong>gsf-dump</strong>:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span>
<span class="k">if</span> <span class="o">[[</span> <span class="nv">$#</span> !<span class="o">=</span> <span class="m">1</span> <span class="o">]]</span>
<span class="k">then</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$0</span><span class="s2"> FILE"</span>
<span class="nb">echo</span> <span class="s2">" FILE is the GSF archive to dump"</span>
<span class="nb">exit</span> <span class="m">1</span>
<span class="k">fi</span>
gsf list <span class="nv">$1</span> <span class="p">|</span> <span class="k">while</span> <span class="nb">read</span> -r typ sz name
<span class="k">do</span>
<span class="k">if</span> <span class="o">[[</span> <span class="s2">"</span><span class="nv">$typ</span><span class="s2">"</span> <span class="o">==</span> <span class="s2">"f"</span> <span class="o">]]</span>
<span class="k">then</span>
gsf dump <span class="nv">$1</span> <span class="nv">$name</span>
<span class="k">fi</span>
<span class="k">done</span>
</code></pre></div>
<p>Now you can use directly <strong>vim file.doc</strong> or <strong>vim -d file1.doc
file2.doc</strong> to inspect the doc files.</p>Hacking OOo for dummies (1)2010-05-27T16:02:00+02:002010-05-27T16:02:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-05-27:/hacking-ooo-for-dummies-1.html<p>This is the first of the serie of posts to introduce OOo
development. It will be all about getting ready to hack, which means
getting the sources, installing the dependencies and building the
sources. The commands here are provided for openSUSE 11.2: you will
certainly need to adapt them …</p><p>This is the first of the serie of posts to introduce OOo
development. It will be all about getting ready to hack, which means
getting the sources, installing the dependencies and building the
sources. The commands here are provided for openSUSE 11.2: you will
certainly need to adapt them to your distribution.</p>
<h3>Getting the sources</h3>
<p>The sources are organized differently in upstream OpenOffice.org (the
official version) and Go-oo. Upstream sources are stored in a mercurial
repository and the development branches are called CWS (Child
WorkSpace). The code integration process is pretty different from Go-oo
where the sources are mainly composed of patches to apply on the
upstream sources. Those patches are stored in a git repository. For the
rest of the serie, I'll consider that the upstream sources are located
on <em>\~/upstream</em> and the Go-oo sources on <em>\~/go-oo</em> on your machine.</p>
<h4>The OpenOffice.org way</h4>
<p>First install Mercurial:</p>
<div class="highlight"><pre><span></span><code>sudo zypper in mercurial
</code></pre></div>
<p>Extract a clean copy of the sources in a folder that will never be
touched. In fact, you will see that the created directory only contains
a hidden folder and no source. I usually do this way to spare some
bandwidth because downloading all the sources is quite a long operation.</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> ~/upstream
hg clone -U http://hg.services.openoffice.org/DEV300 local_DEV300
</code></pre></div>
<p>This operation takes a really long time, you can go out and do some
sport (or whatever you like). After it is completed, you can see a
<em>local_DEV300</em> folder containing nothing but a hidden folder. This
contains a copy of the sources hosted on the OpenOffice.org servers. The
interest here is that you won't need to get everything when you will
need to update that copy with the latest sources... and then you'll need
to do less sport the next times!</p>
<p>In order to extract sources to build and hack, you will need to
duplicate the downloaded sources in another folder. It will be
<em>\~/upstream/myhack</em> in that tutorial. You will then be able to safely
hack in that folder and keep the previous one clean for the sources
updates.</p>
<div class="highlight"><pre><span></span><code>hg clone local_DEV300 myhack
</code></pre></div>
<p>You are now ready to move to the build step.</p>
<h4>The Go-oo way</h4>
<p>First install Git:</p>
<div class="highlight"><pre><span></span><code>sudo zypper in git
</code></pre></div>
<p>Extract the latest sources:</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> ~/go-oo
git clone git://anongit.freedesktop.org/git/ooo-build/ooo-build
</code></pre></div>
<p>Note that the master branch is unstable and may not build. You should
<a href="http://go-oo.org/developers/">ask the developers on IRC or on the mailing-list</a> to check if the
master is usable at that time. Otherwise, you may prefer to extract the
sources of a stable branch. See the Go-oo wiki for more informations on
<a href="http://freedesktop.org/wiki/Software/ooo-build/GettingIt#Gettingaparticularbranch">how to get a particular branch</a>. The sources are now happily sitting
in a newly created <em>ooo-build</em> folder: you can move to the next step!</p>
<h3>Building</h3>
<p>In order to build you will need a lot of packages and dependencies. This
step only needs to be done once for each machine you are building on. On
openSUSE there is a nice trick to quickly install most of the
dependencies for building OpenOffice.org or Go-oo:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Enable the openSUSE sources package repository</span>
sudo zypper mr -r repo-source
<span class="c1"># Install the dependencies</span>
sudo zypper si -d OpenOffice_org-bootstrap
</code></pre></div>
<p>Some dependencies will certainly be still missing as this install the
ones to build the OOo version shipped with openSUSE and we will build a
new version in most of the cases. Here is a command to install the
missing dependencies (for the current versions)</p>
<div class="highlight"><pre><span></span><code>sudo zypper in java-1_6_0-sun-devel junit4
</code></pre></div>
<p>As the Java JDK installation has updated some script run for each new
shell you need to open a new shell to continue.</p>
<p>In order to speedup the build if you have a multi-core machine or
several machines, you should carefully read <a href="http://people.gnome.org/~michael/blog/icecream.html">Michael's blog post on
icecream</a>. The steps after starting the daemon aren't necessary for
our cases: this needs to be adapted to OpenOffice.org build system (or
won't be needed for Go-oo). Icecream will allow you to build on
several cores / machines at the same time and then gain precious time.
If you have a default installation of openSUSE, don't forget to change
the firewall settings by either turn it off or add the rules to allow
icecream through it.</p>
<h4>The OpenOffice.org way</h4>
<p>In order to configure the build you need to issue the following
commands. Of course you can add some more parameters to the configure to
spare some build time.</p>
<div class="highlight"><pre><span></span><code>./configure --with-use-shell<span class="o">=</span>bash --disable-build-mozilla
touch external/unowinreg/unowinreg.dll
</code></pre></div>
<p>Copy the mozilla binaries from the page
<a href="http://tools.openoffice.org/moz_prebuild/OOo3.2/">http://tools.openoffice.org/moz_prebuild/OOo3.2/</a> into the
<em>\~/upstream/myhack/moz/zipped</em> folder. The files to copy are depending
on the architecture you are building on. Read carefully the error
message of the configure to know which files to download and restart the
configure command. Once the configuration is finished, you need to run
the following commands:</p>
<div class="highlight"><pre><span></span><code>./bootstrap
. Linux*Env.Set.sh
</code></pre></div>
<p>Note that the last command has to be issued any time you need to build
some part of the OpenOffice.org sources: it sets a whole lot of
environment variables used during the build. Without having run that
command the <em>build</em> tool won't be found in the <em>PATH</em>. The first command
generally needs to be called only at the first build.</p>
<p>For the ones who are going to perform a parallel build using icecream,
the following commands are needed to build:</p>
<div class="highlight"><pre><span></span><code><span class="nb">export</span> <span class="nv">CXX</span><span class="o">=</span>/opt/icecream/bin/g++
<span class="nb">export</span> <span class="nv">CC</span><span class="o">=</span>/opt/icecream/bin/gcc
<span class="nb">cd</span> instsetoo_native
build --all -P6 -- -P6
</code></pre></div>
<p>For others simply run</p>
<div class="highlight"><pre><span></span><code>make
</code></pre></div>
<h4>The Go-oo way</h4>
<p>The first thing to do is to configure the build. The arguments I'm using
here are really generic: I usually don't build the KDE parts and some
others to avoid installing some more dependencies. If you didn't install
<em>icecream</em> in the previous step you can remove the corresponding
options. The max jobs option specifies the maximum number of parallel
jobs to run during the build.</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> ooo-build
</code></pre></div>
<p>./autogen.sh --with-distro=SUSE-11.2 --with-gcc-speedup=icecream --with-max-jobs=6</p>
<p>Now that the build is configured you can download the upstream sources
needed to apply Go-oo patches. This step takes a while the first time
and much less the next times as it uses git to download the upstream
sources.</p>
<div class="highlight"><pre><span></span><code>./download
</code></pre></div>
<p>Then you can actually build the sources using Gnu make. There is nothing
to worry about the parallel build: the makefiles will handle it for you
if you have used the proper options for the configure step.</p>
<div class="highlight"><pre><span></span><code>make
</code></pre></div>
<h3>After the build</h3>
<p>Keep an eye on the build as this will take a lot of time and can break
if there is something wrong in the sources or with your configuration.
Now that your sources are built, you will need to learn how to hack
OpenOffice.org. In the mean time you will certainly want to play with
your freshly built toy. Here are some details about it.</p>
<h4>The OpenOffice.org way</h4>
<p>The quickest way is to follow <a href="http://blogs.sun.com/GullFOSS/entry/the_fastest_way_to_get">that blog post</a>.</p>
<div class="highlight"><pre><span></span><code><span class="nb">export</span> <span class="nv">LOCALINSTALLDIR</span><span class="o">=</span>~/upstream/myhack-install
<span class="nb">cd</span> ~/upstream/myhack/instsetoo_native/util
dmake openoffice_en-US <span class="nv">PKGFORMAT</span><span class="o">=</span>installed
</code></pre></div>
<p>To run the freshly installed OpenOffice.org:</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> ~/upstream/myhack-install/openoffice.org3/program
./soffice.bin
</code></pre></div>
<p>Note that this installation copies all the needed files from the build
tree. If anything changed in the sources, you will need to copy the
changed files from the build to the installation.</p>
<h4>The Go-oo way</h4>
<p>Go-oo provides some useful tricks to install a development instance. By
running the following command you will have an OOo installed in
\~/go-oo/ooo-build/build/install and the files of this install will be
linked to the corresponding files in the build tree. Thus after a change
and rebuild of the sources, there is nothing to do to have an updated
install.</p>
<div class="highlight"><pre><span></span><code>make dev-install
</code></pre></div>
<p>To run the installed OOo, you need to source the <em>ooenv</em> file. Here is
how to do it:</p>
<div class="highlight"><pre><span></span><code><span class="nb">cd</span> ~/go-oo/ooo-build/build/install/program
. ooenv
./soffice.bin
</code></pre></div>
<p>Happy building until the next step!</p>OOo francophone hackers group2010-05-20T22:12:00+02:002010-05-20T22:12:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-05-20:/ooo-francophone-hackers-group.html<p>For some times, I'm fixing some simple bugs in OpenOffice.org. I'm
starting to think that, with some help, any C++ developer could dive
into OOo's code to fix such bugs. This would help the project to go even
faster and bring some more connections between the users and the …</p><p>For some times, I'm fixing some simple bugs in OpenOffice.org. I'm
starting to think that, with some help, any C++ developer could dive
into OOo's code to fix such bugs. This would help the project to go even
faster and bring some more connections between the users and the
developers. I find it pretty hard to believe that there are only two
developers among the OOo francophone NL project members. In order to
verify that, I decided to create some OOo hackers group inside the Fr NL
project. The principle is easy: experienced developers are mentoring the
newcomers. This small team will discuss the bugs and features it will
want to fix or implement inside the Fr project. The criteria for the bug
selection are simple too: first take the issues in IssueZilla with
numerous votes and the oldest ones. If you want to join that starting
team, don't hesitate: jump in and send an email to present yourself to
the dev@fr.openoffice.org mailing list. The interest to keep that team
in the French NL project is that people who aren't comfortable with
english will be able to be helped.</p>
<p>As all this small world will need to find some useful documentation to
get the sources, build and hack OOo, I'll start a blogs posts / tutorial
serie explaining how to do that. As I'm also a member of the Go-oo team,
I'll of course give the details for the vanilla version of OOo, but also
for Go-oo: this way everybody will be happy! All my machines are running
openSUSE 11 or SLED 11 (guess why ;) ): then I'll provide the commands
for this linux distribution... you are free to post comments for the
other distros.</p>
<p>Until next time for the first step: <em>Get the sources and build...</em></p>Asian phonetic guide exported in Docx2010-05-10T15:42:00+02:002010-05-10T15:42:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-05-10:/asian-phonetic-guide-exported-in-docx.html<p>The asian phonetic guide is a useful feature when learning an
asian language. Last week I worked on writing it in the docx files. The
feature is now happily sitting in the <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/docx-fixes02.diff">docx-fixes02.diff</a> patch in the
go-oo git repository. Here are some screenshots of the feature in Word
and …</p><p>The asian phonetic guide is a useful feature when learning an
asian language. Last week I worked on writing it in the docx files. The
feature is now happily sitting in the <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/docx-fixes02.diff">docx-fixes02.diff</a> patch in the
go-oo git repository. Here are some screenshots of the feature in Word
and OpenOffice.org for those eager to see what it is.</p>
<p><img alt="Phonetic guide in OOo" src="https://bosdonnat.fr/data/ruby-ooo.png"></p>
<p>Phonetic guide in OOo</p>
<p><img alt="Phonetic guide reopened in word" src="https://bosdonnat.fr/data/ruby-word-fix.png"></p>
<p>Phonetic guide reopened in word</p>
<p>The phonetic guide configuration options in OpenOffice.org and Word
aren't the same. What is working here is the export of the text with
it's usual properties and the alignement of the pronounciation. Note
that the characters on the above sample are grouped in the OOo dialog,
but not when opening Word's dialog: this comes from the different color
setting applied to one of the characters.</p>
<p>When testing this code, I also discovered a strange compatibility issue
between Word 97 and Word 2007 when opening the .doc version of the file:</p>
<ul>
<li>For Word 97, the field for the ruby text in the doc file needs to be
{ EQ \* jc0 \* "Font:Arial" \* hps12 \o(\s\up
10(kong3zi); 孔子 ) }*</li>
<li>For Word 2007, the field for the ruby text in the doc file needs to
be { EQ \* jc0 \* "Font:Arial" \* hps12 \o(\s\up
10(kong3zi), 孔子 ) }*</li>
</ul>
<p>Then when saving a file with a phonetic guide in Word 97 and opening it
in Word 2007, all the fields need to be changed to have commas as
function parameters separator (instead of
semi-colon).</p>Windows 7, Office 2010 and user freedom2010-05-07T11:49:00+02:002010-05-07T11:49:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-05-07:/windows-7-office-2010-and-user-freedom.html<p>As I needed to perform some tests on Windows 7 and Office 2010
these days and I had two interesting surprises.</p>
<ol>
<li>Office 2010 asks the user to choose between ODF and OOXML as default
storing format.</li>
<li>Windows 7 asks which Web browser to use / install</li>
</ol>
<p>Here are two screenshots to …</p><p>As I needed to perform some tests on Windows 7 and Office 2010
these days and I had two interesting surprises.</p>
<ol>
<li>Office 2010 asks the user to choose between ODF and OOXML as default
storing format.</li>
<li>Windows 7 asks which Web browser to use / install</li>
</ol>
<p>Here are two screenshots to show these choices... they may be biased but
at least they are existing.</p>
<p><img alt="Office 2010 format choice" src="http://static.pcinpact.com/images/bd/news/mini-80584-office-2010-ballot-screen.png"></p>
<p>Office 2010 format choice</p>
<p><a href="https://bosdonnat.fr/data/win7-browser.png"><img alt="Windows 7 browser choice" src="https://bosdonnat.fr/data/win7-browser-300x166.png"></a></p>
<p>Windows 7 browser choice</p>
<p>I hope more people will then install Firefox on Windows and make it
their default web browser.... but the most interesting point is about
Office 2010: OpenOffice.org marketing centered on ODF support won't make
the difference by now. We need to focus much more on:</p>
<ul>
<li><strong>innovating features</strong>. Copying what Office 2010 does is good to
ensure compatibility, but we need to keep adding some useful
features that aren't yet in Office 2010 for users to find something
interesting in the OpenOffice.org product.</li>
<li>the <strong>values of open source and community</strong> as that's our main
differenciator. How could we as a community show to the users that
they have something to gain to contact us and be part of the
adventure?</li>
</ul>Asian layout export improved2010-04-29T15:27:00+02:002010-04-29T15:27:00+02:00Cédrictag:bosdonnat.fr,2010-04-29:/asian-layout-export-improved.html<p>I recently had a look at the .docx export of the document grid
for asian characters. It was not implemented at all and the .doc export
was buggy. After some time constantly not skipping a word in the OOXML
specifications, I finally had a working implementation and could fix the …</p><p>I recently had a look at the .docx export of the document grid
for asian characters. It was not implemented at all and the .doc export
was buggy. After some time constantly not skipping a word in the OOXML
specifications, I finally had a working implementation and could fix the
.doc export. Here are some screenshots to help you understand what I'm
writing about. Mind the number of asian characters per line...</p>
<p><a href="https://bosdonnat.fr/data/grid-ooo.png"><img alt="The layout in OOo" src="https://bosdonnat.fr/data/grid-ooo-300x252.png"></a></p>
<p>The layout in OOo</p>
<p><a href="https://bosdonnat.fr/data/grid-doc-bug.png"><img alt="The buggy layout in Word" src="https://bosdonnat.fr/data/grid-doc-bug-300x300.png"></a></p>
<p>The buggy layout in Word</p>
<p><a href="https://bosdonnat.fr/data/grid-docx-fix.png"><img alt="The layout in Word after the changes" src="https://bosdonnat.fr/data/grid-docx-fix-300x296.png"></a></p>
<p>The layout in Word after the changes</p>
<p>The fix is already available on the <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/">master branch of ooo-build git
repo</a>.</p>How to filter posts of an RSS feed in Liferea2010-04-26T13:46:00+02:002010-04-26T13:46:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-04-26:/how-to-filter-posts-of-an-rss-feed-in-liferea.html<p>I really turned annoyed by some posts in an RSS feed, because
there were a lot of them and I usually never read them. I wanted to
filter them out of the RSS feed automatically in Liferea. I found out
that this RSS reader can use scripts to filter the …</p><p>I really turned annoyed by some posts in an RSS feed, because
there were a lot of them and I usually never read them. I wanted to
filter them out of the RSS feed automatically in Liferea. I found out
that this RSS reader can use scripts to filter the RSS: I then decided
to create some bash script to achieve my goal. The principle is really
easy: generate some XSL file, apply it on the feed and remove it. The
script receives the feed on the standard input and has to provide the
filtered feed on the standard output.</p>
<p>Some infos about the filtering scripts and how to apply them are
available in <a href="http://liferea.sourceforge.net/scraping.htm">Liferea's documentation</a>.</p>
<p>Here is the script filtering on the start of the title element:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/sh</span>
cat >> /tmp/<span class="nv">$$</span>.xsl <span class="s"><< EOF</span>
<span class="s"><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"</span>
<span class="s"> xmlns:dc="http://purl.org/dc/elements/1.1/"></span>
<span class="s"> <xsl:template match="node()|@*"></span>
<span class="s"> <xsl:copy></span>
<span class="s"> <xsl:apply-templates select="@*|node()"/></span>
<span class="s"> </xsl:copy></span>
<span class="s"> </xsl:template></span>
<span class="s">EOF</span>
<span class="c1"># One element per line before EOF </span>
<span class="k">while</span> <span class="nb">read</span> blacklisted
<span class="k">do</span>
<span class="nb">echo</span> <span class="s2">"<xsl:template match=\"//item[starts-with( title, '</span><span class="nv">$blacklisted</span><span class="s2">' )]\"/>"</span> >> /tmp/<span class="nv">$$</span>.xsl
<span class="k">done</span> <span class="s"><< EOF</span>
<span class="s">Blacklisted post</span>
<span class="s">No thanks</span>
<span class="s">EOF</span>
<span class="nb">echo</span> <span class="s2">"</xsl:stylesheet>"</span> >> /tmp/<span class="nv">$$</span>.xsl
xsltproc /tmp/<span class="nv">$$</span>.xsl -
rm /tmp/<span class="nv">$$</span>.xsl
</code></pre></div>Learning chinese alone2010-03-31T18:06:00+02:002010-03-31T18:06:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2010-03-31:/learning-chinese-alone.html<p>I recently decided to learn chinese again. I took chinese
lessons at the engineering school, but forgot almost everything!
Hopefully I still have the lessons and I have found a cool on-line
chinese course with audio samples on <a href="http://www.chinese-tools.com/">chinese-tools.com</a>... but I
needed some way to monitor my progresses in …</p><p>I recently decided to learn chinese again. I took chinese
lessons at the engineering school, but forgot almost everything!
Hopefully I still have the lessons and I have found a cool on-line
chinese course with audio samples on <a href="http://www.chinese-tools.com/">chinese-tools.com</a>... but I
needed some way to monitor my progresses in vocabulary learning. I
quickly checked if there was some vocabulary training tool for Gnome but
couldn't find any satisfying tool. I thus decided to start my own tool.
As I wanted to learn GTK+ and C# Mono for quite a long time, I have
installed monodevelop and started coding. The sources are available
under GPL on <a href="http://gitorious.org/mylangteacher/mylangteacher">gitorious</a> but I'm not providing any binary yet: those
who want it will need to build it using monodevelop.</p>
<p>Here is a list of the current features, though they might change
quickly:</p>
<ul>
<li>Definition of a sequence of lessons containing the vocabulary</li>
<li>The words can be grouped in some tags using drag and drop. This
helps to sort the words by lexical field (which is not always the
case in the lessons)</li>
<li>A word is composed of the term in the learned language, its
pronunciation and the translation in your language</li>
<li>Double clicking a word shows some details on it. For the moment,
they only include the strokes order for the CJK characters, but we
can easily imagine some connection with an on-line dictionary
showing synonyms or examples. The strokes order images are directly
fetched from the <a href="http://commons.wikimedia.org/wiki/Commons:Stroke_Order_Project">Strokes Order Project on Wikimedia commons</a>.</li>
<li>The exercise mode asks for both the pronunciation and the word. The
results are stored to help see which words are mastered and which
need to be learned again.</li>
</ul>
<p>Here are some screenshots of the application to help you see it without
building it first:</p>
<p><a href="https://bosdonnat.fr/data/MyLangTeacher-main.png"><img alt="Main window" src="https://bosdonnat.fr/data/MyLangTeacher-main-300x215.png"></a></p>
<p>Main window</p>
<p><a href="https://bosdonnat.fr/data/MyLangTeacher-Exercise.png"><img alt="The exercise window" src="https://bosdonnat.fr/data/MyLangTeacher-Exercise-300x216.png"></a></p>
<p>The exercise window</p>
<p><a href="https://bosdonnat.fr/data/MyLangTeacher-strokes.png"><img alt="The strokes order" src="https://bosdonnat.fr/data/MyLangTeacher-strokes-300x215.png"></a></p>
<p>The strokes order</p>
<p>Of course if you wish to use it or improve it, I will appreciate any
help and comment. My short term plans for this are:</p>
<ul>
<li>Adding some properties to the course, like the author, the learned
language</li>
<li>Adding grammar points to the lessons</li>
<li>Allowing nested tags</li>
</ul>
<p>My goal for this application now is not to make it only a vocabulary
training tool, but something more complete. The ultimate feature I'ld
like to see there is the integration with some TTS with nice voices to
speak the words or even have some other exercise based on that for
listening comprehension.</p>Using the drawinglayer in Writer2010-03-19T12:40:00+01:002010-03-19T12:40:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2010-03-19:/using-the-drawinglayer-in-writer.html<p>You may not know what the drawinglayer is and what it would
bring to borders in Writer. This is a new framework for drawing stuffs
on the screen in OpenOffice.org. It offers a nice and easy API to render
complex shapes. When implementing the new engraved / embossed / inset /
outset …</p><p>You may not know what the drawinglayer is and what it would
bring to borders in Writer. This is a new framework for drawing stuffs
on the screen in OpenOffice.org. It offers a nice and easy API to render
complex shapes. When implementing the new engraved / embossed / inset /
outset border types in OpenOffice.org, I have seen the big difference
between the rendering in Writer or Calc and the rendering for impress
tables. To give you an idea of what happens, here are several
motivations to change the way to render borders in Calc and Writer:</p>
<ol>
<li>There are 3 different codes to currently render borders: one for
Writer floating objects, one for Writer tables and calc and the last
one for impress tables. Every time I change the core border
structure, I need to tweak those three places... having only one
rendering code for all of them would <strong>ease the maintenance of the
borders drawing</strong>.</li>
<li>The current code is drawing rectangles... which provides strange
result for the new 3D border types. For Impress tables I have
changed the drawinglayer implementation to clip the polygons
properly. In order to significantly <strong>improve the rendering result</strong>
in Calc and Writer I need to use this drawinglayer.</li>
</ol>
<p>I have just completed a first implementation for the Writer objects and
tables: some screenshots will help you to understand the whole story...</p>
<p><a href="https://bosdonnat.fr/data/embossed-before.png"><img alt="Embossed table before the hack" src="https://bosdonnat.fr/data/embossed-before-300x105.png"></a></p>
<p>Embossed table before the hack</p>
<p><a href="https://bosdonnat.fr/data/embossed-after.png"><img alt="Embosse table with the drawinlayer" src="https://bosdonnat.fr/data/embossed-after-300x113.png"></a></p>
<p>Embossed table with the drawinlayer</p>
<p><a href="https://bosdonnat.fr/data/outset-after.png"><img alt="Outset table with the drawinglayer" src="https://bosdonnat.fr/data/outset-after-300x117.png"></a></p>
<p>Outset table with the drawinglayer</p>
<p>The changes will soon be committed to <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/">ooo-build git repository</a>...
but the patch won't be applied by default as it's still work in
progress.</p>GSoc 2010, let's go for ooo-build!2010-03-19T11:41:00+01:002010-03-19T11:41:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2010-03-19:/gsoc-2010-lets-go-for-ooo-build.html<p><a href="http://socghop.appspot.com/gsoc/program/home/google/gsoc2010"><img alt="" src="http://code.google.com/images/2010soclogo.jpg" title="GSoc 2010 logo"></a>Yesterday evening we received the good news from
Google: <a href="http://go-oo.org/">ooo-build</a> will be a mentoring organization this year again.
This year we will have the pleasure to share projects slots with
<a href="http://wiki.ooo4kids.org/index.php/Main_Page">ooo4kids</a>, the new OpenOffice.org based Office suite for 7/12 years
old children. I hope that we will have …</p><p><a href="http://socghop.appspot.com/gsoc/program/home/google/gsoc2010"><img alt="" src="http://code.google.com/images/2010soclogo.jpg" title="GSoc 2010 logo"></a>Yesterday evening we received the good news from
Google: <a href="http://go-oo.org/">ooo-build</a> will be a mentoring organization this year again.
This year we will have the pleasure to share projects slots with
<a href="http://wiki.ooo4kids.org/index.php/Main_Page">ooo4kids</a>, the new OpenOffice.org based Office suite for 7/12 years
old children. I hope that we will have motivated and fantastic students
this year too!</p>
<p>It's now time to choose some project and submit your ideas to the
community. Check out the <a href="http://www.freedesktop.org/wiki/Software/ooo-build/SummerOfCode/2010">project ideas wiki page</a> and don't hesitate
to ask for some additional information or discuss your ideas with us on
the IRC (#go-oo on irc.freenode.net), <a href="http://lists.freedesktop.org/mailman/listinfo/ooo-build">mailing list</a> or by private
email with the mentor. Please note that we are requiring each student
submitting a project to solve a simple coding <a href="http://www.freedesktop.org/wiki/Software/ooo-build/SummerOfCode/2010#Theexercise">exercise described on the
wiki page</a>.</p>
<p>Many thanks to Google Summer of Code organization team for allowing us
to live this hacking experience again!</p>Borders types fight: round 22010-02-19T19:03:00+01:002010-02-19T19:03:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2010-02-19:/borders-types-fight-round-2.html<p>In the first round I have added the dotted and dashed border
types. The challenging part of it was to draw the dashed lines
everywhere in Calc, Writer and Impress / Draw. More informations can be
found in the <a href="https://bosdonnat.fr/dotted-border-types-in-calc-and-writer.html">previous blog post</a>. The second round aims at improving
the interoperability with …</p><p>In the first round I have added the dotted and dashed border
types. The challenging part of it was to draw the dashed lines
everywhere in Calc, Writer and Impress / Draw. More informations can be
found in the <a href="https://bosdonnat.fr/dotted-border-types-in-calc-and-writer.html">previous blog post</a>. The second round aims at improving
the interoperability with Word border types. The interesting features to
support are:</p>
<ul>
<li>Separated border types and width selection. For the moment,
OpenOffice.org provides a small set of predefined borders... but
what if one wants 1.75pt dashed border? As shown by the border tabs
screenshot, there are now 2 separate controls: one to select the
border type and one to set the border width.</li>
<li>Support the other types from Word. Some of them are already
supported by ODF but not implemented in OpenOffice.org. For example
Word inset, outset, threeDEngraved and threeDEmbossed can be mapped
to ODF / CSS inset, ouset, grooved and ridged border types.</li>
</ul>
<p>Implementing these features brings its lot of problems. One of the most
important one is that I needed to reengineer Word's behaviour to have
something approching for the lines colors and widths. After some time
measuring Word borders and getting its different colors I could get some
useful infos. For curious readers, I have placed the <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/doc/word-embossed-colors.ods">spreadsheet that I
used to determine the functions for the embossed/engraved colors</a> in
the go-oo git repository.</p>
<p>Here are some screenshots of what I have already implemented in my local
build.</p>
<p><a href="https://bosdonnat.fr/data/borders-tab.png"><img alt="The new borders selection" src="https://bosdonnat.fr/data/borders-tab-300x207.png"></a></p>
<p>The new borders selection</p>
<p><a href="https://bosdonnat.fr/data/border-types.png"><img alt="Some of the new border types" src="https://bosdonnat.fr/data/border-types-300x207.png"></a></p>
<p>Some of the new border types</p>
<p><a href="https://bosdonnat.fr/data/screenshot1.png"><img alt="A Writer table with a nice embossed border" src="https://bosdonnat.fr/data/screenshot1-300x201.png"></a></p>
<p>A Writer table with a nice embossed border</p>
<p>This work is still not published as there are loads of remaining
problems and stuffs to fix:</p>
<ul>
<li>As I have changed<em>SvxBorderLine</em>, I need to adapt all the code using
it in Calc and Impress. Writer is almost completely update now.</li>
<li>The changes aren't persisted in the files for the moment.</li>
<li>The whole border width calculation has to be reworked at least in
Writer because of the ouset and inset widths in Word. Word adapts
the total width of these borders to the maximum width of the borders
in the row or column., whereas OpenOffice.org doesn't take care of
the other widths. Here is a small screenshot from Word to better see
the problem.</li>
</ul>
<p><a href="https://bosdonnat.fr/data/word-outinset.png"><img alt="Outset widths in Word" src="https://bosdonnat.fr/data/word-outinset-300x143.png"></a></p>
<p>Outset widths in Word</p>Nice popups for every toolbar2010-02-05T18:41:00+01:002010-02-05T18:41:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2010-02-05:/nice-popups-for-every-toolbar.html<p>In the Go-oo team, we wanted to refactor some toolbar popups
to tend to some general look. The following screenshots give a good idea
of the differences between those popups.</p>
<p><a href="https://bosdonnat.fr/data/toolbar-differences.png"><img alt="Differences between the toolbars" src="https://bosdonnat.fr/data/toolbar-differences-300x136.png"></a></p>
<p>Then I changed the popup windows by something looking more like the
third of the above screenshots. For some popups …</p><p>In the Go-oo team, we wanted to refactor some toolbar popups
to tend to some general look. The following screenshots give a good idea
of the differences between those popups.</p>
<p><a href="https://bosdonnat.fr/data/toolbar-differences.png"><img alt="Differences between the toolbars" src="https://bosdonnat.fr/data/toolbar-differences-300x136.png"></a></p>
<p>Then I changed the popup windows by something looking more like the
third of the above screenshots. For some popups I even removed the menu
to use normal dialog controls: the effect was pretty awful with the
openSUSE 11.2 default GTK theme (with black menus). Here are some
screenshots to better realize what has changed, though there are other
refactored popups...</p>
<p><a href="https://bosdonnat.fr/data/toolbars.png"><img alt="Some changed toolbars" src="https://bosdonnat.fr/data/toolbars-272x300.png"></a></p>
<p><a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/toolbar-decorations-fix.diff">The patch</a> has been committed to ooo-build master branch, but is not
yet applied as there are still some crashes to fix when reopening the
toolbar.</p>COOoder windows bug is fixed2010-01-25T15:43:00+01:002010-01-25T15:43:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2010-01-25:/coooder-windows-bug-is-fixed.html<p>Everything is in the title. You can download the 1.1.2 version
containing the fix from the <a href="http://extensions.services.openoffice.org/project/coooder">usual place on the OOo extensions
website</a>.</p>
<p>Many thanks for your patience and enjoy the new
release.</p>Dotted border types in Calc and Writer2009-12-17T13:56:00+01:002009-12-17T13:56:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-12-17:/dotted-border-types-in-calc-and-writer.html<p>As this has often heard people complaining about the lack of
dotted and dashed line types in Calc and Writer, I have started to
implement it (139 votes on <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=8275">i#8275</a>). Kohei told me that these line
types are heavily used by the Japanese administration in their forms.
Even thought …</p><p>As this has often heard people complaining about the lack of
dotted and dashed line types in Calc and Writer, I have started to
implement it (139 votes on <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=8275">i#8275</a>). Kohei told me that these line
types are heavily used by the Japanese administration in their forms.
Even thought I am in the early development of this feature, this post
exposes the progress.</p>
<p>What is working:</p>
<ul>
<li>Dotted lines have been added to the border types selection list and
the border selection control has been updated according to it.</li>
<li>Writer tables and Calc now show dotted lines as well as the other
writer objects supporting borders (frames, pictures or pages for
example).</li>
<li>Some ugly display in the border selection control has been fixed
(<a href="http://qa.openoffice.org/issues/show_bug.cgi?id=86716">i#86716</a>)</li>
</ul>
<p>What still has to be done:</p>
<ul>
<li>Loading (saving) the dotted lines style from (to) the different file
formats</li>
<li>Make the current changes more generic to support other kinds of
lines like dashed lines.</li>
</ul>
<p>This is one step to improve the interoperability with Word and Excel
documents, but only the dashed and dotted types will be handled as the
others can't be stored in OpenDocument. ODF uses the XSL-FO border
style...</p>
<p>Now here is the time for the screenshots:</p>
<p><a href="https://bosdonnat.fr/data/calc-border-types.png"><img alt="Dotted borders in Calc" src="https://bosdonnat.fr/data/calc-border-types-300x104.png"></a></p>
<p>Dotted borders in Calc</p>
<p><a href="https://bosdonnat.fr/data/writer-border-types.png"><img alt="Dotted borders in writer" src="https://bosdonnat.fr/data/writer-border-types.png"></a></p>
<p>Dotted borders in writer</p>
<p>Here are two screenshots to compare the borders format dialog before and
after the fix.</p>
<p><a href="https://bosdonnat.fr/data/table-format.png"><img alt="Border format dialog before the fix" src="https://bosdonnat.fr/data/table-format-300x221.png"></a></p>
<p>Border format dialog before the fix</p>
<p><a href="https://bosdonnat.fr/data/table-format-fixed.png"><img alt="Border format dialog with the fix" src="https://bosdonnat.fr/data/table-format-fixed-300x221.png"></a></p>
<p>Border format dialog with the fix</p>
<p>Given the fact that the development is still not finished, there is
still no patch available, but please be patient: it will come soon...</p>
<p><strong>EDIT</strong>: the patch is available on <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/border-types.diff">Go-oo git repository</a>.</p>New export wizard for ooeclipse2009-11-27T12:32:00+01:002009-11-27T12:32:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-11-27:/new-export-wizard-for-ooeclipse.html<p>During the last days, I have started to rework the export
wizard of OOEclipse. There are several reasons for this change:</p>
<ul>
<li>Getting rid of the <em>package.properties</em> file and replace it by the
<em>manifest.xml</em> file.</li>
<li>Better fit the Eclipse UI standards</li>
<li>Propose the user to generate scripts to build …</li></ul><p>During the last days, I have started to rework the export
wizard of OOEclipse. There are several reasons for this change:</p>
<ul>
<li>Getting rid of the <em>package.properties</em> file and replace it by the
<em>manifest.xml</em> file.</li>
<li>Better fit the Eclipse UI standards</li>
<li>Propose the user to generate scripts to build the project without
Eclipse. Ant scripts would be generated for Java projects, Makefiles
for C++ projects.</li>
</ul>
<p>The <em>package.properties</em> file in its current form is a barrier to any
fully Eclipse-independent build system. This would require to add some
extra target to Ant in order to generate the <em>manifest.xml</em> file. In the
next version the <em>package.properties</em> file won't be generated anymore,
but there will be an action in the context menu to convert it to
<em>manifest.xml</em> in order to migrate the projects to the new structure.</p>
<p>This new version of the wizard was also the occasion to refactor some
parts of the language extension point: that code isn't really clean at
the moment. The code of those changes is already committed and pushed to
Git, but I didn't remove the legacy wizard yet. Most of the UI code is
already written: the missing part to implement is the actual export.</p>
<p>Here are some screenshots of the two pages of the new export wizard for
a Java project. The langage specific part is the second half of the
second page.</p>
<p><a href="https://bosdonnat.fr/data/new-oxt-export1.png"><img alt="Page 1" src="https://bosdonnat.fr/data/new-oxt-export1-255x300.png"></a></p>
<p>Page 1</p>
<p><a href="https://bosdonnat.fr/data/new-oxt-export2.png"><img alt="Page 2" src="https://bosdonnat.fr/data/new-oxt-export2-255x300.png"></a></p>
<p>Page 2</p>Changing Gnome language for NX connections2009-10-23T16:16:00+02:002009-10-23T16:16:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-10-23:/changing-gnome-language-for-nx-connections.html<p>A colleague of mine kindly opened me an access to one of his
machines using the NX Client from nomachine.com. It works nicely, but I
had some troubles to get <a href="http://www.gnome.org/">Gnome</a> speak something else that the default
language of the machine (Czech). I tried various solutions including the
definition …</p><p>A colleague of mine kindly opened me an access to one of his
machines using the NX Client from nomachine.com. It works nicely, but I
had some troubles to get <a href="http://www.gnome.org/">Gnome</a> speak something else that the default
language of the machine (Czech). I tried various solutions including the
definition of <em>.dmrc</em> file setting the language to the fr_FR.UTF-8
locale... but nothing changed the language. I finally found a solution
that I'm writing it here to avoid forgetting it; it may also help a few
persons as well.</p>
<p>The solution is composed of two steps:</p>
<ol>
<li>Create a small script on the remote machine to launch gnome in the
desired language</li>
<li>Change the command to run by NX Client on the local machine</li>
</ol>
<h3>The launch script</h3>
<p>Here is the script I wrote on the remote machine, this is the
<strong>\~/bin/gnome-fr</strong> file:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/sh</span>
<span class="nb">export</span> <span class="nv">LANG</span><span class="o">=</span>fr_FR.UTF8
/usr/bin/dbus-launch --exit-with-session gnome-session
</code></pre></div>
<h3>The NX client configuration</h3>
<p>Set the Desktop configuration to <strong>Custom</strong> instead of <strong>Gnome</strong> and
click on the <strong>Settings...</strong> button.</p>
<ul>
<li>Choose the option <strong>Run the following command</strong></li>
<li>Input the path to your script file, in my case: <em>\~/bin/gnome-fr</em></li>
<li>Choose the <strong>New virtual desktop</strong> option in the bottom part of the
dialog</li>
</ul>
<p>Here is a screenshot to better understand this configuration:</p>
<p><a href="https://bosdonnat.fr/data/nxclient-config.png"><img alt="NX Client configuration" src="https://bosdonnat.fr/data/nxclient-config-286x300.png"></a></p>
<p>NX Client configuration</p>A new OOEclipse developer2009-10-12T09:41:00+02:002009-10-12T09:41:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-10-12:/a-new-ooeclipse-developer.html<p>I just would like to welcome Jayanga who will work with me on
developping the ooeclipse integration. Student at Moratuwa University
(Sri Lanka), he will create a Calc Addin wizard as a school project. You
can read his announcement on <a href="http://steptoopensource.wordpress.com/">his blog</a>:</p>
<p><a href="http://steptoopensource.wordpress.com/2009/10/09/eclipse-wizard-for-creating-openoffice-calc-addingsproject-kickoff/">Eclipse wizard for creating OpenOffice Calc Addings(project …</a></p><p>I just would like to welcome Jayanga who will work with me on
developping the ooeclipse integration. Student at Moratuwa University
(Sri Lanka), he will create a Calc Addin wizard as a school project. You
can read his announcement on <a href="http://steptoopensource.wordpress.com/">his blog</a>:</p>
<p><a href="http://steptoopensource.wordpress.com/2009/10/09/eclipse-wizard-for-creating-openoffice-calc-addingsproject-kickoff/">Eclipse wizard for creating OpenOffice Calc Addings(project kickoff)</a></p>
<p><strong>Edit:</strong> I forgot to mention that this project is managed by <a href="http://education.openoffice.org/">the
education project</a>. Jayanga is one of the many students of this
university coming to help us.</p>Create an OpenOffice.org Java client in a few seconds2009-10-09T23:43:00+02:002009-10-09T23:43:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-10-09:/create-an-openoffice-org-java-client-in-a-few-seconds.html<p>The next stable version of OOEclipse will contain a new
project wizard to help you creating a new Java client application for
OpenOffice.org. Here are a few screenshots of the wizard. For those who
want to try it, you will soon be able to install the plugin from one …</p><p>The next stable version of OOEclipse will contain a new
project wizard to help you creating a new Java client application for
OpenOffice.org. Here are a few screenshots of the wizard. For those who
want to try it, you will soon be able to install the plugin from one of
the development update site:
<a href="/ooeclipseintegration-dev">On this server</a> or
<a href="http://people.freedesktop.org/~cbosdo/ooeclipseintegration-dev">http://people.freedesktop.org/~cbosdo/ooeclipseintegration-dev</a>.</p>
<p><a href="https://bosdonnat.fr/data/project-selector.png"><img alt="New project type selection " src="https://bosdonnat.fr/data/project-selector-150x150.png"></a></p>
<p>New project type selection </p>
<p><a href="https://bosdonnat.fr/data/javaclient-page1.png"><img alt="First page of the wizard: really standard" src="https://bosdonnat.fr/data/javaclient-page1-150x150.png"></a></p>
<p>First page of the wizard: really standard </p>
<p><a href="https://bosdonnat.fr/data/unocnx-page.png"><img alt="The OOo connection configuration page" src="https://bosdonnat.fr/data/unocnx-page-150x150.png"></a></p>
<p>The OOo connection configuration page</p>
<p><a href="https://bosdonnat.fr/data/javaclient-project.png"><img alt="The generated project" src="https://bosdonnat.fr/data/javaclient-project-150x150.png"></a></p>
<p>The generated project</p>
<p>Many thanks to Mirko Nasato from <a href="http://artofsolving.com">Art of Solving</a> for his nice LGPL
classes to connect to OpenOffice.org: I have extracted them from
<a href="http://artofsolving.com/opensource/jodconverter">JODConverter</a> and added them in a JAR to the generated
project.</p>Surprising Git2009-10-05T10:11:00+02:002009-10-05T10:11:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-10-05:/surprising-git.html<p>Up to now, I wasn't creating a branch for each new version of
ooeclipse. However, I had a bug report last Friday on a rarely used part
of it. The problem came again: what to do in order to fix this version
quickly without providing any of the unstable features …</p><p>Up to now, I wasn't creating a branch for each new version of
ooeclipse. However, I had a bug report last Friday on a rarely used part
of it. The problem came again: what to do in order to fix this version
quickly without providing any of the unstable features of master.
Hopefully Git came to help me:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Extract the commit before the unstable changes</span>
git checkout 73577b8de7d2f3a5ff149b2a3ca8c1c21289a828
<span class="c1"># Create the local branch for the stable version</span>
git checkout -b ooeclipse-1-1-2
<span class="c1"># Push the new local branch into a new remote branch</span>
git push origin ooeclipse-1-1-2:ooeclipse-1-1-2
</code></pre></div>
<p>Then the bug could be fixed and committed into git. The updated version
has been uploaded into the update sites.</p>OOEclipse version 1.1.2 moved to stable2009-10-01T18:38:00+02:002009-10-01T18:38:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-10-01:/ooeclipse-version-1-1-2-moved-to-stable.html<p>Last week a user reported me that the 1.1.2 version (was in
the dev update site at that time) was working for MacOS X. That was the
last issue I was waiting to be validated in order to move the dev
version to stable. There are no new …</p><p>Last week a user reported me that the 1.1.2 version (was in
the dev update site at that time) was working for MacOS X. That was the
last issue I was waiting to be validated in order to move the dev
version to stable. There are no new features in this version, but the
new version in the update site brings the start of a<strong>C++ support</strong> and
the <strong>description.xml file editor</strong>.</p>
<p>Noteworthy:</p>
<ul>
<li>The following update site isn't maintained any more:
<a href="http://api.openoffice.org/Projects/EclipseIntegration/dev-update/site.xml">http://api.openoffice.org/Projects/EclipseIntegration/dev-update/site.xml</a>.
The sources have been moved out of the OOo CVS, I don't feel correct
to maintain the update site there in such a case.</li>
<li>Two other update sites have been set on freedesktop.org to backup
this server in case of problems: <a href="http://people.freedesktop.org/~cbosdo/ooeclipse/">stable</a> and <a href="http://people.freedesktop.org/~cbosdo/ooeclipse-dev">dev</a>.</li>
</ul>
<p>Any feedback on the new features is welcomed, but don't forget that the
C++ support is not completed: the package won't be build. There are some
improvements to bring to the <strong>uno-skeletonmaker</strong> in order to complete
this.</p>OOEclipse on Ohloh2009-09-25T16:58:00+02:002009-09-25T16:58:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-09-25:/ooeclipse-on-ohloh.html<p>Have you remarked that OOEclipse has a project entry on
<a href="https://www.ohloh.net">Ohloh.net</a>? It provides some nice stats on the project like the ones
you can see in the right column of this page. I also hope it to be a
central place for news on the project. If you haven't …</p><p>Have you remarked that OOEclipse has a project entry on
<a href="https://www.ohloh.net">Ohloh.net</a>? It provides some nice stats on the project like the ones
you can see in the right column of this page. I also hope it to be a
central place for news on the project. If you haven't already done so,
<strong>please don't hesitate to say on ohloh that you're using OOEclipse</strong> to
write your OpenOffice.org extensions...</p>
<p><a href="https://www.ohloh.net/p/ooeclipse">https://www.ohloh.net/p/ooeclipse</a></p>
<p>As you might have seen it on the project summary, one of the bad points
of the OOEclipse project is that it is maintained by only one
developper.<strong>I would be delighted if others could contribute.</strong></p>
<p>
<script src="http://www.ohloh.net/p/341397/widgets/project_factoids.js" type="text/javascript"></script>
</p>Maps for Evolution2009-09-21T23:08:00+02:002009-09-21T23:08:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-09-21:/maps-for-evolution.html<p>I recently discovered two interesting Gnome projects:
libchamplain and Geoclue. <a href="http://projects.gnome.org/libchamplain/">Libchamplain</a> is a library to create and
handle maps. <a href="http://geoclue.freedesktop.org/">Geoclue</a> is a set of D-Bus services for positioning. As
I wanted to try them, I started to write a small Evolution plugin
showing a map with the positions of the …</p><p>I recently discovered two interesting Gnome projects:
libchamplain and Geoclue. <a href="http://projects.gnome.org/libchamplain/">Libchamplain</a> is a library to create and
handle maps. <a href="http://geoclue.freedesktop.org/">Geoclue</a> is a set of D-Bus services for positioning. As
I wanted to try them, I started to write a small Evolution plugin
showing a map with the positions of the contacts contained in an address
book.</p>
<p>The principle is really simple:</p>
<ol>
<li>Get the contacts with an address defined</li>
<li>For all of them transform the address into latitude and longitude
coordinates using Geoclue</li>
<li>Create the maps with the markers at the right place using
libchamplain</li>
</ol>
<p>I only have a screenshot to show today as I still haven't published the
sources yet. Don't worry I'll update this post as soon as I'll have them
somewhere on the web.</p>
<p>I would like to say a big thank you to <a href="http://blog.pierlux.com/category/technology/libchamplain/en+fr/">Pierre-Luc Beaudoin</a>, the main
libchamplain developer for having taken some time to help me review my
code and find why my markers weren't appearing... (I simply have
inverted lattitude and longitude at some point)</p>
<p><a href="https://bosdonnat.fr/data/contacts-map.png"><img alt="Contacts map from Evolution" src="https://bosdonnat.fr/data/contacts-map-300x300.png"></a></p>
<p>Contacts map from Evolution</p>
<p>This gave me some interesting idea for OpenOffice.org: why not having a
<a href="http://wiki.services.openoffice.org/wiki/Smart_Tags">SmartTag</a> showing a map for an address in
Writer?</p>Apologies2009-09-14T09:22:00+02:002009-09-14T09:22:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-09-14:/apologies.html<p>Writing a blog article when facts are still too recent isn't
always a good idea. When writing <a href="https://bosdonnat.fr/automatic-hard-spaces-for-french.html">my previous post</a>, I was quite upset
with the fact that the automated tests and specifications blocked the
integration of <em>cbosdo01</em> CWS. I recognize that I have been too critic
regarding Mathias and …</p><p>Writing a blog article when facts are still too recent isn't
always a good idea. When writing <a href="https://bosdonnat.fr/automatic-hard-spaces-for-french.html">my previous post</a>, I was quite upset
with the fact that the automated tests and specifications blocked the
integration of <em>cbosdo01</em> CWS. I recognize that I have been too critic
regarding Mathias and Stefan who spent a lot of time to test that CWS on
the very last days before the feature freeze.</p>
<p>Thank you Stefan and Mathias for your work, and please accept my
apologies for having written such so hard
words.</p>Automatic hard spaces for french2009-09-11T18:27:00+02:002009-09-11T18:27:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-09-11:/automatic-hard-spaces-for-french.html<p>I heard many french people complaining that Writer isn't
adding the hard spaces automatically before the double punctuation
signs. When going through the list of Writer issues on
bugzilla.novell.com, I found out that there was an issue filed on that
topic <a href="https://bugzilla.novell.com/show_bug.cgi?id=278233">n#278233</a>. A quick search on IssueZilla …</p><p>I heard many french people complaining that Writer isn't
adding the hard spaces automatically before the double punctuation
signs. When going through the list of Writer issues on
bugzilla.novell.com, I found out that there was an issue filed on that
topic <a href="https://bugzilla.novell.com/show_bug.cgi?id=278233">n#278233</a>. A quick search on IssueZilla gave me the
corresponding upstream issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=17169">i#17169</a> (6 years old).</p>
<p>As I already <a href="https://bosdonnat.fr/internationalized-1st-autocorrection.html">hacked the autocorrection some times ago</a>, I decided to
fix that one quite quickly when my wife was working during the week-end.
The implementation took only a few hours: the lengthier part of the
process was the creation of the CWS and the build for the tests. My
changes have been proposed upstream in the <strong>cbosdo01</strong> CWS. After a
hard time trying to get it QAed, this CWS won't be integrated before 3.3
as Sun is asking for specifications! The changes have then been
<a href="http://cgit.freedesktop.org/ooo-build/ooo-build/commit/?id=4e3aa880bf4cff092884cd6ca3ca7662a66001e2">committed to go-oo git repo</a>: <strong>the patch will be available in 3.2
for go-oo</strong>.</p>
<p>Here is a small screencast for the rest of the world: french people will
now what I am talking about whithout viewing it.<br>
<a href="https://bosdonnat.fr/data/hard_spaces.ogg"><img alt="thumb-hard_spaces.ogg" src="https://bosdonnat.fr/data/thumb-hard_spaces.ogg-300x197.png"></a><strong>EDIT</strong></p>
<ul>
<li>The autocorrection hack I did some times ago wasn't that one... but
related to i18n ordinal suffixes.</li>
<li>I have been too critic towards the Sun devs who tested that CWS, I
have written <a href="https://bosdonnat.fr/apologies.html">my apologies here</a>.</li>
</ul>Docx import: the unacceptable regression!2009-09-05T11:14:00+02:002009-09-05T11:14:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-09-05:/docx-import-the-unacceptable-regression.html<p>You may remember that I have started my first CWS some times
ago to upstream my docx import changes. I had to quickly rebase it to
<strong>dev300-m56</strong> as the 3.2 feature freeze is nearing and the QA of a CWS
could take quite some time. After a hard time …</p><p>You may remember that I have started my first CWS some times
ago to upstream my docx import changes. I had to quickly rebase it to
<strong>dev300-m56</strong> as the 3.2 feature freeze is nearing and the QA of a CWS
could take quite some time. After a hard time working on that rebase, I
uncovered a serious issue: any docx containing a picture or a shape make
OOo crash on import. It turns out that Kendy has already reported that
issue (<a href="http://www.openoffice.org/issues/show_bug.cgi?id=104155">i104155</a>). This is clearly a regression from the upstream.</p>
<p><strong>How does it comes QA didn't uncover this enormous regression?</strong></p>
<p>As a developer I have some sample documents to test the features I am
improving and I open each of these documents to check if everything goes
nicely. When doing the QA of big changes like those ones, a set of
OOXML documents should be used to test potential regressions. This has
apparently not been done this time. How does it come that no Docx
document with a picture or a shape in it has been loaded during the QA
of a CWS changing the import of OOXML shapes?</p>
<p><strong>I don't blame the developer introducing the regression here as this
can happen to any one of us... but the way the QA is
done!</strong></p>Word collapsed paragraphs import2009-08-24T17:48:00+02:002009-08-24T17:48:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-24:/word-collapsed-paragraphs-import.html<p>Collapsed paragraphs in words are the empty paragraphs that
are hidden in nested tables. Those paragraphs are shown only when the
cursor is inside them. When importing a Word document, OpenOffice.org
Writer currently does some magic to remove these empty paragraphs in
order to have a similar render to …</p><p>Collapsed paragraphs in words are the empty paragraphs that
are hidden in nested tables. Those paragraphs are shown only when the
cursor is inside them. When importing a Word document, OpenOffice.org
Writer currently does some magic to remove these empty paragraphs in
order to have a similar render to the one in Word. The problem is that
the magic is sometimes not powerful enough, e.g. in issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=102630">i#102630</a>.</p>
<p>Here are some screenshots of OpenOffice.org with the patch showing what
collapsed paragraphs are:</p>
<p><a href="https://bosdonnat.fr/data/collapsed.png"><img alt="A collapsed paraph is hidden" src="https://bosdonnat.fr/data/collapsed-300x63.png"></a></p>
<p>A hidden collapsed paraph</p>
<p><a href="https://bosdonnat.fr/data/uncollapsed.png"><img alt="A collapsed pararaph is shown" src="https://bosdonnat.fr/data/uncollapsed-300x69.png"></a></p>
<p>A shown collapsed pararaph</p>
<p>I was having a look at the latter issue and Florian told me of <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/sw-collapse-empty-table-par-like-html.diff">one of
his unfinished patches about collapsed paragraphs</a>: that was a good
occasion to complete it. Florian's idea was to remove the magic on
import and implement the collapsed paragraphs in Writer. In order to
implement this, the patch is playing with the paragraph's frame height.
The fixes I have made took me quite a long time, because the layout
wasn't properly updated when showing the collapsed paragraph. Here is
what was missing:</p>
<ul>
<li>Actually removing the Word import magic</li>
<li>Fix the layout refreshing</li>
<li>Add a compatibility option to ODF</li>
<li>Change the <em>IsCollapse()</em> method to check if any drawing object is
anchored on the collapsed paragraph.</li>
</ul>
<p>Here are some screenshots of a document with an image anchored to a
collapsed paragraph (which is no longer hidden in Word). This very same
document was making OpenOffice.org crash during the import because the
empty paragraph was removed as if it was a collapsed one.</p>
<p><a href="https://bosdonnat.fr/data/anchor-collapse-mso.png"><img alt="In Word" src="https://bosdonnat.fr/data/anchor-collapse-mso-300x99.png"></a></p>
<p>In Word</p>
<p><a href="https://bosdonnat.fr/data/anchor-collapse-ooo.png"><img alt="In OpenOffice.org" src="https://bosdonnat.fr/data/anchor-collapse-ooo-300x79.png"></a></p>
<p>In OpenOffice.org</p>
<p>As usual, the patch is updated in the go-oo git repo and attached to the
upstream issue. Here are the links again:</p>
<ul>
<li><a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/sw-collapse-empty-table-par-like-html.diff">http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/sw-collapse-empty-table-par-like-html.diff</a></li>
<li><a href="http://qa.openoffice.org/issues/show_bug.cgi?id=102630">http://qa.openoffice.org/issues/show_bug.cgi?id=102630</a></li>
</ul>Opening an issue's page from Vim (improved)2009-08-18T15:49:00+02:002009-08-18T15:49:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-18:/opening-an-issues-page-from-vim-improved.html<p>You may remember one of my previous posts on a <a href="https://bosdonnat.fr/opening-an-issues-page-from-vim.html">Vim script I
wrote to quickly open an issue in the browser</a> from the OOo sources.
As the <em>patches/dev300/apply</em> file is containing issues numbers
formatted differently (in the form <strong>i#XXXXX</strong> instead of
<strong>#iXXXXX#</strong>), I decided to tweak …</p><p>You may remember one of my previous posts on a <a href="https://bosdonnat.fr/opening-an-issues-page-from-vim.html">Vim script I
wrote to quickly open an issue in the browser</a> from the OOo sources.
As the <em>patches/dev300/apply</em> file is containing issues numbers
formatted differently (in the form <strong>i#XXXXX</strong> instead of
<strong>#iXXXXX#</strong>), I decided to tweak my script to support this other
issues format.</p>
<p>The previous OpenIssue function was using <em>expand("\<cword>")</em> in order
to get the selected issue. This is not working for the new format I
wanted to support as <strong>#</strong> is a words delimiter. Thanks to
<a href="http://hermitte.free.fr/vim/general.php3#expl_words_tools">word_tools.vim from Luc Hermitte</a>, I have written a new function
getting all the issues formats. Here is the new code:</p>
<div class="highlight"><pre><span></span><code><span class="c">" Get the issue number under the cursor. An issue number is containing</span>
<span class="c">" digits, lating letters and #. The # characters are removed from the result.</span>
<span class="c">" </span>
<span class="c">" Code heavily inspired from the words_tools.vim of Luc Hermitte</span>
<span class="c">" http://hermitte.free.fr/vim/ressources/dollar_VIM/plugin/words_tools_vim.html</span>
<span class="k">function</span><span class="p">!</span> GetCurrentIssueText<span class="p">()</span>
<span class="k">let</span> <span class="k">c</span> <span class="p">=</span> <span class="k">col</span> <span class="p">(</span><span class="s1">'.'</span><span class="p">)</span><span class="m">-1</span>
<span class="k">let</span> <span class="k">l</span> <span class="p">=</span> line<span class="p">(</span><span class="s1">'.'</span><span class="p">)</span>
<span class="k">let</span> <span class="k">ll</span> <span class="p">=</span> getline<span class="p">(</span><span class="k">l</span><span class="p">)</span>
<span class="k">let</span> ll1 <span class="p">=</span> strpart<span class="p">(</span><span class="k">ll</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="k">c</span><span class="p">)</span>
<span class="k">let</span> ll1 <span class="p">=</span> matchstr<span class="p">(</span>ll1<span class="p">,</span><span class="s1">'[0-9#a-zA-Z]*$'</span><span class="p">)</span>
<span class="k">if</span> strlen<span class="p">(</span>ll1<span class="p">)</span> <span class="p">==</span> <span class="m">0</span>
<span class="k">return</span> ll1
<span class="k">else</span>
<span class="k">let</span> ll2 <span class="p">=</span> strpart<span class="p">(</span><span class="k">ll</span><span class="p">,</span><span class="k">c</span><span class="p">,</span>strlen<span class="p">(</span><span class="k">ll</span><span class="p">)-</span><span class="k">c</span><span class="p">+</span><span class="m">1</span><span class="p">)</span>
<span class="k">let</span> ll2 <span class="p">=</span> strpart<span class="p">(</span>ll2<span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="k">match</span><span class="p">(</span>ll2<span class="p">,</span><span class="s1">'$\|[^0-9#a-zA-Z]'</span><span class="p">))</span>
<span class="k">let</span> text <span class="p">=</span> ll1.ll2
<span class="k">let</span> text <span class="p">=</span> substitute<span class="p">(</span> text<span class="p">,</span> <span class="s2">"#"</span><span class="p">,</span> <span class="s2">""</span><span class="p">,</span> <span class="s2">"g"</span> <span class="p">)</span>
<span class="k">return</span> text
<span class="k">endif</span>
<span class="k">endfunction</span>
<span class="c">" Open IssueZilla / Bugzilla for the selected issue</span>
<span class="k">function</span><span class="p">!</span> OpenIssue<span class="p">(</span> <span class="p">)</span>
<span class="k">let</span> s:browser <span class="p">=</span> <span class="s2">"firefox"</span>
<span class="k">let</span> s:issueText <span class="p">=</span> GetCurrentIssueText<span class="p">(</span> <span class="p">)</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">""</span>
<span class="k">let</span> s:pattern <span class="p">=</span> <span class="s2">"\\(\\a\\+\\)\\(\\d\\+\\)"</span>
<span class="k">let</span> s:prefix <span class="p">=</span> substitute<span class="p">(</span> s:issueText<span class="p">,</span> s:pattern<span class="p">,</span> <span class="s2">"\\1"</span><span class="p">,</span> <span class="s2">""</span> <span class="p">)</span>
<span class="k">let</span> s:id <span class="p">=</span> substitute<span class="p">(</span> s:issueText<span class="p">,</span> s:pattern<span class="p">,</span> <span class="s2">"\\2"</span><span class="p">,</span> <span class="s2">""</span> <span class="p">)</span>
<span class="k">if</span> s:prefix <span class="p">==</span> <span class="s2">"i"</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">"http://qa.openoffice.org/issues/show_bug.cgi?id=%"</span>
<span class="k">elseif</span> s:prefix <span class="p">==</span> <span class="s2">"n"</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">"https://bugzilla.novell.com/show_bug.cgi?id=%"</span>
<span class="k">endif</span>
<span class="k">if</span> s:urlTemplate <span class="p">!=</span> <span class="s2">""</span>
<span class="k">let</span> s:url <span class="p">=</span> substitute<span class="p">(</span> s:urlTemplate<span class="p">,</span> <span class="s2">"%"</span><span class="p">,</span> s:id<span class="p">,</span> <span class="s2">"g"</span> <span class="p">)</span>
<span class="k">let</span> s:cmd <span class="p">=</span> <span class="s2">"silent !"</span> . s:browser . <span class="s2">" "</span> . s:url . <span class="s2">"&"</span>
execute s:cmd
<span class="k">endif</span>
<span class="k">endfunction</span>
map :<span class="k">call</span> OpenIssue<span class="p">()</span>
</code></pre></div>EndNote and Bibus fields are finally read in OOo2009-08-14T15:00:00+02:002009-08-14T15:00:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-14:/endnote-and-bibus-fields-are-finally-read-in-ooo.html<p>From my previous job experience, I knew that there were some
problems for EndNote users to read their documents in OpenOffice.org. I
decided to found out a sample document and try to see what is wrong.</p>
<p>Here is the sample document I used: <a href="http://sitemaker.umich.edu/emeier.dt/view_profiles/da.data/1037375/SampleWork/editstyle_sample.doc">editstyle_sample.doc</a>. There are
two problems …</p><p>From my previous job experience, I knew that there were some
problems for EndNote users to read their documents in OpenOffice.org. I
decided to found out a sample document and try to see what is wrong.</p>
<p>Here is the sample document I used: <a href="http://sitemaker.umich.edu/emeier.dt/view_profiles/da.data/1037375/SampleWork/editstyle_sample.doc">editstyle_sample.doc</a>. There are
two problems in this document:</p>
<ol>
<li>the field below the "References" text isn't imported at all</li>
<li>all the other fields are imported as plain text</li>
</ol>
<p>I fixed the first problem thanks to Florian (in fact, he did it all). As
always, <a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/sw-ww8-field-fix.diff">the patch is available on the go-oo git repo</a>. I have also
attached it to the upstream issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=61075">i#61075</a>. Here are some
screenshots to show the difference:</p>
<p><a href="https://bosdonnat.fr/data/ww8-fields-nf.png"><img alt="The initial missing field" src="https://bosdonnat.fr/data/ww8-fields-nf-300x223.png"></a></p>
<p>The initial missing field</p>
<p><a href="https://bosdonnat.fr/data/ww8-fields-fix.png"><img alt="The imported .doc fields" src="https://bosdonnat.fr/data/ww8-fields-fix-300x199.png"></a></p>
<p>The imported .doc fields</p>
<p>Fixing the second point is another problem. What users would at least
expect is to keep the word fields when saving the document back to .doc.
This isn't the case because OOo is importing only the field's text
replacement. In order to do that, ODF should have some mechanism to
store the MSWord field code. This would be useless for OOo, but it could
allow to save the document back to .doc with the fields.</p>
<p>The issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=89667">i#89667</a> about Bibus fields has been fixed by this patch:
it was the same problem.</p>Fixed an old kerning issue2009-08-13T17:13:00+02:002009-08-13T17:13:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-13:/fixed-an-old-kerning-issue.html<p>During the week I discovered an interesting issue around the
kerning <a href="https://bugzilla.novell.com/show_bug.cgi?id=464436">n#464436</a> and <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=26519">i#26519</a>. After some time spent with
Florian and Thorsten, we finally found what was going wrong. Here is a
summary of the problem:</p>
<ul>
<li>If you have a non-printable character between two letters, no
kerning is …</li></ul><p>During the week I discovered an interesting issue around the
kerning <a href="https://bugzilla.novell.com/show_bug.cgi?id=464436">n#464436</a> and <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=26519">i#26519</a>. After some time spent with
Florian and Thorsten, we finally found what was going wrong. Here is a
summary of the problem:</p>
<ul>
<li>If you have a non-printable character between two letters, no
kerning is applied to those characters on linux.</li>
<li>If you have one of the two characters with a different attribute
(eg, font color), the kerning isn't applied to those characters as
well on linux.</li>
</ul>
<p>Here are some screenshot visually explaining the problem and showing the
fix. On those screenshots, the problems are happenning between the A and
V.</p>
<p>The non fixed versions:</p>
<p><a href="https://bosdonnat.fr/data/kerning-fmt.png"><img alt="Formatting without the kerning" src="https://bosdonnat.fr/data/kerning-fmt-300x223.png"></a></p>
<p>Formatting without the kerning</p>
<p><a href="https://bosdonnat.fr/data/kerning-np.png"><img alt="Non printable character without kerning" src="https://bosdonnat.fr/data/kerning-np-300x134.png"></a></p>
<p>Non printable character without kerning</p>
<p>The fixed versions:</p>
<p><a href="https://bosdonnat.fr/data/fix-kerning-fmt.png"><img alt="Formatting with fixed kerning" src="https://bosdonnat.fr/data/fix-kerning-fmt-300x214.png"></a></p>
<p>Formatting with fixed kerning</p>
<p><a href="https://bosdonnat.fr/data/fix-kerning-np.png"><img alt="Non printable character with kerning fixed" src="https://bosdonnat.fr/data/fix-kerning-np-300x130.png"></a></p>
<p>Non printable character with kerning fixed</p>
<p>The patch is attached at the upstream issue and available in go-oo git
repo at: </p>
<p><a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/vcl-kerning-fix.diff">http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/vcl-kerning-fix.diff</a></p>Internationalized 1st autocorrection2009-08-10T13:47:00+02:002009-08-10T13:47:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-10:/internationalized-1st-autocorrection.html<p>When one is typing 1st the 'st' is transformed to super
script. This was only done for english text. Then when typing 1er in a
french text, nothing happened, but typing 1st in a french text was
running as fine as for an english text. I wanted to fix that …</p><p>When one is typing 1st the 'st' is transformed to super
script. This was only done for english text. Then when typing 1er in a
french text, nothing happened, but typing 1st in a french text was
running as fine as for an english text. I wanted to fix that issue for a
long time... and I finally took some time to do it when I learned that
<a href="http://site.icu-project.org/">ICU</a> could help me on that point.</p>
<p>To fix this bug, I changed the implementation of:</p>
<ul>
<li>the <a href="http://svn.services.openoffice.org/opengrok/xref/Current%20(trunk)/i18npool/source/ordinalsuffix/ordinalsuffix.cxx#57"><em>com.sun.star.i18n.OrdinalSuffix</em></a> service to use ICU to get
the localized prefix</li>
<li>the <a href="http://svn.services.openoffice.org/opengrok/xref/Current%20(trunk)/svx/source/editeng/svxacorr.cxx#524"><em>SvxAutoCorrect::FnChgOrdinalNumber( )</em></a> method to make it
use that service</li>
</ul>
<p>I found out that the <em>RuleBasedNumberFormat</em> class from ICU4C was
correctly providing the localized suffix only for english locale with
the current version of ICU used by OOo (4.0.x). As this behaviour has
been improved in ICU 4.2, I then have added the patch in the
<strong>Experimental</strong> section of <em>patches/dev300/apply</em>. The patch can be
found on the go-oo git repo:</p>
<p><a href="http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/svx-i18n-ordinal-autocorr.diff">http://cgit.freedesktop.org/ooo-build/ooo-build/tree/patches/dev300/svx-i18n-ordinal-autocorr.diff</a></p>
<p>There are several related issues upstream, but the main one is:
<a href="http://www.openoffice.org/issues/show_bug.cgi?id=20348">i#20348</a>. Even thought the patch doesn't implement Sun's
specifications related to that issue, this is better than nothing...</p>
<p>Here is a screenshot of the autocorrection with that patch.</p>
<p><a href="https://bosdonnat.fr/data/ordinal_autocorr.png"><img alt="Screenshot of the new autocorrection for ordinal suffixes" src="https://bosdonnat.fr/data/ordinal_autocorr-300x127.png"></a></p>
<p>Screenshot of the new autocorrection for ordinal suffixes</p>
<p>I can start here a small list of what I know which could be improved,
but this could certainly be extended:</p>
<ul>
<li>ICU formatting is providing only one suffix: there are cases where
this suffix has be be changed according to the genre/number, eg: 1er
can be also 1ère or 1ers or 1ères in french...</li>
<li>ICU provides a default suffix for some locales which may have
variations due to users habits, eg: 2e can also be written 2ème in
french and it only depends on the local habits.</li>
</ul>Hackweek on OOEclipse2009-08-03T18:19:00+02:002009-08-03T18:19:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-08-03:/hackweek-on-ooeclipse.html<p>As some of my fellow developers at Novell have already
explained it: we currently had a week of Innovation time. As I was on
holiday during the official hack week time, I had it last week... and
worked on the ooeclipse integration. This was an occasion to make some
old …</p><p>As some of my fellow developers at Novell have already
explained it: we currently had a week of Innovation time. As I was on
holiday during the official hack week time, I had it last week... and
worked on the ooeclipse integration. This was an occasion to make some
old ideas realized. The sources are already committed and push to the
git repository.</p>
<h3>Description.xml really simple edition</h3>
<p>First of all, and it took most of the time to do, I have extended the
<em>package.properties</em> editor to also edit the <em>description.xml</em> file. An
<strong>Overview</strong> page will now help the users to configure the most
important informations of the extension. There are still a few things
which could be improved:</p>
<ul>
<li>there is currently field to select the extension icons.</li>
<li>the description files selection is still present in the old
<strong>Content</strong> page of the editor but is not synchronized with the
<strong>Overview</strong> page at all.</li>
<li>the save doesn't work when you have switched to the
<em>description.xml</em> source page. This is clearly a bug... still too
tricky to have been found and fixed in the week.</li>
</ul>
<p>Here is a screenshot of the Overview page for the <em>description.xml</em> file
of my COOoder extension.</p>
<p><a href="https://bosdonnat.fr/data/description_editor.png"><img alt="Description.xml edition page" src="https://bosdonnat.fr/data/description_editor-300x233.png"></a></p>
<p>Description.xml edition page</p>
<h3>Unit test for the OS tests</h3>
<p>I had a lot of complaints about some versions of OOo not working with
the plugin, mostly macosx versions. The fact is that I don't have all
those OS running at home... and then couldn't test them all. I have
hacked this part of the code to be able to run some basic automatic
tests to check the verifications done on OOo's structure for each of the
supported OS. This is implemented by this JUnit test case:</p>
<p><a href="http://cgit.freedesktop.org/ooo-build/contrib/ooeclipse/tree/core/source/org/openoffice/ide/eclipse/core/unittests/OOoTest.java">http://cgit.freedesktop.org/ooo-build/contrib/ooeclipse/tree/core/source/org/openoffice/ide/eclipse/core/unittests/OOoTest.java</a></p>
<p>Testing the different files that are checked for every OOo install will
now be easy. Even if this is not a really important news for the users,
this is one for me (and other potential developers) to help the
maintainance.</p>
<h3>A first C++ support</h3>
<p>Java was the only extension language supported by the ooeclipse, this
will no longer be true. Even if the C++ support is currently really
basic, there is one. The main problem developing the C++ plugin is to
use the CDT API: the documentation is really seldom and often old. On
top of that the sources are linked linked to the plugin by default in
Eclipse: then exploring the CDT sources is quite a nightmare.</p>
<p>Here is a small screenshot of the first C++ OOo extension project
structure:</p>
<p><a href="https://bosdonnat.fr/data/cpp_structure.png"><img alt="UNO C++ project structure" src="https://bosdonnat.fr/data/cpp_structure-162x300.png"></a></p>
<p>UNO C++ project structure</p>
<p>What is currently working:</p>
<ul>
<li>The C++ project is created with the includes and source folders
defined</li>
<li>The tool chain is working up to the <em>cppumaker</em> run (included)</li>
<li>The service's implementation skeleton is generated</li>
</ul>
<p>Among the points to complete can be found:</p>
<ul>
<li>The code build and package generation isn't working. There may be
some generic Makefile to create, or to use Eclipse CDT features.</li>
<li>The three registration methods will have to gather all the ones
created by the <em>uno-skeletonmaker</em> for all the implementations.</li>
</ul>Unzip bash completion for ODF and OOXML files2009-07-02T19:20:00+02:002009-07-02T19:20:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-07-02:/unzip-bash-completion-for-odf-and-ooxml-files.html<p>Everything is in the title: when you want to unzip an ODF or
OOXML file, there is no bash completion for those documents types. I
hacked the <em>/etc/profile.d/complete.bash</em> file of my openSUSE box to make it
work.</p>
<p>Here is a first diff which can be improved …</p><p>Everything is in the title: when you want to unzip an ODF or
OOXML file, there is no bash completion for those documents types. I
hacked the <em>/etc/profile.d/complete.bash</em> file of my openSUSE box to make it
work.</p>
<p>Here is a first diff which can be improved to support other file
extensions:</p>
<div class="highlight"><pre><span></span><code><span class="gd">--- complete.bash 2008-06-09 14:21:12.000000000 +0200</span>
<span class="gi">+++ complete.bash 2009-07-02 19:04:41.000000000 +0200</span>
<span class="gu">@@ -162,8 +162,7 @@</span>
esac ;;
gunzip) e='!*.+(gz|tgz|z|Z)' ;;
uncompress) e='!*.Z' ;;
<span class="gd">- unzip) e='!*.+(???)'</span>
<span class="gd">- t="@(MS-DOS executable|Zip archive)*" ;;</span>
<span class="gi">+ unzip) e='!*.+(zip|ZIP|o[dt][tspgf]|O[DT][TSPGF]|doc[xm]|DOC[XM]|xlsx|XLSX|pptx|PPTX)';;</span>
gs|ghostview) e='!*.+(eps|EPS|ps|PS|pdf|PDF)' ;;
gv|kghostview) e='!*.+(eps|EPS|ps|PS|ps.gz|pdf|PDF)' ;;
acroread|[xk]pdf) e='!*.+(pdf|PDF)' ;;
</code></pre></div>GSoc: Hacking Writer's toolbars2009-07-01T17:55:00+02:002009-07-01T17:55:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-07-01:/gsoc-hacking-writers-toolbars.html<p>These last days, I dived into the way OpenOffice.org toolbars
are defined in Writer to help Maja on her problems (( See <a href="http://gsoc-ovcica.blogspot.com/2009/06/missing-parts-inserted-but-no-progress.html">her blog post</a>)).
There are several points which were hard to guess, but the navigation toolbar
is now nice and connected to the C++ code:</p>
<ul>
<li>
<p>As Maja has …</p></li></ul><p>These last days, I dived into the way OpenOffice.org toolbars
are defined in Writer to help Maja on her problems (( See <a href="http://gsoc-ovcica.blogspot.com/2009/06/missing-parts-inserted-but-no-progress.html">her blog post</a>)).
There are several points which were hard to guess, but the navigation toolbar
is now nice and connected to the C++ code:</p>
<ul>
<li>
<p>As Maja has stated it, it is necessary to set <strong>Properties</strong> node in the
command definition in the XCU file. This is really strange and
completely stupid, but it works.</p>
<p>:::diff
+ <node oor:name=".uno:NavigateForward" oor:op="replace">
+ <prop oor:name="Label" oor:type="xs:string">
+ <value xml:lang="en-US">Forward</value>
+ </prop>
+ <prop oor:name="Properties" oor:type="xs:int">
+ <value>1</value>
+ </prop>
+ </node></p>
</li>
<li>
<p>The file <em>sfx2/source/appl/workwin.cxx</em> had to be completed to help
make the equivalence between the resource ID and the toolbar name in
the XML configuration.</p>
<p>:::diff
diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx
index b5a26d6..6780959 100644
--- a/sfx2/source/appl/workwin.cxx
+++ b/sfx2/source/appl/workwin.cxx
@@ -143,6 +143,7 @@ static const ResIdToResName pToolBarResToName[] =
{ 23031, "mediaobjectbar" }, //draw/impress
{ 25060, "mediaobjectbar" }, //calc
{ 23311, "mediaobjectbar" }, //writer
+ { 23313, "navigationobjectbar" }, //writer
{ 0, "" }
};</p>
</li>
</ul>
<p>The value here isn't taken out of my hat, but is the value of the
<em>RID_NAVIGATION_TOOLBOX</em> constant registered with the navigation
shell.</p>
<ul>
<li>The class <em>SwNavigationShell</em> had to be instanciated in the
<em>SwView::SelectShell</em> method.</li>
</ul>
<p>The complete patch is available on my freedesktop.org account for those
who want to see the code:<br>
<a href="http://people.freedesktop.org/~cbosdo/gsoc/navigation.diff">http://people.freedesktop.org/~cbosdo/gsoc/navigation.diff</a></p>
<p>Many thanks Thorsten to have helped me understand the horror of the
toolbars.</p>OOEclipse sources moved to git2009-05-28T10:20:00+02:002009-05-28T10:20:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-05-28:/ooeclipse-sources-moved-to-git.html<p>I have decided to move the sources of the OOEclipse
integration plugin to an ooo-build Git repo. Call it a fork if you like,
but my aim here is to allow other developers to contribute easily to the
project without having to sign a SCA. The code is still present …</p><p>I have decided to move the sources of the OOEclipse
integration plugin to an ooo-build Git repo. Call it a fork if you like,
but my aim here is to allow other developers to contribute easily to the
project without having to sign a SCA. The code is still present on the
OpenOffice.org API project CVS, but I will no longer commit changes
there.</p>
<p>The sources can be extracted using the following Git commands:</p>
<ul>
<li>Anonymous access: <strong>git clone
git://anongit.freedesktop.org/git/ooo-build/contrib/ooeclipse</strong></li>
<li>Developer access: <strong>git clone
ssh://[username@]git.freedesktop.org/git/ooo-build/contrib/ooeclipse</strong></li>
</ul>
<p>If you don't want to use the command line, have a look at this Eclipse
plugin: <a href="http://git.or.cz/gitwiki/EclipsePlugin">http://git.or.cz/gitwiki/EclipsePlugin</a>.</p>
<p>If you want to commit some patches, you should refer to the Git
documentation of the ooo-build project:
<a href="http://www.freedesktop.org/wiki/Software/ooo-build/GettingIt">http://www.freedesktop.org/wiki/Software/ooo-build/GettingIt</a>. These
rules will also apply to the ooeclipse project. As written on this page,
you can email your patch if you don't have a freedesktop.org acount yet.</p>
<p>As the project is no longer hosted by the OpenOffice.org API project,
the discussions should take place on the <strong>dev@lists.go-oo.org</strong> mailing
list instead of the <strong>dev@api.openoffice.org</strong> one. Of course, I will
still answer question on the latter list.</p>
<p>Those changes were also the time to create an ohloh account for the
plugin: <a href="https://www.ohloh.net/p/ooeclipse">https://www.ohloh.net/p/ooeclipse</a>.</p>Better diff of XML files2009-05-19T09:53:00+02:002009-05-19T09:53:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-05-19:/better-diff-of-xml-files.html<p>I needed to compare the FlatXML of two OpenOffice.org files. I
usually reformat the XML files using xmllint and then diff those
formatted XML files. However I couldn't properly see the differences
between for those files because the attributes were on the same line
with the element. In order …</p><p>I needed to compare the FlatXML of two OpenOffice.org files. I
usually reformat the XML files using xmllint and then diff those
formatted XML files. However I couldn't properly see the differences
between for those files because the attributes were on the same line
with the element. In order to compare all the attributes one by one, I
decided to hack xmllint (and then libxml2 too) as we discussed it
recently with Tor recently.</p>
<p>All what I have added is a <code>--diff</code> argument for the xmllint program and
change the use of the format parameter in the libxml (when the value
equals 2, then separate each attribute and text on different lines).
Here are two XML sample files (many thanks to Zvon for their nice XML
samples).</p>
<p>Here is file <code>foo.xml</code>:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><AAA></span>
<span class="nt"><BBB</span> <span class="na">aaa =</span> <span class="s">"111"</span> <span class="na">bbb =</span> <span class="s">"222"</span><span class="nt">></span>
<span class="nt"><CCC/></span>
<span class="nt"><CCC</span> <span class="na">xxx =</span> <span class="s">"555"</span> <span class="na">yyy =</span> <span class="s">"666"</span> <span class="na">zzz =</span> <span class="s">"777"</span><span class="nt">/></span>
<span class="nt"></BBB></span>
<span class="nt"><BBB</span> <span class="na">aaa =</span> <span class="s">"999"</span><span class="nt">></span>
<span class="nt"><CCC</span> <span class="na">xxx =</span> <span class="s">"qq"</span><span class="nt">/></span>
<span class="nt"><DDD</span> <span class="na">xxx =</span> <span class="s">"ww"</span><span class="nt">/></span>
<span class="nt"><EEE</span> <span class="na">xxx =</span> <span class="s">"oo"</span><span class="nt">/></span>
<span class="nt"></BBB></span>
<span class="nt"><BBB></span>
<span class="nt"><DDD</span> <span class="na">xxx =</span> <span class="s">"oo"</span><span class="nt">/></span>
<span class="nt"></BBB></span>
<span class="nt"></AAA></span>
</code></pre></div>
<p>Here is file <code>foo2.xml</code>:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><AAA></span>
<span class="nt"><BBB</span> <span class="na">aaa=</span><span class="s">"111"</span> <span class="na">bbb=</span><span class="s">"222"</span><span class="nt">></span>
<span class="nt"><CCC/></span>
<span class="nt"><CCC</span> <span class="na">xxx=</span><span class="s">"565"</span> <span class="na">zzz=</span><span class="s">"777"</span> <span class="na">ddd=</span><span class="s">"new"</span><span class="nt">/></span>
<span class="nt"></BBB></span>
<span class="nt"><BBB</span> <span class="na">aaa=</span><span class="s">"999"</span><span class="nt">></span>
<span class="nt"><CCC</span> <span class="na">xxx=</span><span class="s">"qq"</span><span class="nt">/></span>
<span class="nt"><DDD</span> <span class="na">xxx=</span><span class="s">"ww"</span><span class="nt">/></span>
<span class="nt"><EEE</span> <span class="na">xxx=</span><span class="s">"oo"</span><span class="nt">/></span>
<span class="nt"></BBB></span>
<span class="nt"><NEW</span> <span class="na">attr=</span><span class="s">"newtoo"</span><span class="nt">></span>Change<span class="nt"></NEW></span>
<span class="nt"><BBB></span>
<span class="nt"><DDD</span> <span class="na">xxx=</span><span class="s">"oo"</span><span class="nt">></span>CONTENT<span class="nt"></DDD></span>
<span class="nt"></BBB></span>
<span class="nt"></AAA></span>
</code></pre></div>
<p>I have diff'ed those two files using <code>xmllint --format</code> and
<code>xmllint --diff</code> to better show the differences.</p>
<p>Here is the output using <code>--format</code>:</p>
<div class="highlight"><pre><span></span><code><span class="gd">--- format-foo.xml 2009-05-18 17:41:33.000000000 +0200</span>
<span class="gi">+++ format-foo2.xml 2009-05-18 17:41:42.000000000 +0200</span>
<span class="gu">@@ -2,14 +2,15 @@</span>
<AAA>
<BBB aaa="111" bbb="222">
<CCC/>
<span class="gd">- <CCC xxx="555" yyy="666" zzz="777"/></span>
<span class="gi">+ <CCC xxx="565" zzz="777" ddd="new"/></span>
</BBB>
<BBB aaa="999">
<CCC xxx="qq"/>
<DDD xxx="ww"/>
<EEE xxx="oo"/>
</BBB>
<span class="gi">+ <NEW attr="newtoo">Change</NEW></span>
<BBB>
<span class="gd">-</span>
<DDD xxx="oo"/>
<span class="gi">+</span>
<DDD xxx="oo">CONTENT</DDD>
</BBB>
</AAA>
</code></pre></div>
<p>Here is the output using <code>--diff</code>:</p>
<div class="highlight"><pre><span></span><code><span class="gd">--- diff-foo.xml 2009-05-18 17:40:06.000000000 +0200</span>
<span class="gi">+++ diff-foo2.xml 2009-05-18 17:40:13.000000000 +0200</span>
<span class="gu">@@ -5,9 +5,9 @@</span>
bbb="222">
<CCC/>
<CCC
<span class="gd">- xxx="555"</span>
<span class="gd">- yyy="666"</span>
<span class="gd">- zzz="777"/></span>
<span class="gi">+ xxx="565"</span>
<span class="gi">+ zzz="777"</span>
<span class="gi">+ ddd="new"/></span>
</BBB>
<BBB
aaa="999">
<span class="gu">@@ -18,8 +18,14 @@</span>
<EEE
xxx="oo"/>
</BBB>
<span class="gi">+ <NEW</span>
<span class="gi">+ attr="newtoo"></span>
<span class="gi">+Change</span>
<span class="gi">+ </NEW></span>
<BBB>
<DDD
<span class="gd">- xxx="oo"/></span>
<span class="gi">+ xxx="oo"></span>
<span class="gi">+CONTENT</span>
<span class="gi">+ </DDD></span>
</BBB>
</AAA>
</code></pre></div>
<p><strong>All the test files are available <a href="https://bosdonnat.fr/data/dev/libxml-diff-tests.tar.gz">in this archive</a>. Printing them on
a web page caused some important formatting problems.</strong></p>
<p>The patch for libxml2 hasn't yet been submitted to Daniel Veillard, but
is available <strong><a href="https://bosdonnat.fr/data/dev/libxml2-diff.diff">here</a></strong> for those who wants to try
now.</p>Numbering imports in docx files2009-05-13T18:11:00+02:002009-05-13T18:11:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-05-13:/numbering-imports-in-docx-files.html<p>Here are some hot news from the docx import front. I am
currently working on the numberings and outline import. There were
several problems:</p>
<ul>
<li>the outline styles weren't defined</li>
<li>the numbering layout properties weren't properly set</li>
<li>the suffix and the number of parent levels weren't correctly set.</li>
</ul>
<p>As usual here …</p><p>Here are some hot news from the docx import front. I am
currently working on the numberings and outline import. There were
several problems:</p>
<ul>
<li>the outline styles weren't defined</li>
<li>the numbering layout properties weren't properly set</li>
<li>the suffix and the number of parent levels weren't correctly set.</li>
</ul>
<p>As usual here are some screenshots to better understand the problem. You
can find the sample document attached to <a href="https://bugzilla.novell.com/show_bug.cgi?id=478583">this issue</a>. I have added an
other interesting screenshot to compare with the import of the same file
converted to .doc by Word 2007.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/word-num.png"><img alt="The file in Word" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/word-num-150x150.png"></a></p>
<p>The file in word </p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-nf-num.png"><img alt="Import without the patch" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-nf-num-150x150.png"></a></p>
<p>Import without the patch</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-doc-num.png"><img alt="Import of a .doc file" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-doc-num-150x150.png"></a></p>
<p>Import of a .doc file</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv-num.png"><img alt="Imported using OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv-num-150x150.png"></a></p>
<p>Imported using OdfConverter</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-fix-num.png"><img alt="Import with the fixes" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-fix-num-150x146.png"></a></p>
<p>Import with the fixes</p>
<p>The patch isn't yet committed to the master branch as it is still
experimental and not complete...</p>Opening an issue's page from Vim2009-05-11T16:29:00+02:002009-05-11T16:29:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-05-11:/opening-an-issues-page-from-vim.html<p>As I have been tired to have to navigate to the issues query page on
either OOo IssueZilla or Novell Bugzilla when I have a comment like
#iXXXX#, I wrote a small Vim function to do it for me. Here is the
script I have added to my .vimrc.</p>
<div class="highlight"><pre><span></span><code><span class="c">" Open …</span></code></pre></div><p>As I have been tired to have to navigate to the issues query page on
either OOo IssueZilla or Novell Bugzilla when I have a comment like
#iXXXX#, I wrote a small Vim function to do it for me. Here is the
script I have added to my .vimrc.</p>
<div class="highlight"><pre><span></span><code><span class="c">" Open IssueZilla / Bugzilla for the selected issue</span>
<span class="k">function</span><span class="p">!</span> OpenIssue<span class="p">(</span> <span class="p">)</span>
<span class="k">let</span> s:browser <span class="p">=</span> <span class="s2">"firefox"</span>
<span class="k">let</span> s:wordUnderCursor <span class="p">=</span> expand<span class="p">(</span><span class="s2">""</span><span class="p">)</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">""</span>
<span class="k">let</span> s:pattern <span class="p">=</span> <span class="s2">"\\(\\a\\+\\)\\(\\d\\+\\)"</span>
<span class="k">let</span> s:prefix <span class="p">=</span> substitute<span class="p">(</span> s:wordUnderCursor<span class="p">,</span> s:pattern<span class="p">,</span> <span class="s2">"\\1"</span><span class="p">,</span> <span class="s2">""</span> <span class="p">)</span>
<span class="k">let</span> s:id <span class="p">=</span> substitute<span class="p">(</span> s:wordUnderCursor<span class="p">,</span> s:pattern<span class="p">,</span> <span class="s2">"\\2"</span><span class="p">,</span> <span class="s2">""</span> <span class="p">)</span>
<span class="k">if</span> s:prefix <span class="p">==</span> <span class="s2">"i"</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">"http://qa.openoffice.org/issues/show_bug.cgi?id=%"</span>
<span class="k">elseif</span> s:prefix <span class="p">==</span> <span class="s2">"n"</span>
<span class="k">let</span> s:urlTemplate <span class="p">=</span> <span class="s2">"https://bugzilla.novell.com/show_bug.cgi?id=%"</span>
<span class="k">endif</span>
<span class="k">if</span> s:urlTemplate <span class="p">!=</span> <span class="s2">""</span>
<span class="k">let</span> s:url <span class="p">=</span> substitute<span class="p">(</span> s:urlTemplate<span class="p">,</span> <span class="s2">"%"</span><span class="p">,</span> s:id<span class="p">,</span> <span class="s2">"g"</span> <span class="p">)</span>
<span class="k">let</span> s:cmd <span class="p">=</span> <span class="s2">"silent !"</span> . s:browser . <span class="s2">" "</span> . s:url . <span class="s2">"&"</span>
execute s:cmd
<span class="k">endif</span>
<span class="k">endfunction</span>
map :<span class="k">call</span> OpenIssue<span class="p">()</span>
</code></pre></div>
<p>To run the script, place the cursor on a word in the form iXXXXX or
nXXXXX and hit <strong>Ctrl-i</strong>. you will certainly need to tweak to script if
you which to add other shortcuts or use another browser. Of course, this
is not cross-platform and could be much more configurable. If you have
some improvements in this area, please propose them! Many thanks to
<a href="http://vim.wikia.com/wiki/Online_documentation_for_word_under_cursor">this Vim tip</a> which helped me a lot to write this script.</p>Gdb utilities2009-04-27T18:30:00+02:002009-04-27T18:30:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-04-27:/gdb-utilities.html<p>While chatting this morning with Eric, I found out that I was
using some gdb useful methods unknown to some other fellow developers.
Here is are some links to help debugging OOo.</p>
<ul>
<li>An interesting forum thread giving two ways to <a href="http://help.lockergnome.com/linux/GDB-capabilities-exploring-STL-classes--ftopict279673.html">easily print the
content of STL containers</a></li>
<li>gdb functions to …</li></ul><p>While chatting this morning with Eric, I found out that I was
using some gdb useful methods unknown to some other fellow developers.
Here is are some links to help debugging OOo.</p>
<ul>
<li>An interesting forum thread giving two ways to <a href="http://help.lockergnome.com/linux/GDB-capabilities-exploring-STL-classes--ftopict279673.html">easily print the
content of STL containers</a></li>
<li>gdb functions to <a href="http://wiki.services.openoffice.org/wiki/Debugging#The_recommended_.gdbinit_file">print the OOo internal strings</a></li>
</ul>
<p>If anyone has some other links or tips, I would be glad to try
them.</p>Docx shapes import: with text2009-04-22T10:39:00+02:002009-04-22T10:39:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-04-22:/docx-shapes-import-with-text.html<p>Importing the text inside the shapes from docx files is a
complex problem in OpenOffice.org. Most of the problem comes from the
fact that there are two text engines in OOo like in older versions of
Word:</p>
<ul>
<li>the Writer text engine used in the text documents and in the …</li></ul><p>Importing the text inside the shapes from docx files is a
complex problem in OpenOffice.org. Most of the problem comes from the
fact that there are two text engines in OOo like in older versions of
Word:</p>
<ul>
<li>the Writer text engine used in the text documents and in the text
frames</li>
<li>the edit engine used in Draw / Impress and for the shapes content in
Writer.</li>
</ul>
<p>The edit engine is supporting only simple formatted text, whereas the
Writer text engine is supporting other objects like tables, pictures,
etc. In Word 2007 any shape can contain any piece of content: not only
text. The problem when importing is then: how to import the shapes
containing complex text? A short term solution is to create a text frame
for any rectangle shape containing text and keeping shapes for anything
else. Some data could then be lost, for example if an ellipse shape is
containing a table. A long term solution would be to get rid of the edit
engine and use the writer engine everywhere...</p>
<p>I managed to create the shape or frame depending on the docx input and
to set the text in it. There is a really annoying thing with the text
frames and shapes: their UNO APIs are completely different: then all the
work with the shape properties have to be done another time with the
frame properties... Couldn't at least the fill / line properties be the
same for both TextFrame and Shape services ?</p>
<p>Here are some screenshots showing the import of a docx file with shapes
containing text. There is no screenshot for the OdfConverter as the
generated odf document makes OOo crash!</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-mso.png"><img alt="The original document" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-mso-150x150.png"></a></p>
<p>The original document</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-nofix.png"><img alt="Imported with a non fixed OOo" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-nofix-150x150.png"></a></p>
<p>Imported with a non fixed OOo</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-fix.png"><img alt="Imported with the fixed OOo" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/vml-text-fix-150x150.png"></a></p>
<p>Imported with the fixed OOo</p>Opening OpenXML or ODF files with Vim2009-04-15T09:49:00+02:002009-04-15T09:49:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-04-15:/opening-openxml-or-odf-files-with-vim.html<p>As I was tired to unzip my test .docx files to see what was
inside, I decided to ask the web for a solution. I have been gladly
surprised to see that Vim can natively open Zip files and change them.
All I had to do is to tell Vim …</p><p>As I was tired to unzip my test .docx files to see what was
inside, I decided to ask the web for a solution. I have been gladly
surprised to see that Vim can natively open Zip files and change them.
All I had to do is to tell Vim, that the docx, odt, and other OpenXML
and ODF extensions are Zip files. Here are the lines I have added to my
<code>.vimrc</code> file:</p>
<div class="highlight"><pre><span></span><code><span class="k">au</span> <span class="nb">BufReadCmd</span> *.docx<span class="p">,</span>*.xlsx<span class="p">,</span>*.pptx <span class="k">call</span> zip#Browse<span class="p">(</span>expand<span class="p">(</span><span class="s2">""</span><span class="p">))</span>
<span class="k">au</span> <span class="nb">BufReadCmd</span> *.odt<span class="p">,</span>*.ott<span class="p">,</span>*.ods<span class="p">,</span>*.ots<span class="p">,</span>*.odp<span class="p">,</span>*.otp<span class="p">,</span>*.odg<span class="p">,</span>*.otg <span class="k">call</span> zip#Browse<span class="p">(</span>expand<span class="p">(</span><span class="s2">""</span><span class="p">))</span>
</code></pre></div>
<p>Now debugging life will be easier for me, and maybe for you
too.</p>Shapes in Writer2009-04-01T11:51:00+02:002009-04-01T11:51:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2009-04-01:/shapes-in-writer.html<p>I'm currently working on importing the shapes' content of docx
files in OpenOffice.org and I found some troubling differences between
OOo and Word on this point.</p>
<ul>
<li>A shape Word can contain text, tables and other objects. A shape in
OOo can only contain text; to have a table inside …</li></ul><p>I'm currently working on importing the shapes' content of docx
files in OpenOffice.org and I found some troubling differences between
OOo and Word on this point.</p>
<ul>
<li>A shape Word can contain text, tables and other objects. A shape in
OOo can only contain text; to have a table inside a shape you need
to create a frame and then insert the table. The old doc import
filter is importing all the rectangle shape containing text as
frames as there is no difference between a textbox and a shape in
.doc files. The problems comes for the other shapes: e.g. an ellipse
contains a table in Word will be imported as an ellipse shape in
writer without the table. Data are lost here! Would it be worse an
effort to have shapes handled and laid out like frames?</li>
<li>A shape in Word can be rotated, and when the background is filled
with a picture, this one is also rotated with the shape (in fact
this is an option). A shape can be rotated in Writer, but the
picture can't be rotated. This leads to some ugly results when
importing such .doc file. Why can't a Writer shape be rotated in the
same way than draw shapes? Even for a user, it's fairly complicated
to rotate a shape in Writer...</li>
<li>In Writer, even the UNO API can set custom bitmaps as the background
of shapes, but there is nothing in the UI to select a custom picture
as the shape background. Isn't that strange?</li>
</ul>
<p>Here are two screenshots showing a .doc file in Word and OpenOffice.org
to better see the above differences.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/shapes-word.png"><img alt="Shapes in word" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/shapes-word-150x150.png"></a></p>
<p>Shapes in word </p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/shapes-ooo.png"><img alt="Shapes in OpenOffice.org" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/shapes-ooo-150x150.png"></a></p>
<p>Shapes in OpenOffice.org</p>Docx shapes import: first steps2009-03-27T18:02:00+01:002009-03-27T18:02:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-27:/docx-shapes-import-first-steps.html<p>One of the other big areas for improvement in the docx files
import is the import of the shapes, text boxes and other VML stuffs. The
fact is simple: there is no shape imported yet! The challenge here is to
reuse and expand some code of the <em>oox</em> module in …</p><p>One of the other big areas for improvement in the docx files
import is the import of the shapes, text boxes and other VML stuffs. The
fact is simple: there is no shape imported yet! The challenge here is to
reuse and expand some code of the <em>oox</em> module in order to share it with
the import of xlsx and pptx. After some time investigating how things
are working in the VML import code of oox and the <em>writerfilter</em>, I
found that the XML tokens between the two modules were using the same
constants but not the namespaces.</p>
<p>After having fixed this tokens issue, I managed to import some shapes.
After some hacks in the <em>oox</em> and the <em>writerfilter</em> module, here are
some results for the import:</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/mso1.png"><img alt="Shapes in Word 2007" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/mso1-150x150.png"></a></p>
<p>Shapes in Word 2007</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv1.png"><img alt="Shapes imported with OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv1-150x150.png"></a></p>
<p>Shapes imported with OdfConverter </p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-hacks.png"><img alt="Shapes imported in OOo with some hacks" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-hacks-150x150.png"></a></p>
<p>Shapes imported in OOo with some hacks </p>
<p>There are still a lot of things to do here, including:</p>
<ul>
<li>Create text frames where a rectangle shape can't be enough</li>
<li>Complete the VML import</li>
</ul>
<p>This is a first step and I hope to show more progresses
soon.</p>docx nested tables import2009-03-24T15:58:00+01:002009-03-24T15:58:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-24:/docx-nested-tables-import.html<p>The last weeks have been quite hard: I was working on
difficult parts of the writerfilter and sw code. I was working on a
patch to import the nested tables in the docx files. As you will be able
to see it, the import is much better, even thought it …</p><p>The last weeks have been quite hard: I was working on
difficult parts of the writerfilter and sw code. I was working on a
patch to import the nested tables in the docx files. As you will be able
to see it, the import is much better, even thought it is not yet
perfect. As usual, here are some screenshots to help you understand what
has changed.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/mso.png"><img alt="Nested tables in Word 2007" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/mso-150x150.png"></a></p>
<p>Nested tables in Word 2007</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-nf.png"><img alt="Nested tables imported by OOo without patch" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-nf-150x150.png"></a></p>
<p>Nested tables imported by OOo without patch</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv.png"><img alt="Nested tables imported using OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/odfconv-150x150.png"></a></p>
<p>Nested tables imported using OdfConverter</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-fixed.png"><img alt="Nested tables imported by OOo with the all docx import patches" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/ooo-fixed-150x150.png"></a></p>
<p>Nested tables imported by OOo with the all docx import patches </p>
<p>Of course, in the above screenshots, the one of the non-fixed OOo
doesn't include any of the previous docx import patches I previously
mentionned, whereas the one with the fixed OOo includes them
all.</p>gdb and SwDoc2009-03-20T19:10:00+01:002009-03-20T19:10:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-20:/gdb-and-swdoc.html<p>Today I needed to see what happened in a Writer document. In
order to do this I used gdb to explore the state of the <em>SwDoc</em> object.
I was particularly interested in the nodes which where present, but
checking the type, sub-type of all of them can be long. Then …</p><p>Today I needed to see what happened in a Writer document. In
order to do this I used gdb to explore the state of the <em>SwDoc</em> object.
I was particularly interested in the nodes which where present, but
checking the type, sub-type of all of them can be long. Then I created a
small gdb define to help in this task. Here is the code, needing the
functions defined on the wiki
<a href="http://wiki.services.openoffice.org/wiki/Debugging#The_recommended_.gdbinit_file">http://wiki.services.openoffice.org/wiki/Debugging#The_recommended_.gdbinit_file</a>:</p>
<div class="highlight"><pre><span></span><code><span class="n">def</span> <span class="n">pIndent</span>
<span class="k">set</span> <span class="err">$</span><span class="k">level</span> <span class="o">=</span> <span class="err">$</span><span class="n">arg0</span>
<span class="k">set</span> <span class="err">$</span><span class="n">iLevel</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">while</span> <span class="p">(</span> <span class="err">$</span><span class="n">iLevel</span> <span class="o"><</span> <span class="err">$</span><span class="k">level</span> <span class="p">)</span>
<span class="n">printf</span> <span class="ss">"\t"</span>
<span class="k">set</span> <span class="err">$</span><span class="n">iLevel</span> <span class="o">=</span> <span class="err">$</span><span class="n">iLevel</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">def</span> <span class="n">pNodes</span>
<span class="k">set</span> <span class="err">$</span><span class="n">doc</span> <span class="o">=</span> <span class="err">$</span><span class="n">arg0</span>
<span class="k">set</span> <span class="err">$</span><span class="k">size</span> <span class="o">=</span> <span class="err">$</span><span class="n">doc</span><span class="o">-></span><span class="n">aNodes</span><span class="o">-></span><span class="n">nSize</span>
<span class="k">set</span> <span class="err">$</span><span class="n">iNodes</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">set</span> <span class="err">$</span><span class="n">indent</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">while</span> <span class="p">(</span> <span class="err">$</span><span class="n">iNodes</span><span class="o">++<</span><span class="err">$</span><span class="k">size</span> <span class="o">&&</span> <span class="err">$</span><span class="n">iNodes</span><span class="o"><</span><span class="mi">255</span> <span class="p">)</span>
<span class="k">set</span> <span class="err">$</span><span class="n">node</span><span class="o">=</span><span class="err">$</span><span class="n">doc</span><span class="o">-></span><span class="n">aNodes</span><span class="p">[</span><span class="err">$</span><span class="n">iNodes</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="p">(</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">nNodeType</span> <span class="o">==</span> <span class="mi">1</span> <span class="p">)</span>
<span class="k">set</span> <span class="err">$</span><span class="n">indent</span> <span class="o">=</span> <span class="err">$</span><span class="n">indent</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="n">pIndent</span> <span class="err">$</span><span class="n">indent</span>
<span class="n">printf</span> <span class="ss">"Node %d - Type: %d, SoS: %d"</span><span class="p">,</span> <span class="err">$</span><span class="n">iNodes</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">nNodeType</span><span class="p">,</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">pStartOfSection</span><span class="o">-></span><span class="n">nOffset</span>
<span class="k">if</span> <span class="p">(</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">nNodeType</span> <span class="o">==</span> <span class="mi">2</span> <span class="o">||</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">nNodeType</span> <span class="o">==</span> <span class="mi">6</span> <span class="p">)</span>
<span class="n">printf</span> <span class="ss">", EoS: %d"</span><span class="p">,</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">GetStartNode</span><span class="p">(</span> <span class="p">)</span><span class="o">-></span><span class="n">pEndOfSection</span><span class="o">-></span><span class="n">nOffset</span>
<span class="k">set</span> <span class="err">$</span><span class="n">indent</span> <span class="o">=</span> <span class="err">$</span><span class="n">indent</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">if</span> <span class="p">(</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">IsTxtNode</span><span class="p">(</span> <span class="p">)</span> <span class="p">)</span>
<span class="n">printf</span> <span class="ss">", Text: "</span>
<span class="k">set</span> <span class="err">$</span><span class="n">txt</span> <span class="o">=</span> <span class="err">$</span><span class="n">node</span><span class="o">-></span><span class="n">GetTxtNode</span><span class="p">(</span> <span class="p">)</span><span class="o">-></span><span class="n">aText</span>
<span class="n">ptu</span> <span class="err">$</span><span class="n">txt</span>
<span class="k">else</span>
<span class="n">printf</span> <span class="ss">"\n"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>The values in this file are needed to better understand the ouput:
<a href="http://svn.services.openoffice.org/opengrok/xref/DEV300_m40/sw/inc/ndtyp.hxx">http://svn.services.openoffice.org/opengrok/xref/DEV300_m40/sw/inc/ndtyp.hxx</a>.
This function has to be called with the instance of the <em>SwDoc</em> object
as parameter.</p>Last docx import fixes2009-03-13T16:15:00+01:002009-03-13T16:15:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-13:/last-docx-import-fixes.html<p>I had no time to write a post for each new fix I made this
week, then here is a summary of what happened. Don't blame me for
providing screenshots only for some very visible points instead of every
fix.</p>
<h4>Changes tracking import</h4>
<p>This was and is still a big …</p><p>I had no time to write a post for each new fix I made this
week, then here is a summary of what happened. Don't blame me for
providing screenshots only for some very visible points instead of every
fix.</p>
<h4>Changes tracking import</h4>
<p>This was and is still a big area for improvement. I first fixed what I
saw easily in some example documents but it's quite hard to find every
single bug in there. If you find others, please don't hesitate to leave
me a message or some issue either on IZ or Novell's bugzilla. Here is a
list of what have been fixed for the changes tracking:</p>
<ul>
<li>When inserting a footnote or endnote, the imported redline was
completely wrong</li>
<li>When there are several changes on the same piece of text only one
was imported</li>
<li>The added / removed paragraphs weren't imported</li>
<li>The changes weren't shown by default in OOo when opening a document
with changes</li>
<li>The changes weren't tracked in OOo as the documents settings weren't
read at all. The settings.xml import has been fixed / started, but
it currently handles only this property.</li>
</ul>
<p>There are some points to be aware of if you want to try to find other
changes tracking issues:</p>
<ul>
<li>Compare with what is imported by OOo when opening the same file in
.doc: OOo doesn't support all the changes tracks of Word: checking
what the .doc import does is a quick way to check if OOo can usually
handle this kind of change.</li>
<li>Open the <em>"Review & Approve"</em> dialog in OOo and compare these
entries with the changes in Word: OOo isn't showing the changes in
the same way than Word and there might be some display problems.</li>
</ul>
<h4>Page number alignement</h4>
<p>There where problems of page numbers alignement in some cases: this came
from a too large minimum width of the frame. By defining this constant
to 0, the frame is now fitting to its content automatically
(<a href="http://qa.openoffice.org/issues/show_bug.cgi?id=93786">i#93786</a>)</p>
<h4>Page borders import</h4>
<p>The page borders weren't imported at all: it is now fixed. Here are some
screenshots to better understand what happened. The test document is
attached to the issue <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=100176">i#00176</a>.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-mso.png"><img alt="Page borders in Word 2007" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-mso-150x150.png"></a></p>
<p>Page borders in Word 2007</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-ooo.png"><img alt="Page borders imported in OOo" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-ooo-150x150.png"></a></p>
<p>Page borders imported in OOo</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-odfconv.png"><img alt="Page Borders imported with OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-odfconv-150x150.png"></a></p>
<p>Page Borders imported with OdfConverter</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-fixed.png"><img alt="Page borders import fixed" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pgborder-fixed-150x150.png"></a></p>
<p>Page borders import fixed</p>
<h4>A CWS for all those fixes</h4>
<p>As it starts to make a small amount of changes to the code, I have also
created a CWS to up-stream the changes:
<strong>writerfilter32bugfixes01</strong>.</p>Pictures in docx import2009-03-04T18:12:00+01:002009-03-04T18:12:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-04:/pictures-in-docx-import.html<p>As I explained it in a previous post, I am working on fixing
docx import in OpenOffice.org. I have fixed a bug on the pictures import
recently. The patch fixes the issues i#97645 and i#96021. The i#96021
issue fix isn't complete yet, because it has something …</p><p>As I explained it in a previous post, I am working on fixing
docx import in OpenOffice.org. I have fixed a bug on the pictures import
recently. The patch fixes the issues i#97645 and i#96021. The i#96021
issue fix isn't complete yet, because it has something to do with shapes
import which aren't working at all. The patch has been committed to
go-oo trunk. As one of the fixes isn't complete, I still haven't
submitted it to the upstream.</p>
<p>Here are some screenshots to show the differences:</p>
<p><img alt="Picture in Word 2007" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/picture-mso.png"></p>
<p>Picture in Word 2007</p>
<p><img alt="Pictures import in OOo without the patch" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/pcture-nf.png"></p>
<p>Pictures import in OOo without the patch</p>
<p><img alt="Picture import in OOo using OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/picture-conv.png"></p>
<p>Picture import in OOo using OdfConverter</p>
<p><img alt="Picture imported in OOo with the patch" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/picture-ooo.png"></p>
<p>Picture imported in OOo with the patch</p>
<p>Thanks again Andrew for providing your useful reference document and
pointing out the bugs.</p>XPath search in Vim2009-03-03T11:07:00+01:002009-03-03T11:07:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-03-03:/xpath-search-in-vim.html<p>You might already have to work with huge XML files. Using regexp
searches aren't really handy as you easily get lost in the XML file. I
am currently working with a really enormous XML file. I have then
written some small Perl and Vim script to search in XML files …</p><p>You might already have to work with huge XML files. Using regexp
searches aren't really handy as you easily get lost in the XML file. I
am currently working with a really enormous XML file. I have then
written some small Perl and Vim script to search in XML files using
XPath. I have been mostly inspired by those pages:</p>
<ul>
<li><a href="http://use.perl.org/~Ovid/journal/36682">http://use.perl.org/~Ovid/journal/36682</a> for the Perl script
base</li>
<li><a href="http://vim.wikia.com/wiki/Temporarily_replace_grep_with_a_custom_program">http://vim.wikia.com/wiki/Temporarily_replace_grep_with_a_custom_program</a>
for the Vim integration part</li>
</ul>
<h4>Installing</h4>
<p>The Perl program mentioned in the first link has been heavily changed to
report a clean filename, line number and message to use in the Vim
quickfix window. All you need is to copy the Perl script into your PATH
and name it <code>xpath</code> (really original name), then copy the <code>.vimrc</code>
fragment into your <code>.vimrc</code> file.</p>
<p>Perl script:</p>
<div class="highlight"><pre><span></span><code><span class="ch">#!/usr/bin/env perl</span>
<span class="k">use</span> <span class="nn">strict</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">warnings</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">XML::LibXML</span><span class="p">;</span>
<span class="k">my</span> <span class="p">(</span> <span class="nv">$filename</span><span class="p">,</span> <span class="nv">$xpath</span><span class="p">,</span> <span class="nv">$rname</span> <span class="p">)</span> <span class="o">=</span> <span class="nv">@ARGV</span><span class="p">;</span>
<span class="k">unless</span> <span class="p">(</span> <span class="nb">defined</span> <span class="nv">$rname</span> <span class="p">)</span> <span class="p">{</span>
<span class="nv">$rname</span> <span class="o">=</span> <span class="nv">$filename</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">my</span> <span class="nv">$parser</span> <span class="o">=</span> <span class="nn">XML::LibXML</span><span class="o">-></span><span class="k">new</span><span class="p">();</span>
<span class="k">my</span> <span class="nv">$doc</span> <span class="o">=</span> <span class="nv">$parser</span><span class="o">-></span><span class="n">parse_file</span><span class="p">(</span> <span class="nv">$filename</span> <span class="p">);</span>
<span class="k">my</span> <span class="nv">$xc</span> <span class="o">=</span> <span class="nn">XML::LibXML::XPathContext</span><span class="o">-></span><span class="k">new</span><span class="p">(</span> <span class="nv">$doc</span> <span class="p">);</span>
<span class="k">my</span> <span class="nv">$nodes</span> <span class="o">=</span> <span class="nv">$xc</span><span class="o">-></span><span class="n">findnodes</span><span class="p">(</span> <span class="nv">$xpath</span> <span class="p">);</span>
<span class="k">my</span> <span class="nv">$found</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">foreach</span> <span class="k">my</span> <span class="nv">$node</span> <span class="p">(</span> <span class="nv">$nodes</span><span class="o">-></span><span class="n">get_nodelist</span> <span class="p">)</span> <span class="p">{</span>
<span class="nv">$found</span><span class="o">++</span><span class="p">;</span>
<span class="k">print</span> <span class="nv">$rname</span><span class="p">,</span> <span class="s">":"</span><span class="p">,</span> <span class="nv">$node</span><span class="o">-></span><span class="n">line_number</span><span class="p">(),</span> <span class="s">" "</span><span class="p">,</span> <span class="nv">$node</span><span class="o">-></span><span class="n">nodePath</span><span class="p">(</span> <span class="p">)</span> <span class="p">,</span><span class="s">"\n"</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">unless</span> <span class="p">(</span> <span class="nv">$found</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">print</span> <span class="s">"No XML found matching xpath '$xpath'\n"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p><code>.vimrc</code> fragment:</p>
<div class="highlight"><pre><span></span><code><span class="k">function</span><span class="p">!</span> XMLMappings<span class="p">()</span>
<span class="nb">noremap</span> ;xp :<span class="k">call</span> Xpath<span class="p">()</span>
<span class="k">endfunction</span>
<span class="k">function</span><span class="p">!</span> Xpath<span class="p">()</span>
<span class="c">" Needs to get the real file name for the quickfix window</span>
<span class="k">let</span> realname <span class="p">=</span> bufname<span class="p">(</span> <span class="s2">"%"</span> <span class="p">)</span>
<span class="c">" Write the buffer to a temp file</span>
<span class="k">let</span> filename <span class="p">=</span> tempname<span class="p">()</span>
<span class="k">let</span> <span class="nb">lines</span> <span class="p">=</span> getline<span class="p">(</span> <span class="m">1</span><span class="p">,</span> <span class="s2">"$"</span> <span class="p">)</span>
<span class="k">call</span> writefile<span class="p">(</span> <span class="nb">lines</span><span class="p">,</span> filename <span class="p">)</span>
<span class="k">let</span> xpath <span class="p">=</span> input<span class="p">(</span><span class="s2">"Enter xpath expression: "</span><span class="p">)</span>
<span class="k">let</span> tmp1<span class="p">=</span>&<span class="nb">grepprg</span>
<span class="k">let</span> tmp2<span class="p">=</span>&<span class="nb">grepformat</span>
<span class="k">set</span> <span class="nb">grepformat</span><span class="p">=</span>%<span class="k">f</span>:%<span class="k">l</span>\ %<span class="k">m</span>
<span class="k">set</span> <span class="nb">grepprg</span><span class="p">=</span>xpath
exe <span class="s2">"grep "</span>.escape<span class="p">(</span>filename<span class="p">,</span> <span class="s1">' \'</span><span class="p">)</span>.<span class="s2">" \""</span>.xpath.<span class="s2">"\" "</span>.escape<span class="p">(</span>realname<span class="p">,</span> <span class="s1">' \'</span><span class="p">)</span>
<span class="k">let</span> &<span class="nb">grepprg</span><span class="p">=</span>tmp1
<span class="k">let</span> &<span class="nb">grepformat</span><span class="p">=</span>tmp2
<span class="k">endfunction</span>
</code></pre></div>
<h4>Using</h4>
<p>To use this feature, open an XML file and type <code><leader>xp</code>, then type
your XPath expression. <code><leader></code> is the '<code>\</code>' key by default but you
may have changed it. <strong>The Perl script handles the namespaces in the
XPath expressions</strong>.</p>OOXML tables import in docx files fixed2009-02-20T19:10:00+01:002009-02-20T19:10:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-02-20:/ooxml-tables-import-in-docx-files-fixed.html<p>Thanks to Andrew Ziem in his post <a href="http://www.oooninja.com/2008/12/better-office-docx-converter.html">A Better Office .docx
converter</a>, I have discovered a place needing many improvements in
OOo. I started to fix the border problem exposed in Andrew's document,
but then found that the table styles weren't imported. This problem is
now fixed in go-oo trunk …</p><p>Thanks to Andrew Ziem in his post <a href="http://www.oooninja.com/2008/12/better-office-docx-converter.html">A Better Office .docx
converter</a>, I have discovered a place needing many improvements in
OOo. I started to fix the border problem exposed in Andrew's document,
but then found that the table styles weren't imported. This problem is
now fixed in go-oo trunk and a patch has been submitted on IssueZilla.</p>
<p>The best way to understand the problem is to consider the following
screenshots. To show how important these styles are, simply consider
that the simple-black-border tables in word are using a style.</p>
<p>The document in Word 2007:</p>
<p><img alt="Tables in Word 2007" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/tables-import-mso.png"></p>
<p>Tables in Word 2007</p>
<p>The document opened by OpenOffice.org (dev300m40):</p>
<p><img alt="Tables in OOo without the fixes" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/table-import-ooo-nf1.png"></p>
<p>Tables in OOo without the fixes</p>
<p>The document opened by ooo-build using the OdfConverter:</p>
<p><img alt="Tables in OOo using OdfConverter" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/table-import-ooo-odfconv1.png"></p>
<p>Tables in OOo using OdfConverter</p>
<p>The document opened by OpenOffice.org with the fixes:</p>
<p><img alt="Tables imported by OOo after fixes" src="https://bosdonnat.fr/data/OpenOffice.org/ooxml/table-import-ooo.png"></p>
<p>Tables imported by OOo after fixes</p>
<p>As Andrew pointed it, there are still other places of improvements in
the docx files import; I will continue to fix them: many thanks
Andrew!</p>Using Vim for OOo development2009-01-13T21:19:00+01:002009-01-13T21:19:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2009-01-13:/using-vim-for-ooo-development.html<p>Since I have only 5 fingers on each hand, I prefer using Vim to develop
in C++ for OpenOffice.org. I have found some tricks that help me working
that I would like to share in this post. I am sorry for those coding on
windows, but I don't know …</p><p>Since I have only 5 fingers on each hand, I prefer using Vim to develop
in C++ for OpenOffice.org. I have found some tricks that help me working
that I would like to share in this post. I am sorry for those coding on
windows, but I don't know how all this could be transposed to window...
cygwin could certainly be useful in this case.</p>
<h2>tags</h2>
<p>First things first, a ctags database for the whole OpenOffice.org code
is mandatory: it helps to find identifiers in all this code without
knowing exactly where it is defined. If this ctags base is correctly
generated, it could also provide autocompletion when typing C++ code in
Vim. Here is how I generate my ctags database after cd'ing into the OOo
sources directory and having sourced the OOo environment:</p>
<div class="highlight"><pre><span></span><code><span class="nv">omnicppoptions</span><span class="o">=</span><span class="s2">"--c++-kinds=+p --fields=+iaS --extra=+q"</span>
ctags -h <span class="s2">"+.hdl.hrc"</span> --langmap<span class="o">=</span>c:+.hdl.hrc.src <span class="nv">$omnicppoptions</span> -R --exclude<span class="o">=</span>unxlngi6<span class="se">\.</span>pro
--exclude<span class="o">=</span>binfilter --exclude<span class="o">=</span>solver --totals<span class="o">=</span>yes --sort<span class="o">=</span>foldcase *
</code></pre></div>
<p>The <code>binfilter</code> and <code>solver</code> are excluded from the indexing process to
avoid having types defined twice or more as <code>binfilter</code> is mostly a copy
of other code of OOo and the <code>solver</code> is the place where all the build
results are delivered. Excluding the <code>unxlngi6.pro</code> directories avoids
having duplicate types, but hides some header files generated by the
build. The <code>unxlngi6.pro</code> exclude has to be changed according to the
<code>INPATH</code> environment variable.</p>
<p>Define the <code>tags</code> variable in <code>.vimrc</code> to be able to locate the tags
file wen editing a source file. Here is my definition taken from the OOo
wiki:</p>
<div class="highlight"><pre><span></span><code><span class="k">set</span> <span class="k">tags</span><span class="p">=</span>.<span class="sr">/tags,./</span>..<span class="sr">/tags,./</span>..<span class="sr">/../</span><span class="k">tags</span><span class="p">,</span>.<span class="sr">/../</span>..<span class="sr">/../</span><span class="k">tags</span><span class="p">,</span>.<span class="sr">/../</span>..<span class="sr">/../</span>..<span class="sr">/tags,./</span>..<span class="sr">/../</span>..<span class="sr">/../</span>..<span class="sr">/tags,tags,../</span><span class="k">tags</span><span class="p">,</span>..<span class="sr">/../</span><span class="k">tags</span><span class="p">,</span>..<span class="sr">/../</span>..<span class="sr">/tags,../</span>..<span class="sr">/../</span>..<span class="sr">/tags,../</span>..<span class="sr">/../</span>..<span class="sr">/../</span><span class="k">tags</span><span class="p">,~</span>/<span class="k">tags</span>
</code></pre></div>
<p>Now, finding a type in Vim is quite easy: I am using most of the time
the vim command <code>:ts TheTypeToFind</code>. Using the <code>:ta</code> command or <code>Ctrl-]</code>
is also possible, but the first result is not necessarily the
interesting one.</p>
<p>Installing the OmniCppComplete plugin for Vim is also a good idea. It
can be found here:
<a href="http://www.vim.org/scripts/script.php?script_id=1520">http://www.vim.org/scripts/script.php?script_id=1520</a>.</p>
<h2>Building from Vim</h2>
<p>There are some details about that point on the wiki page
<a href="http://wiki.services.openoffice.org/wiki/Editor_Vim">http://wiki.services.openoffice.org/wiki/Editor_Vim</a> but I have
changed it a little to make it work properly for me. Here is the part of
my <code>.vimrc</code> for this:</p>
<div class="highlight"><pre><span></span><code><span class="k">set</span> <span class="nb">makeef</span><span class="p">=</span>$TMPDIR/<span class="k">vim</span>##.err
<span class="c">" Call appropriate makeprg with Ctrl+K</span>
map :<span class="k">call</span> Make<span class="p">()</span>
<span class="k">if</span> $SOLARENV <span class="p">==</span> <span class="s2">""</span>
<span class="c"> " Normal makeprg, not in OpenOffice.org/StarOffice environment</span>
<span class="k">function</span> Make<span class="p">()</span>
<span class="k">make</span>
<span class="k">endfun</span>
<span class="k">else</span>
<span class="c"> " Define the make tool. Doesn't works with Vim: report to the OOo wiki</span>
<span class="k">set</span> <span class="nb">makeprg</span><span class="p">=</span>build.pl\ <span class="k">debug</span><span class="p">=</span>true
<span class="k">function</span> Make<span class="p">()</span>
<span class="k">let</span> my_local_path <span class="p">=</span> expand<span class="p">(</span><span class="s2">"%:h"</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span>my_local_path <span class="p">==</span> <span class="s2">""</span><span class="p">)</span>
<span class="k">let</span> my_local_path <span class="p">=</span> <span class="s2">"."</span>
<span class="k">endif</span>
<span class="k">if</span> filereadable<span class="p">(</span> my_local_path . <span class="s2">"/makefile.mk"</span> <span class="p">)</span>
exec <span class="s1">'lcd '</span> . my_local_path
<span class="k">call</span> SetMakeprg<span class="p">()</span>
<span class="k">make</span>
<span class="k">else</span>
echo <span class="s2">"No makefile.mk in "</span> . my_local_path
<span class="k">endif</span>
<span class="k">endfun</span>
<span class="k">endif</span>
<span class="c">" previous and next compiler error (quickfix)</span>
map :<span class="k">cp</span>
map :<span class="k">cn</span>
</code></pre></div>
<p>To automatically deliver the build results before returning to the code,
some lines needs to be added to the <code>.vimrc</code> file:</p>
<div class="highlight"><pre><span></span><code><span class="k">if</span> has<span class="p">(</span><span class="s2">"autocmd"</span><span class="p">)</span>
<span class="k">if</span> $SOLARENV <span class="p">!=</span> <span class="s2">""</span>
autocmd <span class="nb">QuickFixCmdPost</span> <span class="k">make</span> <span class="p">!</span>deliver.pl <span class="m">2</span><span class="p">></span>&<span class="m">1</span> <span class="p">|</span> <span class="k">grep</span> delivered
<span class="k">endif</span>
<span class="k">endif</span>
</code></pre></div>
<h2>Other useful commands</h2>
<p>The next points aren't useful only for OpenOffice.org development, but
also any other one. I am giving them unsorted here:</p>
<ul>
<li>I often run a shell and want have the output in a buffer. Here is a
Vim tip which helps for this:
<a href="http://vim.wikia.com/wiki/Display_shell_commands%27_output_on_Vim_window">http://vim.wikia.com/wiki/Display_shell_commands%27_output_on_Vim_window</a>.</li>
<li>Reading huge methods or files is often hard as its structure is hard
to see. Vim has a really good folding support for C++: just run the
following command or add it to the <code>.vimrc</code> file:
<code>set foldmethod=syntax</code>. To open a folded part of code, place the
cursor on the fold and type <code>zo</code>. To close it, simply type <code>zc</code> in
the code to fold.</li>
<li>By navigating in the sources using <code>lgrep</code> or the tags, I often come
to have a lot of opened buffers. Buffers can be closed using the
<code>bd</code> command, the <code>close</code> command only closes the Vim window.</li>
<li>To indent properly some parts of the code, there is an easy way:
apply the <code>indent</code> shell command to the current selection. I often
run it like this: <code>:'<,'>!indent -prs -i4 -nut</code>. To avoid repeating
the <code>indent</code> options every time, they could be set in the
<code>~/.indent.pro</code>. Of course, <code>indent</code> has much more options, but read
the <code>man</code> page to get them all.</li>
<li>Sometime I open a Vim window like the locations window, but it opens
at the bottom of the screen and I want it as a vertical split on the
left. In order to do this, I simply use the <code>Ctrl-w + H</code> (note the
uppercase <code>H</code>). This command and all its <code>J</code>, <code>K</code> and <code>L</code> friends
are helping a lot to rearrange the windows.</li>
</ul>Bootstrapping OOo from Java2008-12-13T15:10:00+01:002008-12-13T15:10:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-12-13:/bootstrapping-ooo-from-java.html<p>As you may have read it I have been working for some time on a
new system to bootstrap OpenOffice.org from the Eclipse integration. I
will take this occasion to explain how to bootstrap OOo in a Java
application.</p>
<h3>The problem</h3>
<p>You may have already encountered that problem, because …</p><p>As you may have read it I have been working for some time on a
new system to bootstrap OpenOffice.org from the Eclipse integration. I
will take this occasion to explain how to bootstrap OOo in a Java
application.</p>
<h3>The problem</h3>
<p>You may have already encountered that problem, because it is quite
common: when using the <code>Bootstrap</code> class provided by OpenOffice.org jars
a message like <strong>No office executable has been found</strong> is often
displayed. After some investigations we often discover that this is a
<code>ClassLoader</code> problem. There are many documentations and code snippets
on the web explaining what are class loaders in Java, but it is often
hard to apply to our problem.</p>
<p>In fact the <code>Boostrap</code> class will try to find the <code>soffice</code> file using
its class loader. In Java each class is loaded by a class loader. Class
loaders are organized in a tree structure: a class loader has a parent
(generally the one used to load the class of the class loader). On the
top of the tree there is the JVM classloader. When looking for a class
or resource, a class loader will look if it can load the class or
resource, and will delegate to its parent if that resource or class file
can't be found be that class loader.</p>
<p>This means that I can create a simple Java application bootstrapping OOo
with no custom class loader. But that implies that the <code>LD_LIBRARY_PATH</code>
and <code>CLASSPATH</code> variables are properly set before starting the
application. Defining a custom class loader using the OpenOffice.org
installation path would be a much better idea: this is what I will show
in the next lines.</p>
<h3>A custom class loader for OOo classes</h3>
<p>The class loader that we need to create has only to inherit from the
<code>URLClassLoader</code> and be provided the URL to the OpenOffice.org jars and
library directories. For OpenOffice.org 3 it means that you need to add
the URLs for:</p>
<ul>
<li>every Jar file of the Basis layer, in
<code>/path/to/ooo/basis-link/program/classes</code></li>
<li>every Jar file of the URE, in
<code>/path/to/ooo/basis-link/ure-link/share/java</code></li>
<li>the Basis layer program directory, ie:
<code>/path/to/ooo/basis-link/program</code></li>
<li>the URE lib directory, ie: <code>/path/to/ooo/basis-link/ure-link/lib</code></li>
</ul>
<p>We also need to add our application's own code to the URLs in order to
load our OOo-specific classes by that class loader.</p>
<p>Here is a sample class loader extracted from the Eclipse integration
code (simplified). <code>IOOo</code> is an interface describing the OpenOffice.org
instance to use:</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">OfficeClassLoader</span> <span class="kd">extends</span> <span class="n">URLClassLoader</span> <span class="p">{</span>
<span class="kd">public</span> <span class="nf">OfficeClassLoader</span><span class="p">(</span><span class="n">IOOo</span> <span class="n">pOOo</span><span class="p">,</span> <span class="n">ClassLoader</span> <span class="n">pParent</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">super</span><span class="p">(</span><span class="n">getUrls</span><span class="p">(</span><span class="n">pOOo</span><span class="p">),</span> <span class="n">pParent</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="n">URL</span><span class="o">[]</span> <span class="nf">getUrls</span><span class="p">(</span><span class="n">IOOo</span> <span class="n">pOOo</span><span class="p">)</span> <span class="p">{</span>
<span class="n">LinkedList</span> <span class="n">oUrls</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinkedList</span><span class="p">();</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">String</span><span class="o">[]</span> <span class="n">javaPaths</span> <span class="o">=</span> <span class="n">pOOo</span><span class="p">.</span><span class="na">getClassesPath</span><span class="p">();</span>
<span class="n">URL</span> <span class="n">bundleUrl</span> <span class="o">=</span> <span class="n">OOEclipsePlugin</span><span class="p">.</span><span class="na">getDefault</span><span class="p">().</span><span class="na">getBundle</span><span class="p">().</span><span class="na">getResource</span><span class="p">(</span><span class="s">"/"</span><span class="p">);</span> <span class="c1">//$NON-NLS-1$</span>
<span class="n">URL</span> <span class="n">plugin</span> <span class="o">=</span> <span class="n">FileLocator</span><span class="p">.</span><span class="na">resolve</span><span class="p">(</span><span class="n">bundleUrl</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">path</span> <span class="p">:</span> <span class="n">javaPaths</span><span class="p">)</span> <span class="p">{</span>
<span class="n">File</span> <span class="n">dir</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="p">(</span><span class="n">path</span><span class="p">);</span>
<span class="n">File</span><span class="o">[]</span> <span class="n">jars</span> <span class="o">=</span> <span class="n">dir</span><span class="p">.</span><span class="na">listFiles</span><span class="p">(</span><span class="k">new</span> <span class="n">FileFilter</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">accept</span><span class="p">(</span><span class="n">File</span> <span class="n">pTested</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">pTested</span><span class="p">.</span><span class="na">getName</span><span class="p">().</span><span class="na">endsWith</span><span class="p">(</span><span class="s">".jar"</span><span class="p">);</span> <span class="c1">//$NON-NLS-1$</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">for</span> <span class="p">(</span><span class="n">File</span> <span class="n">jar</span> <span class="p">:</span> <span class="n">jars</span><span class="p">)</span> <span class="p">{</span>
<span class="n">oUrls</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">jar</span><span class="p">.</span><span class="na">toURI</span><span class="p">().</span><span class="na">toURL</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">String</span><span class="o">[]</span> <span class="n">libsPath</span> <span class="o">=</span> <span class="n">pOOo</span><span class="p">.</span><span class="na">getLibsPath</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">path</span> <span class="p">:</span> <span class="n">libsPath</span><span class="p">)</span> <span class="p">{</span>
<span class="n">oUrls</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="k">new</span> <span class="n">File</span><span class="p">(</span><span class="n">path</span><span class="p">).</span><span class="na">toURI</span><span class="p">().</span><span class="na">toURL</span><span class="p">());</span>
<span class="p">}</span>
<span class="n">oUrls</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">plugin</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">PluginLogger</span><span class="p">.</span><span class="na">error</span><span class="p">(</span><span class="s">"Failed to create the OfficeClassLoader"</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">oUrls</span><span class="p">.</span><span class="na">toArray</span><span class="p">(</span><span class="k">new</span> <span class="n">URL</span><span class="o">[</span><span class="n">oUrls</span><span class="p">.</span><span class="na">size</span><span class="p">()</span><span class="o">]</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Now that we have that class loader, how should it be used? The only
point to know is that we need to be sure that our classes bootstrapping
OpenOffice.org and handling its API have to be loaded by this custom
class loader. This means that we have to use the Java introspection API
to instanciate the class and run the desired method. Here is a small
example using the above class loader:</p>
<div class="highlight"><pre><span></span><code><span class="n">OfficeClassLoader</span> <span class="n">oooClassLoader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">OfficeClassLoader</span><span class="p">.</span><span class="na">getClassLoader</span><span class="p">(</span><span class="n">getOOo</span><span class="p">(),</span>
<span class="n">TypesGetter</span><span class="p">.</span><span class="na">class</span><span class="p">.</span><span class="na">getClassLoader</span><span class="p">());</span>
<span class="n">Class</span> <span class="n">clazz</span> <span class="o">=</span> <span class="n">oooClassLoader</span><span class="p">.</span><span class="na">loadClass</span><span class="p">(</span><span class="s">"org.openoffice.test.MyOOoAction"</span><span class="p">);</span>
<span class="n">Object</span> <span class="n">myAction</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="na">newInstance</span><span class="p">();</span>
</code></pre></div>
<p>The <code>MyOOoAction</code> class can now call the famous <code>Bootstrap.bootstrap()</code>
method and use the connection to OpenOffice.org.</p>
<h3>Tips & Tricks</h3>
<p>However, this is not exactly what I have done for the Eclipse
integration. I had several needs:</p>
<ul>
<li>the action classes needed to return some results to be used
somewhere else. These results are classes of the Eclipse integration
which are not related to the OpenOffice.org API at all. If I add the
URL of the Eclipse plugin code to the class loader URLs, I can
instanciate those classes in the OOo-specific classes. However Java
does consider that class <code>A</code> loaded by <code>ClassLoader1</code> is not the
same thing than class <code>A</code> loaded by <code>ClassLoader2</code>. I cannot cast
those results using classes loaded by an other class loader: the
shared classes have to be loaded by the Eclipse plugin class loader.</li>
<li>the Eclipse integration can start and stop OpenOffice.org several
times in the application lifetime. The same OpenOffice.org libraries
can't be loaded twice by two different instances of the same class
loader.</li>
</ul>
<p>In order to address those two needs, I had to:</p>
<ul>
<li>Redefine the <code>loadClass</code> method of the <code>OfficeClassLoader</code> in order
to make it load only the OOo-specific classes of the Eclipse
Integration. All the other classes have to be loaded by the parent
class loader: the normal one of the Eclipse plugin. In order to do
this I had to impose that all the OOo-specific classes are grouped
into one precise package.</li>
<li>Cache the class loader and re-use them when I needed to bootstrap
again the same instance of OOo.</li>
</ul>Eclipse integration and OOo 32008-12-02T11:11:00+01:002008-12-02T11:11:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-12-02:/eclipse-integration-and-ooo-3.html<p>For some time, I have been working on one of your comments on
the Eclipse integration: I am making it work with OpenOffice.org 3.0 and
its SDK. In the same time, I have found some problems with the UNO types
browser. I have started to fix them and …</p><p>For some time, I have been working on one of your comments on
the Eclipse integration: I am making it work with OpenOffice.org 3.0 and
its SDK. In the same time, I have found some problems with the UNO types
browser. I have started to fix them and improve the OpenOffice.org
bootstrapping system from Eclipse.</p>
<ol>
<li>The Eclipse integration will now be able to bootstrap OpenOffice.org
2.x or 3.0 with some custom classloader instead of running a small
Java application and reading its output. This will improve the
stability of the UNO types provider. I won't explain this custom
classloader system here, but it will certainly be the topic of a
next post.</li>
<li>The fetched UNO types will be stored in a cache on the Eclipse side.
The user will be able to refresh this cache. This improvement will
increase the speed to display the UNO types selection list: the UNO
types don't change so often.</li>
</ol>
<p>Among the other points I would like to improve is the build system. It
is yet depending on the Eclipse integration and I would like to extract
the necessary code for the manifest generation and provide some ant
scripts generating a package from the project sources.</p>
<p>As I am working on the Eclipse integration during my spare time now, I
have no time to fix some important bugs on the COOoder extension. I hope
you will understand the timing issue...</p>A time for changes2008-11-28T16:32:00+01:002008-11-28T16:32:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-11-28:/a-time-for-changes.html<p>December will be the start of a new way of life for me and my
wife.</p>
<ul>
<li>First, I will work at Novell on OpenOffice.org. I will be able to
work in this familiar open source project again. On top of that I
will work from home and thus have …</li></ul><p>December will be the start of a new way of life for me and my
wife.</p>
<ul>
<li>First, I will work at Novell on OpenOffice.org. I will be able to
work in this familiar open source project again. On top of that I
will work from home and thus have more time with my wife and my
friends.</li>
<li>The next news is that I'll become father in march. Even if the
changes will really come with the baby, some are already operating
to welcome him (or her).</li>
</ul>
<p>As a conclusion to my readers interested in Alfresco, I will completely
stop working on that product and thus I will stop writing tutorials on
it. I will focus on my OpenOffice.org related activities. These will
obviously include my existing projects like the Eclipse integration and
the COOoder extension.</p>A wonderful week in Québec2008-11-02T16:10:00+01:002008-11-02T16:10:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-11-02:/a-wonderful-week-in-quebec.html<p>This week I have travelled to Quebec for my work. I had time
to discover Québec city during the week-ends and was full of the
French-Canadian culture. If I have spent such a good time there, it
thanks to my clients and hosts: <a href="http://www.infoglobe.ca/">InfoGlobe (fr)</a>. I would like to
thank …</p><p>This week I have travelled to Quebec for my work. I had time
to discover Québec city during the week-ends and was full of the
French-Canadian culture. If I have spent such a good time there, it
thanks to my clients and hosts: <a href="http://www.infoglobe.ca/">InfoGlobe (fr)</a>. I would like to
thank again David Tremblay and Sam Chau who helped me discover their
city and culture, but I don't forget the others.</p>
<p>This is definitely a place to return with my wife...</p>Unit tests for OOo extensions2008-10-02T15:15:00+02:002008-10-02T15:15:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-10-02:/unit-tests-for-ooo-extensions.html<p>I have explained <a href="https://bosdonnat.fr/test-coverage-for-ooo-extensions.html">in one of my last posts</a> how to measure
the coverage of the test of a Java OpenOffice.org extension. These
white-box tests are generally not enough to ensure the quality of a
development. XUnit tests are often used by developers to automate the
tests. What about …</p><p>I have explained <a href="https://bosdonnat.fr/test-coverage-for-ooo-extensions.html">in one of my last posts</a> how to measure
the coverage of the test of a Java OpenOffice.org extension. These
white-box tests are generally not enough to ensure the quality of a
development. XUnit tests are often used by developers to automate the
tests. What about unit tests for an OpenOffice.org extension? Is there
any way to automate the tests of a Java extension for OpenOffice.org? To
improve the quality of the COOoder extension, I wanted to create some
unit tests. I will present here some basic classes to use to create easy
tests.</p>
<h3>Theoretically...</h3>
<p>Before presenting any code snippet, I need to explain the general
principle of the unit tests for OpenOffice.org. The key concept of the
following is that OpenOffice.org can be launched and controlled by a
remote program. A JUnit test is a normal Java program and the idea is to
make it bootstrap OOo, connect to it and execute the tests. Here is a
small sequence diagram of what happens:</p>
<p><img alt="Sequence diagram" src="/images/ooo/unittest_1.png" title="Sequence diagram"></p>
<p>OpenOffice.org is bootstrapped once at the beginning by the test suite
and stopped when all tests are run (this part has been forgotten on the
diagram). The remote OpenOffice.org context is transmitted to all the
test cases which can use it to set the fixture up, run the test and tear
the fixture down.</p>
<h3>...and practically</h3>
<p>To implement all this nice feature, I have created some base classes for
the tests cases and suites. They both inherits from the JUnit
corresponding classes. The classes are in the
<code>org.openoffice.coooder.test.base</code> package in the ooo-build project:</p>
<ul>
<li><code>Bootstrap</code>: the OpenOffice.org <code>Bootstrap</code> class modified to easily
bootstrap the office</li>
<li><code>UnoTestSuite</code>: the test suite to use to run all the unit tests for
OpenOffice.org</li>
<li><code>UnoTestCase</code>: the OpenOffice.org context-aware test case. This
abstract class has to be the base of all the unit tests for
OpenOffice.org Java extensions.</li>
</ul>
<p>To correctly bootstrap the office, the <code>program</code> folder of the
OpenOffice.org installation has to be added to the<code>LD_LIBRARY_PATH</code>
variable (<code>PATH</code> on windows and <code>DYLIB_LIBRARY_PATH</code> on MacOS). This
folder has to be passed as a property to the JUnit launcher using the
following JVM parameter:</p>
<div class="highlight"><pre><span></span><code><span class="err">-Dopenoffice.program.path=/usr/lib/openoffice/program</span>
</code></pre></div>
<p>Now there is only to write the tests. Here is an example of test suite
and a test case:</p>
<div class="highlight"><pre><span></span><code><span class="cm">/**</span>
<span class="cm"> * The test case class with two tests</span>
<span class="cm"> */</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">DummyTest</span> <span class="kd">extends</span> <span class="n">UnoTestCase</span> <span class="p">{</span>
<span class="kd">private</span> <span class="n">XTextDocument</span> <span class="n">mTestDoc</span><span class="p">;</span>
<span class="kd">public</span> <span class="nf">DummyTest</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">super</span><span class="p">();</span>
<span class="p">}</span>
<span class="kd">public</span> <span class="nf">DummyTest</span><span class="p">(</span><span class="n">String</span> <span class="n">pName</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">super</span><span class="p">(</span><span class="n">pName</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Fixture setup: creates an empty writer document</span>
<span class="cm"> */</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">setUp</span><span class="p">()</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="p">{</span>
<span class="n">mTestDoc</span> <span class="o">=</span> <span class="n">loadDocument</span><span class="p">(</span><span class="s">"private:factory/swriter"</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * Fixture tear down: closes the document without saving</span>
<span class="cm"> */</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="nf">tearDown</span><span class="p">()</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="p">{</span>
<span class="n">XCloseable</span> <span class="n">xCloseable</span> <span class="o">=</span> <span class="p">(</span><span class="n">XCloseable</span><span class="p">)</span><span class="n">UnoRuntime</span><span class="p">.</span><span class="na">queryInterface</span><span class="p">(</span>
<span class="n">XCloseable</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="n">mTestDoc</span><span class="p">);</span>
<span class="n">xCloseable</span><span class="p">.</span><span class="na">close</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * One correct test</span>
<span class="cm"> */</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testHello</span><span class="p">()</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">String</span> <span class="n">hello</span> <span class="o">=</span> <span class="s">"Hello world!"</span><span class="p">;</span>
<span class="n">mTestDoc</span><span class="p">.</span><span class="na">getText</span><span class="p">().</span><span class="na">setString</span><span class="p">(</span><span class="n">hello</span><span class="p">);</span>
<span class="n">assertEquals</span><span class="p">(</span><span class="n">hello</span><span class="p">,</span> <span class="n">mTestDoc</span><span class="p">.</span><span class="na">getText</span><span class="p">().</span><span class="na">getString</span><span class="p">());</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fail</span><span class="p">(</span><span class="s">"Shouldn't have thrown an exception"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * One failing test</span>
<span class="cm"> */</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testFailure</span><span class="p">()</span> <span class="p">{</span>
<span class="n">fail</span><span class="p">(</span><span class="s">"test will fail here"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="n">XTextDocument</span> <span class="nf">loadDocument</span><span class="p">(</span><span class="n">String</span> <span class="n">pUrl</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="p">{</span>
<span class="n">XMultiComponentFactory</span> <span class="n">xMngr</span> <span class="o">=</span> <span class="n">getContext</span><span class="p">().</span><span class="na">getServiceManager</span><span class="p">();</span>
<span class="n">Object</span> <span class="n">oDesktop</span> <span class="o">=</span> <span class="n">xMngr</span><span class="p">.</span><span class="na">createInstanceWithContext</span><span class="p">(</span><span class="s">"com.sun.star.frame.Desktop"</span><span class="p">,</span> <span class="n">getContext</span><span class="p">());</span>
<span class="n">XComponentLoader</span> <span class="n">xLoader</span> <span class="o">=</span> <span class="p">(</span><span class="n">XComponentLoader</span><span class="p">)</span><span class="n">UnoRuntime</span><span class="p">.</span><span class="na">queryInterface</span><span class="p">(</span>
<span class="n">XComponentLoader</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="n">oDesktop</span><span class="p">);</span>
<span class="n">XComponent</span> <span class="n">xDoc</span> <span class="o">=</span> <span class="n">xLoader</span><span class="p">.</span><span class="na">loadComponentFromURL</span><span class="p">(</span><span class="n">pUrl</span><span class="p">,</span> <span class="s">"_default"</span><span class="p">,</span>
<span class="n">FrameSearchFlag</span><span class="p">.</span><span class="na">ALL</span><span class="p">,</span> <span class="k">new</span> <span class="n">PropertyValue</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">);</span>
<span class="n">XTextDocument</span> <span class="n">xTextDoc</span> <span class="o">=</span> <span class="p">(</span><span class="n">XTextDocument</span><span class="p">)</span><span class="n">UnoRuntime</span><span class="p">.</span><span class="na">queryInterface</span><span class="p">(</span><span class="n">XTextDocument</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="n">xDoc</span><span class="p">);</span>
<span class="k">return</span> <span class="n">xTextDoc</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="cm">/**</span>
<span class="cm"> * The test suite class.</span>
<span class="cm"> */</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">AllTests</span> <span class="p">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">Test</span> <span class="nf">suite</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// The tests to run by the suite</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">testClasses</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span> <span class="p">{</span>
<span class="n">DummyTest</span><span class="p">.</span><span class="na">class</span>
<span class="p">};</span>
<span class="c1">// Create the test suite</span>
<span class="n">UnoTestSuite</span> <span class="n">suite</span> <span class="o">=</span> <span class="k">new</span> <span class="n">UnoTestSuite</span><span class="p">(</span><span class="n">testClasses</span><span class="p">);</span>
<span class="k">return</span> <span class="n">suite</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>OpenOffice.org codeswarm2008-09-29T17:11:00+02:002008-09-29T17:11:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-29:/openofficeorg-codeswarm.html<p>You may have already heard of <a href="http://vis.cs.ucdavis.edu/~ogawa/codeswarm/">codeswarm</a>. This small
project, helps you to create a video from the commits logs of project.
Some open source projects have their codeswarm, but not OpenOffice.org.
At the beginning I wanted to have a codeswarm of both OOo and ooo-build,
but the OOo …</p><p>You may have already heard of <a href="http://vis.cs.ucdavis.edu/~ogawa/codeswarm/">codeswarm</a>. This small
project, helps you to create a video from the commits logs of project.
Some open source projects have their codeswarm, but not OpenOffice.org.
At the beginning I wanted to have a codeswarm of both OOo and ooo-build,
but the OOo CVS logs are too huge for my computer to run codeswarm on
them.</p>
<p>However, I managed to get the codeswarm for ooo-build project. These
kind of videos are much more interesting when you know the people
committing:</p>
<iframe src="http://player.vimeo.com/video/1840832" width="400" height="300" frameborder="0"></iframe>
<p><a href="http://vimeo.com/1840832?pg=embed&sec=1840832">ooo-build codeswarm</a> from <a href="http://vimeo.com/user792889?pg=embed&sec=1840832">Cédric Bosdonnat</a> on
<a href="http://vimeo.com?pg=embed&sec=1840832">Vimeo</a></p>Test coverage for OOo Extensions2008-09-23T09:54:00+02:002008-09-23T09:54:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-23:/test-coverage-for-ooo-extensions.html<p>Testing code is always one the most important part in the
development process. Testing OpenOffice.org extensions cannot be often
automated, but it would be interesting to know whether the tests are
enough or not. Having some code coverage informations for the tests can
be really useful.</p>
<p>This post explains …</p><p>Testing code is always one the most important part in the
development process. Testing OpenOffice.org extensions cannot be often
automated, but it would be interesting to know whether the tests are
enough or not. Having some code coverage informations for the tests can
be really useful.</p>
<p>This post explains how to measure the code coverage of a Java extension
for OpenOffice.org. There are some traps in the path leading to the data
and you should read the complete article to avoid them.</p>Some C/C++ discoveries2008-09-17T13:29:00+02:002008-09-17T13:29:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-17:/some-cc-discoveries.html<p>As you might know, I'm used to code in Java in Eclipse. As many other
modern IDE users, I'm not really used to code using a text editor.
Yesterday evening, in my hotel room, I was idling among the
OpenOffice.org sources and I was really impressed by what can …</p><p>As you might know, I'm used to code in Java in Eclipse. As many other
modern IDE users, I'm not really used to code using a text editor.
Yesterday evening, in my hotel room, I was idling among the
OpenOffice.org sources and I was really impressed by what can be done
with <code>Vim</code> and <code>ctags</code>.</p>
<h3>Building the tags file</h3>
<p>I have installed <code>ctags-exuberant</code> and here is the command
line that I have used to build my tags file:</p>
<div class="highlight"><pre><span></span><code>ctags --recurse<span class="o">=</span>yes --languages<span class="o">=</span>C,C++,Java,Python --totals<span class="o">=</span>yes --fields<span class="o">=</span>fksiSm --exclude<span class="o">=</span>unxlngi6<span class="se">\.</span>pro
</code></pre></div>
<p>The surprise for me was the time it takes for <code>ctags</code> to build
the tags file for the whole OpenOffice sources. Here are the output
statistics:</p>
<div class="highlight"><pre><span></span><code><span class="err">31490 files, 10738178 lines (352871 kB) scanned in 35.8 seconds (9865 kB/s)</span>
<span class="err">772019 tags added to tag file</span>
<span class="err">772019 tags sorted in 0.00 seconds</span>
</code></pre></div>
<h3>Using the tags in Vim</h3>
<p>After this really good surprise I really wanted to try this discovery.
Thus I opened Vim and read the help on the tags features. Here are some
of the interesting commands:</p>
<ul>
<li><strong>:ta \<ident></strong> shows all the places where the identifier
pattern matches</li>
<li><strong>Ctrl + ]</strong> opens the definition of the identifier under the cursor</li>
<li><strong>Ctrl + T</strong> comes back in the tag navigation history</li>
</ul>
<p>Using these commands I have finally found out what is the <code>SAL_CALL</code>
macro... this is nothing for most of the platforms but has its importance
for MSC (<a href="http://msdn.microsoft.com/en-us/library/zkwh89ks(VS.80).aspx">__cdecl</a>). Using these commands I don't need to remember where
exactly a type is defined or or implemented: Vim is remembering it for
me!</p>OOo integration tips (2)2008-09-17T13:19:00+02:002008-09-17T13:19:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-17:/ooo-integration-tips-2.html<p>Here is a new instance of the
OpenOffice.org Eclipse integration tips. I hope you will enjoy
it.</p>
<h3>Tip #3: Creating a valid OXT extension</h3>
<p>The OpenOffice.org Eclipse integration is starting to be out-dated and
doesn't support the OXT extensions by default. This tip explains how to
create an …</p><p>Here is a new instance of the
OpenOffice.org Eclipse integration tips. I hope you will enjoy
it.</p>
<h3>Tip #3: Creating a valid OXT extension</h3>
<p>The OpenOffice.org Eclipse integration is starting to be out-dated and
doesn't support the OXT extensions by default. This tip explains how to
create an OXT package using the Eclipse plugin.</p>
<p>The package to build is configured by the <code>package.properties</code> file.
When editing this project configuration file, the shown editor is composed
of three sections:</p>
<ul>
<li>
<p>the <strong>Package content</strong> section: used to select which files should
be included in the extension</p>
</li>
<li>
<p>the <strong>Basic and dialog libraries</strong> section: used to add folders
containing OOo-Basic libraries to the extension</p>
</li>
<li>
<p>the <strong>Package descriptions</strong> section: used to select text files
containing a short description of the package.</p>
</li>
</ul>
<p>An OXT extension contains a <code>description.xml</code> file description the
package, its license, its update site, its version, its dependencies...
An OpenOffice.org extension is also generally containing an
<code>Addons.xcu</code> file describing the different
menus and toolbars to add to the OpenOffice.org user interface.</p>
<p>Even if there is no wizard in the Eclipse integration
to easily produce these files, they can be hand-written and added to the
package. In order to do this, add them to the root of the project and
select them in the <code>package.properties</code> file editor. This tip will not
explain how to create the <code>Addons.xcu</code> and <code>description.xml</code> files:
this is well described in the OpenOffice.org documentation.</p>
<ul>
<li>
<p><a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/AddOns/Configuration">Addons.xcu in the developer's guide</a> </p>
</li>
<li>
<p><a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Extensions/description.xml">description.xml in the developer's guide</a></p>
</li>
<li>
<p><a href="http://wiki.services.openoffice.org/wiki/Extensions_Packager#BasicAddonBuilder">BasicAddonBuilder on the wiki</a> </p>
</li>
</ul>
<p>The extension descriptions files are shown when the mouse is over the
package in the extensions manager.</p>
<p>To create the package, simply select a file of the project, run the
Eclipse export wizard and choose the <strong>OpenOffice.org package</strong> wizard
in the <strong>UNO</strong> category. In the next step, select <strong>2.0.4</strong> as the
minimum version of OpenOffice.org: this will generate an OXT file.</p>
<p>If you have defined a license file for your extension, do not click on
<strong>Yes</strong> when the wizard asks you whether to deploy the extension in
OpenOffice.org or not: Eclipse would be waiting indefinitely for a
license validation which is not handled by the OpenOffice.org
integration.</p>A better COOoder is here2008-09-12T12:56:00+02:002008-09-12T12:56:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-12:/a-better-coooder-is-here.html<p>This new version of the syntax highlighting extension for
OpenOffice.org brings the announced features. Many thanks for those who
brought their improvement ideas.</p>
<ul>
<li>The language definition files are written on one line: 40% of time
is thus gained during the definition file reading.</li>
<li>The regular expressions used to find …</li></ul><p>This new version of the syntax highlighting extension for
OpenOffice.org brings the announced features. Many thanks for those who
brought their improvement ideas.</p>
<ul>
<li>The language definition files are written on one line: 40% of time
is thus gained during the definition file reading.</li>
<li>The regular expressions used to find the keywords are compiled and
stored in a regexp cache: this gains only 3% of time on the snippet
highlighting... but it's already interesting on huge snippets.</li>
<li>A progress bar is now showing the highlighting progress.</li>
<li>The languages names are sorted in the listbox... but their display
name is still not shown.</li>
<li>A fix for problems with keywords starting with the character <strong>?</strong>.</li>
</ul>
<p>The update site is not ready and the updated sources will be soon
available on the Gnome SVN in the ooo-build project.</p>
<p><a href="https://bosdonnat.fr/data/COOoder.oxt">COOoder.oxt</a></p>
<p><strong>EDIT</strong> The sources can be browsed on <a href="https://github.com/cbosdo/coooder">GitHub</a></p>OOo integration tips2008-09-07T16:41:00+02:002008-09-07T16:41:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-09-07:/ooo-integration-tips.html<p>Even if I'm not maintaining it for the moment, I'm still using
the Eclipse integration of OpenOffice.org and would be glad to share
some tips with you. Here are the two first tips. Stay tuned because
there may be others...</p>
<h3>Tip #1</h3>
<p>I recently decided to switch back to …</p><p>Even if I'm not maintaining it for the moment, I'm still using
the Eclipse integration of OpenOffice.org and would be glad to share
some tips with you. Here are the two first tips. Stay tuned because
there may be others...</p>
<h3>Tip #1</h3>
<p>I recently decided to switch back to the default packages of
OpenOffice.org on Ubuntu. However, I had to find a way to use the
Eclipse integration with it. Here is how to do it.</p>
<ol>
<li>Install OpenOffice.org and its SDK packages. The
<em>openoffice.org-java-common</em> and <em>openoffice.org-dev</em> packages are
needed. Installing the <em>openoffice.org-dev-doc</em> package is also a
good idea to have the IDL reference on your machine.</li>
<li>Open your Eclipse workspace and go to the <strong>OpenOffice.org plugin >
SDK configuration</strong> page. Add a new OpenOffice.org instance with the
path: <em>/usr/lib/openoffice</em>. Add a new SDK instance with the path
<em>/usr/lib/openoffice/sdk</em>.</li>
</ol>
<p>Now the OOo Eclipse integration can be used normally.</p>
<h3>Tip #2</h3>
<p>Often when starting a new project, I miss some methods or attributes in
the main type. Adding a new type is often needed. Even if there is no
wizard to refactor the IDL specifications yet, there is a way to handle
the problem.</p>
<p>The first thing is to have some basic knowledge of the UNO-IDL language.
Here are some links to get started:</p>
<ul>
<li><a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/ProUNO/API_Concepts">Understanding the different types</a></li>
<li><a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_the_Specification">UNO-IDL documentation on the developer's guide wiki</a></li>
<li><a href="http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/AppendixD/UNOIDL_Syntax_Specification">The UNO-IDL grammar</a></li>
</ul>
<p>Let us suppose that you have a defined service and interface but you
need to add a <em>checkYear()</em> method. Then you will edit the corresponding
interface and add the following definition to the existing members:</p>
<div class="highlight"><pre><span></span><code><span class="k">boolean</span><span class="w"> </span><span class="n">checkYear</span><span class="p">(</span><span class="o">[</span><span class="n">in</span><span class="o">]</span><span class="w"> </span><span class="n">long</span><span class="w"> </span><span class="k">value</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>The member is added to the interface because there should be nothing
else than constructors in the service definition (See the documentation
on <a href="http://udk.openoffice.org/common/man/draft/multinherit.html">new style services</a>).</p>
<p>Save the modified <em>idl</em> file, it should be re-compiled. Then an error
should appear on the implementation class explaining that there is a
missing method. Use the <strong>Ctrl+1</strong> shortcut on the error to quickfix it
and have the new method. After this, the only thing to do is to add the
method body.</p>
<p>If you need to add a new service or interface, then you should better
use the provided UNO wizards. Select the UNO project where to add the
type and go to the <strong>File > New > Other...</strong> menu. Select the new
service or interface wizard in the UNO category and follow the
instructions. </p>GeSHi for OpenOffice.org2008-07-05T09:50:00+02:002008-07-05T09:50:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-07-05:/geshi-for-openofficeorg.html<p>As I have promised it in a later post, here is a first version
of the OpenOffice.org extension for syntax highlighting. There are still
some things to improve like:</p>
<ul>
<li>reading the languages files: this could certainly be optimized to
avoid parsing the language file at each parsing time.</li>
<li>generating …</li></ul><p>As I have promised it in a later post, here is a first version
of the OpenOffice.org extension for syntax highlighting. There are still
some things to improve like:</p>
<ul>
<li>reading the languages files: this could certainly be optimized to
avoid parsing the language file at each parsing time.</li>
<li>generating the languages files: add a parameter to remove the new
lines in the XML definitions of the language.</li>
<li>present the display names of the languages and sort them by
alphabetical order in the language selection dialog.</li>
<li>add some error dialogs for the user to understand problems.</li>
</ul>
<p>Do not hesitate to report any bug here if you find some.
<a href="https://bosdonnat.fr/data/COOoder.oxt">COOoder.oxt</a></p>
<p><strong>Edit 2008, 06/07:</strong><br>
<a href="https://github.com/cbosdo/coooder">Sources</a></p>Alfresco and groups of admins2008-06-26T11:42:00+02:002008-06-26T11:42:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-26:/alfresco-and-groups-of-admins.html<p>I had to add groups of users as administrators to the Alfresco
configuration. As this is a common requested feature, I will explain how
I did it. This will also be a good example of how to tweak Alfresco
internal classes by overriding its Spring beans. Before reading further,
you …</p><p>I had to add groups of users as administrators to the Alfresco
configuration. As this is a common requested feature, I will explain how
I did it. This will also be a good example of how to tweak Alfresco
internal classes by overriding its Spring beans. Before reading further,
you should have read the <a href="https://bosdonnat.fr/howto-create-a-new-alfresco-module.html">howto on Alfresco modules creation</a>.</p>
<p>In an <code>org.alfresco.sample</code> package in the <code>source/java</code> folder of the
module, add the following class. This class will subclass the default
Alfresco <code>AuthorityService</code> implementation to change only the
<code>setAdminUsers()</code> method defining the administrators from the Spring
configuration.</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyAuthorityService</span> <span class="kd">extends</span> <span class="n">AuthorityServiceImpl</span> <span class="p">{</span>
<span class="kd">private</span> <span class="n">TransactionService</span> <span class="n">transactionService</span><span class="p">;</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setAdminUsers</span><span class="p">(</span><span class="n">Set</span> <span class="n">pConfig</span><span class="p">)</span> <span class="p">{</span>
<span class="n">UserTransaction</span> <span class="n">txn</span> <span class="o">=</span> <span class="n">transactionService</span><span class="p">.</span><span class="na">getUserTransaction</span><span class="p">();</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">txn</span><span class="p">.</span><span class="na">begin</span><span class="p">();</span>
<span class="n">HashSet</span> <span class="n">users</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashSet</span><span class="p">();</span>
<span class="n">Iterator</span> <span class="n">iter</span> <span class="o">=</span> <span class="n">pConfig</span><span class="p">.</span><span class="na">iterator</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="n">iter</span><span class="p">.</span><span class="na">hasNext</span><span class="p">())</span> <span class="p">{</span>
<span class="n">String</span> <span class="n">authority</span> <span class="o">=</span> <span class="n">iter</span><span class="p">.</span><span class="na">next</span><span class="p">();</span>
<span class="n">AuthorityType</span> <span class="n">type</span> <span class="o">=</span> <span class="n">AuthorityType</span><span class="p">.</span><span class="na">getAuthorityType</span><span class="p">(</span><span class="n">authority</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">type</span><span class="p">.</span><span class="na">equals</span><span class="p">(</span><span class="n">AuthorityType</span><span class="p">.</span><span class="na">GROUP</span><span class="p">)</span> <span class="o">&&</span> <span class="n">authorityExists</span><span class="p">(</span><span class="n">authority</span><span class="p">))</span> <span class="p">{</span>
<span class="c1">// Get all the group's users</span>
<span class="n">Set</span> <span class="n">groupLogins</span> <span class="o">=</span> <span class="n">getContainedAuthorities</span><span class="p">(</span><span class="n">AuthorityType</span><span class="p">.</span><span class="na">USER</span><span class="p">,</span> <span class="n">authority</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="n">users</span><span class="p">.</span><span class="na">addAll</span><span class="p">(</span><span class="n">groupLogins</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">users</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">authority</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">super</span><span class="p">.</span><span class="na">setAdminUsers</span><span class="p">(</span><span class="n">users</span><span class="p">);</span>
<span class="n">txn</span><span class="p">.</span><span class="na">commit</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span> <span class="n">txn</span><span class="p">.</span><span class="na">rollback</span><span class="p">();</span> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e1</span><span class="p">)</span> <span class="p">{</span> <span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">setTransactionService</span><span class="p">(</span><span class="n">TransactionService</span> <span class="n">pTransactionService</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="na">transactionService</span> <span class="o">=</span> <span class="n">pTransactionService</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>Now that the implementation is changed, we need to tell Alfresco to use
it instead of the default one. For this, add the following bean
definition to the <code>module-context.xml</code> file. This Spring configuration
is a copy of the one in the <code>authority-service-context.xml</code> file with
some changes to use our own implementation. As our implementation needs
the transaction service, it has been added as a property to the bean
configuration.</p>
<div class="highlight"><pre><span></span><code><span class="nt"><bean</span> <span class="na">id=</span><span class="s">"authorityService"</span> <span class="na">class=</span><span class="s">"org.alfresco.sample.MyAuthorityService"</span><span class="nt">></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"authenticationComponent"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"authenticationComponent"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"personService"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"personService"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"nodeService"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"nodeService"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"authorityDAO"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"authorityDAO"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"permissionServiceSPI"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"permissionServiceImpl"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"transactionService"</span><span class="nt">></span>
<span class="nt"><ref</span> <span class="na">bean=</span><span class="s">"transactionService"</span> <span class="nt">/></span>
<span class="nt"></property></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"adminUsers"</span><span class="nt">></span>
<span class="nt"><set></span>
<span class="nt"><value></span>admin<span class="nt"></value></span>
<span class="nt"><value></span>GROUP_Administrators<span class="nt"></value></span>
<span class="nt"></set></span>
<span class="nt"></property></span>
<span class="nt"></bean></span>
</code></pre></div>
<p>It is now possible to set the full name of a groupe in the
administrators' list. In the example case, all the users of the
<strong>GROUP_Administrators</strong> group will be administrators of Alfresco. </p>Howto create a new Alfresco module2008-06-17T08:41:00+02:002008-06-17T08:41:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-17:/howto-create-a-new-alfresco-module.html<p>This post aims at explaining how to set up Eclipse to build a
new Alfresco module easily. Before continuing to read, be sure to have
downloaded Alfresco and its Software Development Kit (SDK). Of course
the following will assume that you have an installed Eclipse with the
J2EE plugins. This …</p><p>This post aims at explaining how to set up Eclipse to build a
new Alfresco module easily. Before continuing to read, be sure to have
downloaded Alfresco and its Software Development Kit (SDK). Of course
the following will assume that you have an installed Eclipse with the
J2EE plugins. This article will not explain all the technical details on
AMP files, for more informations on this topic, please refer to the
<a href="http://wiki.alfresco.com/wiki/AMP_Files">corresponding Alfresco Wiki page</a>.</p>
<p>This post will be composed of the following parts:</p>
<ol>
<li>Creating the project</li>
<li>Useful settings for Alfresco development</li>
</ol>
<p><strong>Creating the project</strong></p>
<p>First we need to create a common Java project in Eclipse. What will be
interesting here is only how to structure the project and build it
easily. The only tricky thing during the project creation is to remove
the default source folder and replace it by two <code>source/java</code> and
<code>config</code> folders. Don't forget to add the Alfresco embedded SDK project
as a dependency of the new project.</p>
<p>In the newly created project, create the following folders:</p>
<ul>
<li><code>source/web/jsp</code>: this folder is mapped to the <code>jsp</code> folder in the
Alfresco WAR</li>
<li><code>source/web/scripts</code>: this folder is mapped to the <code>scripts</code> folder
in the Alfresco WAR</li>
<li><code>source/web/images</code>: this folder is mapped to the <code>images</code> folder in
the Alfresco WAR</li>
<li><code>source/web/css</code>: this folder is mapped to the <code>css</code> folder in the
Alfresco WAR</li>
<li><code>lib</code>: this folder will contain all the third party dependencies to
include in the AMP file</li>
<li><code>WEB-INF</code>: this folder will be mapped to the <code>WEB-INF</code> folder of the
Alfresco WAR.</li>
</ul>
<p>Now that the useful folders are created, we need to create the mandatory
files of an Alfresco module package. Before continuing, please choose an
identifier for the module: this will be needed in the next steps. For
this tutorial I will named the module <code>sample</code>. The AMP file will need
to have a descriptor file. This one will be a <code>module.properties</code> file
created at the project's root. This file will need to contain the
following properties:</p>
<ul>
<li><code>module.id</code>: the chosen identifier for the module. In my case:
<code>sample</code></li>
<li><code>module.version</code>: the module version. Let's put <code>1.0</code> for a first
version, but don't forget to change it afterwards</li>
<li><code>module.title</code>: a displayable title for the module</li>
<li><code>module.description</code>: a longer description for the module</li>
<li><code>module.repo.version.min</code>: the minimum required version of Alfresco</li>
<li><code>module.repo.version.max</code>: the maximum possible version of Alfresco</li>
</ul>
<p>The module is almost ready, but there is still to add the
<code>module-context.xml</code> file. This one will have to be placed in a
<code>alfresco.module.<your_id></code> package. In the example case, the file will
need to be created in a <code>alfresco.module.sample</code> package in the <code>config</code>
folder. This file only needs to contain the following content:</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?xml version='1.0' encoding='UTF-8'?></span>
<span class="cp"><!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'></span>
<span class="nt"><beans></span>
<span class="nt"></beans></span>
</code></pre></div>
<p>All the spring configuration can go in the <code>beans</code> tag of this file.
However you can also place it in files ending with <code>-context.xml</code> in a
<code>alfresco.extension</code> package in the <code>source/java</code> folder. All the Java
classes to package in a JAR and deploy with the AMP have to be placed
somewhere inside the <code>source/java</code> folder.</p>
<p>To make Alfresco use the <code>WEB-INF</code> folder in the AMP file, you need to
add a new <code>file-mapping.properties</code> file at the project's root
containing the following line. <strong>Do not use the <code>WEB-INF</code> folder unless
you really know what you are doing!</strong></p>
<div class="highlight"><pre><span></span><code><span class="err">/WEB-INF = /WEB-INF</span>
</code></pre></div>
<p>Now that all the important parts of the project are created we need to
write an ANT build file to transform this into a valid AMP file. The ANT
build file will need to know the path where to find the Alfresco SDK:
this will need to be configured in a <code>build.properties</code> file. I won't
explain the details of the ANT build file as this is not an ANT
tutorial. However you will see that it is composed of the following
targets:</p>
<ul>
<li><code>clean</code>: cleans the build results</li>
<li><code>compile</code>: compile the Java code in the <code>source/java</code> folder and
copy the resources in the build output tree</li>
<li><code>package-jar</code>: package the results of the <code>compile</code> target into a
JAR file</li>
<li><code>package-amp</code>: package the JAR file, libraries, <code>WEB-INF</code>, <code>config</code>
folders and configuration files into an AMP file</li>
</ul>
<p>The ANT build file is a <code>build.xml</code> file at the project's root. This
file will contain the code shown by the following snippet. Of course it
can be changed to fit your needs, but don't forget to update the
project's structure if necessary.</p>
<div class="highlight"><pre><span></span><code><span class="cp"><?xml version="1.0"?></span>
<span class="nt"><project</span> <span class="na">name=</span><span class="s">"Sample Module"</span> <span class="na">default=</span><span class="s">"package-amp"</span> <span class="na">basedir=</span><span class="s">"."</span><span class="nt">></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"project.dir"</span> <span class="na">value=</span><span class="s">"."</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">file=</span><span class="s">"${project.dir}/build.properties"</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">file=</span><span class="s">"${project.dir}/module.properties"</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"build.dir"</span> <span class="na">value=</span><span class="s">"${project.dir}/build"</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"config.dir"</span> <span class="na">value=</span><span class="s">"${project.dir}/config"</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"jar.file"</span> <span class="na">value=</span><span class="s">"${build.dir}/lib/${module.id}.jar"</span><span class="nt">/></span>
<span class="nt"><property</span> <span class="na">name=</span><span class="s">"amp.file"</span> <span class="na">value=</span><span class="s">"${build.dir}/dist/${module.id}.amp"</span><span class="nt">/></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"mkdirs"</span><span class="nt">></span>
<span class="nt"><mkdir</span> <span class="na">dir=</span><span class="s">"${build.dir}/dist"</span> <span class="nt">/></span>
<span class="nt"><mkdir</span> <span class="na">dir=</span><span class="s">"${build.dir}/lib"</span> <span class="nt">/></span>
<span class="nt"><mkdir</span> <span class="na">dir=</span><span class="s">"${build.dir}/classes"</span> <span class="nt">/></span>
<span class="nt"></target></span>
<span class="nt"><path</span> <span class="na">id=</span><span class="s">"class.path"</span><span class="nt">></span>
<span class="nt"><dirset</span> <span class="na">dir=</span><span class="s">"${build.dir}"</span> <span class="nt">/></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${project.dir}/lib"</span> <span class="na">includes=</span><span class="s">"**/*.jar"</span> <span class="nt">/></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${alfresco.sdk.dir}/lib/server"</span> <span class="na">includes=</span><span class="s">"**/*.jar"</span> <span class="nt">/></span>
<span class="nt"></path></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"clean"</span><span class="nt">></span>
<span class="nt"><delete</span> <span class="na">dir=</span><span class="s">"${build.dir}"</span> <span class="nt">/></span>
<span class="nt"></target></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"compile"</span> <span class="na">depends=</span><span class="s">"mkdirs"</span><span class="nt">></span>
<span class="nt"><javac</span> <span class="na">classpathref=</span><span class="s">"class.path"</span> <span class="na">debug=</span><span class="s">"${debug}"</span> <span class="na">srcdir=</span><span class="s">"${project.dir}/source/java"</span>
<span class="na">destdir=</span><span class="s">"${build.dir}/classes"</span> <span class="na">target=</span><span class="s">"1.5"</span> <span class="na">encoding=</span><span class="s">"UTF-8"</span><span class="nt">/></span>
<span class="nt"><copy</span> <span class="na">todir=</span><span class="s">"${build.dir}/classes"</span><span class="nt">></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${project.dir}/source/java"</span> <span class="na">defaultexcludes=</span><span class="s">"false"</span><span class="nt">></span>
<span class="nt"><exclude</span> <span class="na">name=</span><span class="s">"**/*.java"</span><span class="nt">/></span>
<span class="nt"><exclude</span> <span class="na">name=</span><span class="s">"**/.svn/**"</span><span class="nt">/></span>
<span class="nt"><exclude</span> <span class="na">name=</span><span class="s">"**/CVS/**"</span><span class="nt">/></span>
<span class="nt"></fileset></span>
<span class="nt"></copy></span>
<span class="nt"></target></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"package-jar"</span> <span class="na">depends=</span><span class="s">"compile"</span><span class="nt">></span>
<span class="nt"><jar</span> <span class="na">destfile=</span><span class="s">"${jar.file}"</span> <span class="na">encoding=</span><span class="s">"UTF-8"</span><span class="nt">></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${build.dir}/classes"</span> <span class="na">excludes=</span><span class="s">"**/custom*,**/*Test*"</span> <span class="na">defaultexcludes=</span><span class="s">"false"</span> <span class="nt">/></span>
<span class="nt"></jar></span>
<span class="nt"></target></span>
<span class="nt"><target</span> <span class="na">name=</span><span class="s">"package-amp"</span> <span class="na">depends=</span><span class="s">"package-jar"</span> <span class="na">description=</span><span class="s">"Package the Module"</span> <span class="nt">></span>
<span class="nt"><zip</span> <span class="na">destfile=</span><span class="s">"${amp.file}"</span> <span class="na">encoding=</span><span class="s">"UTF-8"</span><span class="nt">></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${project.dir}/build"</span> <span class="na">includes=</span><span class="s">"lib/*.jar"</span> <span class="nt">/></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${project.dir}"</span> <span class="na">includes=</span><span class="s">"config/**/*.*"</span> <span class="na">excludes=</span><span class="s">"**/module.properties"</span> <span class="nt">/></span>
<span class="nt"><fileset</span> <span class="na">dir=</span><span class="s">"${project.dir}"</span><span class="nt">></span>
<span class="nt"><include</span> <span class="na">name=</span><span class="s">"module.properties"</span><span class="nt">/></span>
<span class="nt"><include</span> <span class="na">name=</span><span class="s">"file-mapping.properties"</span> <span class="nt">/></span>
<span class="nt"><include</span> <span class="na">name=</span><span class="s">"WEB-INF/**/*"</span> <span class="nt">/></span>
<span class="nt"><include</span> <span class="na">name=</span><span class="s">"lib/**/*"</span> <span class="nt">/></span>
<span class="nt"><exclude</span> <span class="na">name=</span><span class="s">"WEB-INF/alfresco.tld"</span><span class="nt">/></span>
<span class="nt"><exclude</span> <span class="na">name=</span><span class="s">"WEB-INF/repo.tld"</span><span class="nt">/></span>
<span class="nt"></fileset></span>
<span class="nt"><zipfileset</span> <span class="na">dir=</span><span class="s">"source/web"</span> <span class="na">prefix=</span><span class="s">"web"</span><span class="nt">/></span>
<span class="nt"></zip></span>
<span class="nt"></target></span>
<span class="nt"></project></span>
</code></pre></div>
<p>The ANT build file will try to find some configuration in a
<code>build.properties</code> file. This file will have to be created under the
project's root and have to contain the following properties:</p>
<ul>
<li><code>alfresco.sdk.dir</code>: the absolute path to the Alfresco SDK to build
the module for.</li>
<li><code>debug</code>: <code>true</code> if the module should be build with the debugging
symbols. This property is not mandatory.</li>
</ul>
<p><strong>Useful settings for Alfresco development<br>
</strong></p>
<p>Now that the module is ready for development, here are some Eclipse
tricks to ease the Alfresco developement.</p>
<ul>
<li>Copy the
<code>tomcat/webapps/alfresco/WEB-INF/classes/alfresco/model/modelSchema.xsd</code>
into the SDK folder and add it to the Eclipse XML Catalog in <em>Window
> Preferences</em>. This schema doesn't cover the constraints in
Alfresco model definitions, but it saves a lot of time fixing dummy
syntax errors or typos.</li>
<li>You can do the same with the
<code>tomcat/webapps/alfresco/WEB-INF/classes/alfresco/auditSchema.xsd</code>
file.</li>
<li>Copy the <code>alfresco.tld</code> and <code>repo.tld</code> files into the <code>WEB-INF</code>
folder of your project. This will provide auto-completion for the
Alfresco tags when writing your JSP pages.</li>
<li>Install the Eclipse plugin for FreeMarker support: it helps a lot to
write template and webscripts.</li>
</ul>
<p>With the created module project and some Eclipse configuration, you are
now ready for Alfresco extensions development. You can still improve the
ANT build file by adding some target to auto-deploy your changes...
Don't forget to have a look at the post explaining <a href="https://bosdonnat.fr/debugging-an-alfresco-extension.html">how to debug an
Alfresco extension</a>: this can save a lot of time too during your
module development.</p>OOo for coders (2)2008-06-13T08:59:00+02:002008-06-13T08:59:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-13:/ooo-for-coders-2.html<p>Some times ago I have written a post about an OpenOffice.org
extension to present code snippets in <a href="https://bosdonnat.fr/ooo-for-coders.html">OOo with syntax highlighting</a>.
You may thing that this project is forgotten... but I'm writing here to
tell the contrary: I'm coding it when I have some time between work and
social …</p><p>Some times ago I have written a post about an OpenOffice.org
extension to present code snippets in <a href="https://bosdonnat.fr/ooo-for-coders.html">OOo with syntax highlighting</a>.
You may thing that this project is forgotten... but I'm writing here to
tell the contrary: I'm coding it when I have some time between work and
social life, that is to say slowly.</p>
<p>The GeSHi engine is now almost completely ported to OpenOffice.org: I
only need to add the support for the case insensitivity. However I'm not
providing anthing yet because there are a few things that are still
missing:</p>
<ul>
<li>Proper language definition files in XML support. The current tests
are done with a code snippet mixing several languages with a hard
coded language definition. The next step is to define an XML schema
for the language definition files and make the language service read
it.</li>
<li>A tool converting the GeSHi configuration files into the XML
language definition files.</li>
<li>The automated creation of the styles from the language definition
during thhe syntax highlighting. The styles are currently used but
manually defined.</li>
<li>A GUI to apply the syntax highlighting.</li>
</ul>
<p>I will provide some dev snapshot of the extension when it will be usable
even if you have to configure some things manually. However I can't
promise any date... this will completely depend on my available time and
mood. Stay tuned...</p>Some stats2008-06-10T21:00:00+02:002008-06-10T21:00:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-10:/some-stats.html<p>The Wordpress statistic plugin provides me some interesting
informations on what you are doing on my blog. As these may be of
interest for you too, here are some comments on them.</p>
<p>Firs of all, the top visiting day on this blog as been set a few days
ago: the …</p><p>The Wordpress statistic plugin provides me some interesting
informations on what you are doing on my blog. As these may be of
interest for you too, here are some comments on them.</p>
<p>Firs of all, the top visiting day on this blog as been set a few days
ago: the best score is now 124 visits for the day. But what it more
interesting is what kind of article you are reading.</p>
<p>Thanks to Wordpress stats plugins and OpenOffice.org I have produced the
following chart showing what category of article have been mostly read
during the last 30 days.</p>
<p><img alt="Categories for the last 30 days" src="https://bosdonnat.fr/data/stats_2008_05.jpg"></p>
<p>At first sight it seems that OpenOffice.org articles are the most read
ones. However Alfresco articles seems to be more and more interesting to
you as they are already 30% of the visits after only 3 months of posts.
The top 10 articles can also show what is interesting you more
precisely.</p>
<table>
<thead>
<tr>
<th>Post title</th>
<th>Visits</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://bosdonnat.fr/pages/libreoffice-eclipse.html">OpenOffice.org & Eclipse</a></td>
<td>251</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/using-webscripts-to-extend-alfresco-web-client.html">Using webscripts to extend Alfresco Web</a></td>
<td>101</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/getting-an-ooo-cws.html">Getting an OOo CWS</a></td>
<td>44</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/generating-uml-diagrams-from-java-code.html">Generating UML diagrams from Java code</a></td>
<td>40</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/pages/le-mariage-chretien.html">Marriage as a Christian (fr)</a></td>
<td>34</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/whos-using-my-alfresco.html">Who's using my Alfresco?</a></td>
<td>32</td>
</tr>
<tr>
<td>Albums (dropped)</td>
<td>31</td>
</tr>
<tr>
<td>o.r.i.g.i.n.a.l. plugin for wordpress (dropped)</td>
<td>30</td>
</tr>
<tr>
<td><a href="https://bosdonnat.fr/toggle-alfresco-in-a-read-only-mode.html">uno-skeletonmaker and multiple services</a></td>
<td>24</td>
</tr>
<tr>
<td>[Toggle Alfresco in a read-only mode][8]</td>
<td>19</td>
</tr>
</tbody>
</table>
<p>The good news here are that the Eclipse integration page is the most
visited page: it makes me hope that their are some people using it. This
is quite comforting to know that this work might not be completely lost
in the abyss of the forgotten projects.</p>
<p>The next good news is that Alfresco Webscripts sounds interesting. I'll
try to post a little bit more on what I'm doing with them and what you
could do. As I already mentionned it above, Alfresco topic seems really
hot, because 3 recent Alfresco posts are already in the top ten...</p>
<p>Last but not least, the great surprise to me is the number of persons
visiting my page on the christian wedding. I didn't even expect it to be
read by other people than friends... this is really good to see that
there are still persons considering this way of life. Should I translate
this page in english? As I didn't want to do it at the beginning, leave
me some comments if you would like to see it translated. Of course, you
may offer your help to translate it too!</p>Debugging an Alfresco extension2008-06-10T08:45:00+02:002008-06-10T08:45:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-10:/debugging-an-alfresco-extension.html<p>You may remember that I have written a post on <a href="https://bosdonnat.fr/debugging-an-ooo-extension-with-eclipse.html">how to debug
an OpenOffice.org extension</a>. This post is about to explain how to do
the same for an Alfresco extension. In fact the principle is the same.
To set Alfresco in a debug mode, edit the <code>tomcat/bin …</code></p><p>You may remember that I have written a post on <a href="https://bosdonnat.fr/debugging-an-ooo-extension-with-eclipse.html">how to debug
an OpenOffice.org extension</a>. This post is about to explain how to do
the same for an Alfresco extension. In fact the principle is the same.
To set Alfresco in a debug mode, edit the <code>tomcat/bin/startup.sh</code> file
and change the last line into:</p>
<div class="highlight"><pre><span></span><code><span class="nb">exec</span> <span class="s2">"</span><span class="nv">$PRGDIR</span><span class="s2">"</span>/<span class="s2">"</span><span class="nv">$EXECUTABLE</span><span class="s2">"</span> jpda start <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span>
</code></pre></div>
<p>The next time Alfresco is started it will be listening on the 8000 port.
Then you will be able to set up the Eclipse debugging session in the
same way than the one I described in the post on OOo extension
debugging.</p>
<p>To avoid lengthy Alfresco restarts when you change some code, you can
unset the automatic build, and use the <strong>Project > Build All</strong> menu for
a hot replace of code. This doesn't work when you have changed the
signature of a method or of a class. There are some cases where it
doesn't work... but I still haven't identified why it sometimes fails. I
only have noticed that you shouldn't change code when the debug session
isn't running or when you are stepping in the code.</p>Removing My Alfresco2008-06-09T16:24:00+02:002008-06-09T16:24:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-09:/removing-my-alfresco.html<p>I needed to remove the <strong>My Alfresco</strong> part in Alfresco
Navigator. This is a piece of JSF hack that I'll share here. The way it
is done here isn't the way it should be done in order to properly
package it... but it's a hack.</p>
<p>Copy the source code of …</p><p>I needed to remove the <strong>My Alfresco</strong> part in Alfresco
Navigator. This is a piece of JSF hack that I'll share here. The way it
is done here isn't the way it should be done in order to properly
package it... but it's a hack.</p>
<p>Copy the source code of the
<code>org.alfresco.web.ui.repo.component.UINavigator</code> class and remove the
following blocks:</p>
<div class="highlight"><pre><span></span><code><span class="k">else</span>
<span class="p">{</span>
<span class="n">treePanel</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="n">areaTitle</span> <span class="o">=</span> <span class="n">Application</span><span class="p">.</span><span class="na">getMessage</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">NavigationBean</span><span class="p">.</span><span class="na">MSG_MYALFRESCO</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>and</p>
<div class="highlight"><pre><span></span><code><span class="k">if</span> <span class="p">(</span><span class="n">NavigationBean</span><span class="p">.</span><span class="na">LOCATION_MYALFRESCO</span><span class="p">.</span><span class="na">equals</span><span class="p">(</span><span class="n">area</span><span class="p">)</span> <span class="o">==</span> <span class="kc">false</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">encodeSidebarButton</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">out</span><span class="p">,</span> <span class="n">sideBarStyle</span><span class="p">,</span>
<span class="n">NavigationBean</span><span class="p">.</span><span class="na">LOCATION_MYALFRESCO</span><span class="p">,</span>
<span class="n">NavigationBean</span><span class="p">.</span><span class="na">MSG_MYALFRESCO</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>Compile the Java class and put the result into a JAR file. Then place
the jar file into the <code>WEB-INF/lib</code> folder and restart Alfresco.</p>
<p>Of course you should also remove the tag corresponding to <strong>My
Alfresco</strong> in the <code>jsp/parts/titlebar.jsp</code> page to remove the link from
the page.</p>Alfresco Database schema2008-06-05T08:32:00+02:002008-06-05T08:32:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-05:/alfresco-database-schema.html<p>I'm often looking for some precise informations in Alfresco
database. This is quite hard when you don't have a graph showing the
database schema.</p>
<p>I have recently discovered that <a href="http://squirrel-sql.sourceforge.net">SQuirreL SQL</a> could help me in this
task. Select each table to show in the graph, right-clic and select
<strong>Add to …</strong></p><p>I'm often looking for some precise informations in Alfresco
database. This is quite hard when you don't have a graph showing the
database schema.</p>
<p>I have recently discovered that <a href="http://squirrel-sql.sourceforge.net">SQuirreL SQL</a> could help me in this
task. Select each table to show in the graph, right-clic and select
<strong>Add to graph</strong>. There is now only to reorganize the graph manually to
make it readable. The graph can be renamed and saved with the contextual
menu of the graph.</p>
<p>Here is a picture showing Alfresco database schema created using this
method.</p>
<p><a href="https://bosdonnat.fr/data/alfresco/schema_bd_alfresco.jpg"><img alt="Alfresco database schema" src="https://bosdonnat.fr/data/alfresco/preview_schema_bd_alfresco.jpg"></a></p>Toggle Alfresco in a read-only mode2008-06-04T18:35:00+02:002008-06-04T18:35:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-06-04:/toggle-alfresco-in-a-read-only-mode.html<p>Have you ever wondered how to keep Alfresco running while
backing it up? As you may have found it, Alfresco database and data
filesystem have to be saved in a coherent state. For this, Alfresco
should be turned off, or in a read-only mode. A read-only mode is also
useful …</p><p>Have you ever wondered how to keep Alfresco running while
backing it up? As you may have found it, Alfresco database and data
filesystem have to be saved in a coherent state. For this, Alfresco
should be turned off, or in a read-only mode. A read-only mode is also
useful for some maintainance operations.</p>
<p>On Alfresco 1.4, I could put it in a read-only mode by changing the
<code>transactions.properties</code> file and restarting Alfresco. This doesn't
work on Alfresco 2.1 as Alfresco tries to write some informations in the
system repositories during the bootstrap. Thus the only way to set it in
a read-only mode is to do it without stopping it, by interacting with
the <code>TransactionService</code>. This post is about to explain how to create a
webscript to toggle Alfresco in read-only or read-write mode. </p>Who's using my Alfresco?2008-05-31T19:25:00+02:002008-05-31T19:25:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-31:/whos-using-my-alfresco.html<p>Every shared file server administrator has this problem: "who
is taking most of the space?". This question is also a valid one for
Alfresco administrators, but they do not have any easy tool to answer
it. Adding this feature to Alfresco isn't very hard but for those who
prefer reusing …</p><p>Every shared file server administrator has this problem: "who
is taking most of the space?". This question is also a valid one for
Alfresco administrators, but they do not have any easy tool to answer
it. Adding this feature to Alfresco isn't very hard but for those who
prefer reusing the others work, I will present a piece of Freemarker
template doing it. This template will be also a good way to introduce
interesting Alfresco Freemarker use.</p>
<p>First, here is a preview of the final result.<br>
<a href="https://bosdonnat.fr/data/alfresco/shot-alf-size.png"><img alt="Preview of the space size template" src="https://bosdonnat.fr/data/alfresco/shot-alf-size.miniature.png"></a></p>
<p>I will present the template file in two steps:</p>
<ol>
<li>Showing a table with the current space children and their total size</li>
<li>Showing the same information as a pie chart</li>
</ol>
<p><strong>STEP 1: Showing the table</strong></p>
<p>First of all, having a function returning the total size of a space is
necessary. This function will have to recurse over the whole hierarchy
to compute the real size of the space. The following piece of Freemarker
code defines this function and can be called either on a container or on
a leaf of the tree.</p>
<div class="highlight"><pre><span></span><code><span class="err"><#function getSize node></span>
<span class="err"> <#assign sum = 0/></span>
<span class="err"> <#if node.children?size = 0></span>
<span class="err"> <#assign sum = node.size/></span>
<span class="err"> <#else&gt;</span>
<span class="err"> <#list node.children as child></span>
<span class="err"> <#assign sum = sum + getSize(child)/></span>
<span class="err"> <!--#list--></span>
<span class="err"> <!--#if--></span>
<span class="err"> <#return sum /></span>
<span class="err"><!--#function--></span>
</code></pre></div>
<p>Now that the function computing a node's real size is written, the
template showing the table is easy to do. Here is a way to do it like
the screenshot. The only noticeable point in this code could be the way
to alternate the CSS class for the data rows.</p>
<div class="highlight"><pre><span></span><code><span class="nt"><table</span> <span class="na">class=</span><span class="s">"recordSet"</span> <span class="na">border=</span><span class="s">"0"</span> <span class="na">cellspacing=</span><span class="s">"0"</span> <span class="na">cellpadding=</span><span class="s">"0"</span> <span class="na">width=</span><span class="s">"100%"</span><span class="nt">></span>
<span class="nt"><tbody></span>
<span class="nt"><tr></span>
<span class="nt"><th</span> <span class="na">class=</span><span class="s">"recordSetHeader"</span> <span class="na">style=</span><span class="s">"padding: 2px; text-align: left;"</span><span class="nt">></span>Node<span class="nt"></th></span>
<span class="nt"><th</span> <span class="na">class=</span><span class="s">"recordSetHeader"</span> <span class="na">style=</span><span class="s">"padding: 2px; text-align: left;"</span><span class="nt">></span>Size (in Byte)<span class="nt"></th></span>
<span class="nt"></tr></span>
<span class="err"><</span>#if document?exists>
<span class="nt"><tr</span> <span class="na">class=</span><span class="s">"recordSetRow"</span><span class="nt">></span>
<span class="nt"><td></span><span class="cp">${</span><span class="n">document</span><span class="o">.</span><span class="n">name</span><span class="cp">}</span><span class="nt"></td></span>
<span class="nt"><td></span><span class="cp">${</span><span class="n">getSize</span><span class="p">(</span><span class="n">document</span><span class="p">)</span><span class="cp">}</span><span class="nt"></td></span>
<span class="nt"></tr></span>
<span class="err"><</span>#else>
<span class="err"><</span>#assign i = 0/>
<span class="err"><</span>#list space.children as child>
<span class="nt"><tr</span> <span class="na">class=</span><span class="s">"</span><span class="cp">${</span><span class="p">(</span><span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span><span class="err">?</span><span class="n">string</span><span class="p">(</span><span class="s2">"></span>
<span class="o"><</span><span class="n">td</span> <span class="n">style</span><span class="o">=</span><span class="s2">"padding: 2px; text-align: left;"</span><span class="o">></span><span class="err">$</span><span class="p">{</span><span class="n">child</span><span class="o">.</span><span class="n">name</span><span class="cp">}</span><span class="s"></td></span>
<span class="s"> <td style="padding:</span> <span class="err">2px;</span> <span class="err">text-align:</span> <span class="err">left;"</span><span class="nt">></span><span class="cp">${</span><span class="n">getSize</span><span class="p">(</span><span class="n">child</span><span class="p">)</span><span class="cp">}</span><span class="nt"></td></span>
<span class="nt"></tr></span>
<span class="err"><</span>#assign i = i + 1 />
<span class="c"><!--#list--></span>
<span class="c"><!--#if--></span>
<span class="nt"></tbody></span>
<span class="nt"></table></span>
</code></pre></div>
<p><strong>STEP 2: Showing the pie chart</strong></p>
<p>To show a chart, an existing library for charts creation will be
necessary. I have chosen to use <a>PlotKit</a> Javascript library. This
library depends on the <a>MochiKit</a> Javascript library. There is an
example of chart with labels among the PlotKit examples to know how to
create the pie chart with the children names as labels. The problem is
that the JavaScript function used to create the chart will need the data
and these ones can't be computed another time for obvious performance
reasons.</p>
<p>The previously written function will have to be reused to produce the
JavaScript function. In order to reuse the data for both the chart and
the table, the data have to be put in a Freemarker sequence. But as
creating an empty Freemarker sequence and fill it in a loop doesn't seem
to be possible, the only solution is to create the Freemarker definition
of the sequence and evaluate it. Here is how to do it:</p>
<div class="highlight"><pre><span></span><code><span class="o"><#</span><span class="n">assign</span> <span class="n">ftlArray</span> <span class="o">=</span> <span class="ss">"["</span><span class="o">/></span>
<span class="o"><#</span><span class="k">if</span> <span class="n">document</span><span class="o">?</span><span class="k">exists</span><span class="o">></span>
<span class="o"><#</span><span class="n">assign</span> <span class="n">ftlArray</span> <span class="o">=</span> <span class="ss">"[["" + document.name + "","</span> <span class="o">+</span> <span class="n">getSize</span><span class="p">(</span><span class="n">document</span><span class="p">)</span><span class="o">?</span><span class="k">c</span> <span class="o">+</span> <span class="ss">"]]"</span><span class="o">/></span>
<span class="o"><#</span><span class="k">else</span><span class="o">></span>
<span class="o"><#</span><span class="n">assign</span> <span class="k">first</span> <span class="o">=</span> <span class="k">true</span> <span class="o">/></span>
<span class="o"><#</span><span class="n">list</span> <span class="k">space</span><span class="p">.</span><span class="n">children</span> <span class="k">as</span> <span class="n">child</span><span class="o">></span>
<span class="o"><#</span><span class="k">if</span> <span class="k">first</span> <span class="o">=</span> <span class="k">false</span><span class="o">></span>
<span class="o"><#</span><span class="n">assign</span> <span class="n">ftlArray</span> <span class="o">=</span> <span class="n">ftlArray</span> <span class="o">+</span> <span class="ss">","</span><span class="o">/></span>
<span class="o"><!</span><span class="c1">--#if--></span>
<span class="o"><#</span><span class="n">assign</span> <span class="n">ftlArray</span> <span class="o">=</span> <span class="n">ftlArray</span> <span class="o">+</span> <span class="ss">"["" + child.name + "","</span> <span class="o">+</span> <span class="n">getSize</span><span class="p">(</span><span class="n">child</span><span class="p">)</span><span class="o">?</span><span class="k">c</span> <span class="o">+</span> <span class="ss">"]"</span> <span class="o">/></span>
<span class="o"><#</span><span class="n">assign</span> <span class="k">first</span> <span class="o">=</span> <span class="k">false</span><span class="o">/></span>
<span class="o"><!</span><span class="c1">--#list--></span>
<span class="o"><#</span><span class="n">assign</span> <span class="n">ftlArray</span> <span class="o">=</span> <span class="n">ftlArray</span> <span class="o">+</span> <span class="ss">"]"</span><span class="o">/></span>
<span class="o"><!</span><span class="c1">--#if--></span>
<span class="o"><#</span><span class="n">assign</span> <span class="k">values</span> <span class="o">=</span> <span class="n">ftlArray</span><span class="o">?</span><span class="n">eval</span><span class="o">/></span>
</code></pre></div>
<p>After this Freemarker code, the <code>values</code> variable will contain the data
as a sequence of sequences. The JavaScript function to add in the
template and the HTML tag for the chart rendering are done in the
following way. For it to work, the files provided in the <code>lib/MochiKit</code>
directory of the MochiKit distribution and the files found in the
<code>PlotKit</code> directory of the MochiKit distribution have to be placed in
<code>/scripts/mochikit</code> and <code>/scripts/plotkit</code> in the alfresco WAR.</p>
<div class="highlight"><pre><span></span><code><span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/mochikit/MochiKit.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">0</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/plotkit/excanvas.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">1</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/plotkit/Base.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">2</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/plotkit/Layout.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">3</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/plotkit/Canvas.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">4</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">"/alfresco/scripts/plotkit/SweetCanvas.js"</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">5</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
<span class="p"><</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"text/javascript"</span><span class="p">></span><span class="c"><!--</span><span class="nx">mce</span><span class="o">:</span><span class="mi">6</span><span class="o">--></span><span class="p"></</span><span class="nt">script</span><span class="p">></span>
</code></pre></div>
<p>The chart will be rendered in the canvas element. The code shown in the
first step for the table printing has to be adapted to use the <code>values</code>
variable instead of using directly the <code>getSize()</code> function.</p>
<p>In order to use the template, place it in the
<code>Data Dictionary/Presentation Templates</code> space in Alfresco. Then simply
apply the template on the space for which to get the table and chart.</p>
<p>Here are some useful links to create more templates like this one for
Alfresco:</p>
<ul>
<li><a>Freemarker reference</a></li>
<li><a>Alfresco Freemarker guide</a></li>
<li><a>Alfresco Freemarker cookbook</a></li>
</ul>Alfresco and categories2008-05-23T20:15:00+02:002008-05-23T20:15:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-23:/alfresco-and-categories.html<p>Have you ever counted the number of clics needed to select a
Category on a document in Alfresco? The user interface for the category
selection was really hard to understand for a normal user up to in the
2.x series and will be improved in the 3.0 version …</p><p>Have you ever counted the number of clics needed to select a
Category on a document in Alfresco? The user interface for the category
selection was really hard to understand for a normal user up to in the
2.x series and will be improved in the 3.0 version. This can already be
tested in the 2.9 Beta version.</p>
<p>I have worked on a little test with <a href="http://www.jboss.org/jbossrichfaces/">RichFaces</a> to make it better.
When I hear that the 2.9 had changed the categories selection I needed
to see how it was done... It's better than the previous interface but
not yet perfect for me: my test is still useful.</p>
<p>My test presents the categories as a tree in a modal dialog. Here is a
screenshot to better understand what I am talking about.</p>
<p><a href="https://bosdonnat.fr/data/alfresco/screenshot1.png"><img alt="Alfresco categories test screenshot" src="https://bosdonnat.fr/data/alfresco/screenshot1.miniature.png"></a></p>
<p>As you can guess this is a test on a blank page... it still needs to be
integrated but it looks promising. To make it work I am using a
combination of the JSF RichFaces taglib and WebScripts.</p>
<p>The next steps are</p>
<ul>
<li>to support list of categories</li>
<li>to embed all the JSF part into a tag lib to make it easier to embed
everywhere</li>
<li>test it as a replacement for Alfresco standard categories selection
UI</li>
</ul>
<p>That said Alfresco 2.9 has a nice feature around the categories. In the
left panel you can show the list of your document sorted in the
categories tree...</p>
<p>Useful link: <a href="http://livedemo.exadel.com/richfaces-demo/index.jsp">the RichFaces live demo</a>.</p>Changing Alfresco Breadcrumb2008-05-23T08:05:00+02:002008-05-23T08:05:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-23:/changing-alfresco-breadcrumb.html<p>Since I am configuring and installing Alfresco for customers I
have a remark about the breadcrumb. Many of the customers want it to be
a path showing the current node location instead of the default
breadcrumb. In fact it behaves like a path if you are using only the
browsing …</p><p>Since I am configuring and installing Alfresco for customers I
have a remark about the breadcrumb. Many of the customers want it to be
a path showing the current node location instead of the default
breadcrumb. In fact it behaves like a path if you are using only the
browsing interface, but not if you are using the navigator on the left.
This is often seen as a bug by the users.</p>
<p>The good news is that Alfresco breadcrumb will be configurable in
version 3.0. This feature is already present in Alfresco 2.9. The <a href="http://wiki.alfresco.com/wiki/Web_Client_Customisation_FAQ#Changing_Breadcrumb_Mode">Web
client customisation FAQ</a> page from the Alfresco Wiki explains how to
configure it. However, if you want this feature on a previous version of
Alfresco this can also be done... even if it is a bit more tricky.</p>
<p>To do this, you will have to override the
<code>org.alfresco.web.ui.common.renderer.BreadcrumbRenderer</code> class and
implement the <code>encodeBegin()</code> method yourself by using the
<code>NavigatorBean.getCurrentNode()</code> method and the <code>NodeService</code>. To make
Alfresco use your renderer instead of the defaults, don't forget to add
something like the following section in the <code>faces-config-custom.xml</code>
file:</p>
<div class="highlight"><pre><span></span><code><span class="nt"><render-kit></span>
<span class="nt"><renderer></span>
<span class="nt"><component-family></span>org.alfresco.faces.Controls<span class="nt"></component-family></span>
<span class="nt"><renderer-type></span>org.alfresco.faces.BreadcrumbRenderer<span class="nt"></renderer-type></span>
<span class="nt"><renderer-class></span>some.company.alfresco.MyBreadcrumbRenderer<span class="nt"></renderer-class></span>
<span class="nt"></renderer></span>
<span class="nt"></render-kit></span>
</code></pre></div>
<p>And do not forget to change the class name in this small XML code... </p>Using Firefox 3.0 beta 52008-05-22T09:29:00+02:002008-05-22T09:29:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-22:/using-firefox-30-beta-5.html<p>As I have updated to the Ubuntu 8.04 I now have firefox 3.0
Beta 5 installed on my computer. Some of my extensions where not updated
for Firefox 3.0 but I have found some betas of these extensions or
replacements. Here are the extensions I've found: I …</p><p>As I have updated to the Ubuntu 8.04 I now have firefox 3.0
Beta 5 installed on my computer. Some of my extensions where not updated
for Firefox 3.0 but I have found some betas of these extensions or
replacements. Here are the extensions I've found: I hope these links can
be useful to someone else.</p>
<ul>
<li><strong>Firebug</strong> - Use the 1.2 beta version which could be fetched on
<a href="http://getfirebug.com/releases/">firebug's website</a></li>
<li><strong>Del.icio.us bookmarks</strong> - Use the beta provided on <a href="http://blog.delicious.com/blog/2008/04/firefox-3-delicious-and-you.html">del.icio.us
blog</a></li>
<li><strong>Document map</strong> - This extension shows the document headings as a
tree: this is really handy when reading huge pages. This extension
has no version for Firefox 3.0 beta 5 but I have found another
experimental extension doing the same job: <a href="https://addons.mozilla.org/fr/firefox/addon/7203">HeadingsMap (es)</a>.</li>
</ul>
<p>Now I can use Firefox 3.0 like I was using Firefox 2.x... </p>Using webscripts to extend Alfresco Web client2008-05-18T23:39:00+02:002008-05-18T23:39:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-18:/using-webscripts-to-extend-alfresco-web-client.html<p>Alfresco Webscripts are really easy to code and can help to do
many things (but not the coffee yet). They can even be used to create
new dialogs in Alfresco, for example to show some custom informations.
This post will explain how to setup a simple mechanism to help creating …</p><p>Alfresco Webscripts are really easy to code and can help to do
many things (but not the coffee yet). They can even be used to create
new dialogs in Alfresco, for example to show some custom informations.
This post will explain how to setup a simple mechanism to help creating
Alfresco dialogs based on webscript with only an action configuration.</p>
<p>The steps are the following:</p>
<ol>
<li>Create a generic dialog configured in <code>web-client-config-custom.xml</code></li>
<li>Create the Webscript to display in the dialog</li>
<li>Create the action configuration to display the dialog with the
webscript</li>
</ol>
<p>In this post, I will assume that you already have a webscript to show
and that you are already quite used to Alfresco extensions developement:
these could be topics for some other posts and are well explained on
Alfresco Wiki. </p>Eclipse RCP and AJAX2008-05-14T22:16:00+02:002008-05-14T22:16:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-14:/eclipse-rcp-and-ajax.html<p>Some time ago, I've discovered an Eclipse project which sounds
interesting to me. This project aims at providing an AJAX runtime target
for Eclipse RCP applications. I didn't have more time but to play a
little with the public demos. Thus I still wondered what is the gap for
an …</p><p>Some time ago, I've discovered an Eclipse project which sounds
interesting to me. This project aims at providing an AJAX runtime target
for Eclipse RCP applications. I didn't have more time but to play a
little with the public demos. Thus I still wondered what is the gap for
an Eclipse RCP applications developper before starting to create a RAP
application.</p>
<p>Today I had some time to have a look at the sources of a RAP application
project. There is quite nothing more to do if you are already
programming Eclipse RCP applications as the differences are:</p>
<ul>
<li>Adding the <code>org.eclipse.rap.ui</code> plugin to the dependencies.</li>
<li>Importing the <code>javax.servlet</code> and <code>javax.servlet.http</code> packages</li>
<li>Add an <code>org.eclipse.rap.ui.entrypoint</code> extension to define the RAP
application entry point</li>
</ul>
<p>To internationalization of a RAP application works also differently from
the standard Eclipse internationalization. This is described in the RAP
on-line help: internationalizing a RAP application shouldn't be a huge
problem.</p>
<p>A RAP application can even be packaged in a WAR file as any other web
application. There is no wizard to perform this, but a sample Eclipse
feature projects with Ant build scripts are available on the Eclipse
CVS. There is also generic Equinox documentation on that topic at
<a href="http://www.eclipse.org/equinox/server/http_in_container.php">http://www.eclipse.org/equinox/server/http_in_container.php</a>.</p>
<p>Thus creating a standard Web application by using the JFace and SWT APIs
is quite easy. When combined with <a href="http://www.springframework.org/osgi">Spring-OSGi</a>, let us imagine
creating powerful and sexy Web applications.</p>
<p>The only thing I still would like to see before being a RAP fan is a
benchmark of an application used by hundreds or thousands of users. Does
it make a difference with toolkits like <a href="http://code.google.com/webtoolkit/">GWT</a> or <a href="http://developer.yahoo.com/yui/">YUI</a>? Can I use
RAP for business applications used every day by a whole company? </p>Getting an OOo CWS2008-05-12T16:56:00+02:002008-05-12T16:56:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-12:/getting-an-ooo-cws.html<p>Recently, I wanted to build OOo with some features like canvas support.
As I had some errors when building the canvas module, <a href="http://eric.bachard.free.fr/news/">ericb2</a> told me
that I should get the <em>canvas05</em> CWS<footnote>CWS: Child Work
Space</footnote> and build OpenOffice.org with it. As I didn't know how
to do it …</p><p>Recently, I wanted to build OOo with some features like canvas support.
As I had some errors when building the canvas module, <a href="http://eric.bachard.free.fr/news/">ericb2</a> told me
that I should get the <em>canvas05</em> CWS<footnote>CWS: Child Work
Space</footnote> and build OpenOffice.org with it. As I didn't know how
to do it, Eric explained it on <code>#education.openoffice.org</code> channel.
Here is a condensed version of what Eric explained on IRC for people
who'ld like to check out a CWS.</p>
<p><strong>Getting informations on the CWS</strong></p>
<p>The first thing to do is to get some informations about the desired CWS.
For this, search the wanted CWS in <a href="https://tools.services.openoffice.org/EIS2/GuestLogon">EIS</a>. A search by the CWS name
will do the trick here as we know it: <em>canvas05</em>. Click on the CWS name
in the search results and then on the <strong>All</strong> link to see all the CWS
informations.</p>
<p>In our case, the useful informations are:</p>
<ul>
<li>the current milestone, which is the milestone against which to build
the CWS. Here the milestone for <em>canvas05</em> is <em>m9</em></li>
<li>the list of the CVS modules changed by the CWS. Here these are:
basecmp, basegfx, canvas, comphelper, cppcanvas, goodies, offapi,
officecfg, offuh, scp2, sd, sdext, slideshow, scx, testshl2, tools,
unoil, vcl</li>
<li>the MWS<footnote>MWS: Master Work Space</footnote> of the CWS'
creation. Here it's <em>SRC680</em></li>
</ul>
<p><strong>Getting the sources</strong></p>
<p>First, be sure to have the sources of the correct OpenOffice.org
milestone. If not, check them out using the following command. For more
informations on how to access the OpenOffice.org CVS, read <a href="http://wiki.services.openoffice.org/wiki/CVS">this
page</a>. In this command, <code>DEV300</code> is the MWS and <code>m9</code> the milestone of
the desired version. Before executing this command, be sure to have set
the <code>CVSROOT</code> environment variable.</p>
<div class="highlight"><pre><span></span><code>cvs -z4 co -r DEV300_m9 OpenOffice3
</code></pre></div>
<p>Now that the OpenOffice.org sources are checked out, it's time to check
out the sources of the CWS. To do this, use a shell command (Windows
users, can use it with Cygwin or can translate it) like the following.
In this command:</p>
<ul>
<li>the list of the <code>for</code> loop is the list of the changed modules for
the CWS</li>
<li>
<p>the tag to extract is build using the MWS of the CWS creation and
the CWS name</p>
<p>:::sh
for i in basebmp basegfx canvas comphelper cppcanvas goodies offapi officecfg offuh scp2 sd sdext slideshow svx testshl2 tools unoil vcl
do
mv $i $i"_old"
cvs -z4 co -r cws_src680_canvas05 $i
done</p>
</li>
</ul>
<p>After this, there is "only" to build OpenOffice.org with the CWS. </p>Improving the uno-skeletonmaker2008-05-06T10:34:00+02:002008-05-06T10:34:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-06:/improving-the-uno-skeletonmaker.html<p>As many of the readers may wonder what is the <code>uno-skeletonmaker</code>, I
will start with a short explanation of its use. The <code>uno-skeletonmaker</code>
is a command line tool provided in the OpenOffice.org SDK which
generates a skeleton of code for the implementation of an UNO IDL
service specification. This …</p><p>As many of the readers may wonder what is the <code>uno-skeletonmaker</code>, I
will start with a short explanation of its use. The <code>uno-skeletonmaker</code>
is a command line tool provided in the OpenOffice.org SDK which
generates a skeleton of code for the implementation of an UNO IDL
service specification. This tool can generate either C++ or Java. The
<code>uno-skeletonmaker</code> is mainly used in the Eclipse and NetBeans
integrations for OpenOffice.org.</p>
<p><strong>Why do I would like to improve the <code>uno-skeletonmaker</code>?</strong></p>
<p>In fact the code generated by this tool is not really acceptable for a
OpenOffice.org extensions beginner developer. For example, the methods
generated for an interface attributes in Java simply does nothing and
there is no <code>TODO</code> comment to inform the developer that something has to
be written there. What could be great has been started in the C++ code
generation: these methods have a default body using a private member.
The problem with the C++ generated code is that the member is not
defined.</p>
<p>By talking with Noel Power at the Go-OOCon in Prague, we found
interesting to improve (may be redevelop) the <code>uno-skeletonmaker</code> for it
to be able to manage code style definitions. The need is that every
coder or enterprise has its own code style and would like to have it
applied by the <code>uno-skeletonmaker</code>. An other interesting point of making
the <code>uno-skeletonmaker</code> templateable would be to have to ability to add
new languages more easily (e.g. Python).</p>
<p>I've started hacking the <code>uno-skeletonmaker</code> to fix the attributes
methods generation problems and I will certainly add the support of
singletons code generation. However, I won't make the
<code>uno-skeletonmaker</code> templateable during the nights because its quite a
long job. If anyone wants to do it, feel free to propose yourself on the
<code>dev AT api</code> mailing list: its a quite small piece of code with really
few dependencies. </p>Zimbra & Evolution2008-05-01T22:35:00+02:002008-05-01T22:35:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-05-01:/zimbra-evolution.html<p>As I had problems to use <a href="http://www.zimbra.com/">Zimbra</a> collaborative messaging
correctly without using the web client interface, I decided to find a
really useable solution.</p>
<p>I was using Mozilla Thunderbird 2.0 on my Ubuntu laptop to read all the
emails from all my mail boxes. I tried <a href="http://www.mozilla.org/projects/calendar/lightning/">Lightening 0.8 …</a></p><p>As I had problems to use <a href="http://www.zimbra.com/">Zimbra</a> collaborative messaging
correctly without using the web client interface, I decided to find a
really useable solution.</p>
<p>I was using Mozilla Thunderbird 2.0 on my Ubuntu laptop to read all the
emails from all my mail boxes. I tried <a href="http://www.mozilla.org/projects/calendar/lightning/">Lightening 0.8</a> for Zimbra
calendar management, but there were some bugs and problems to connect to
my Zimbra Calendar. I tried Zimbra Desktop too, but there were some
problems with searches in shared folders. There are even some tricky
things with the emails trapped into server filters.</p>
<p>Then I tried <a href="http://www.gnome.org/projects/evolution/">Evolution</a> because it has all the features I needed:</p>
<ul>
<li>Multiple emails accounts</li>
<li>Calendar</li>
<li>Shared contacts</li>
</ul>
<p>The only problem was to make it work properly with Zimbra. There is an
evolution connector for Zimbra, but it isn't present in Ubuntu Feisty
Fawn repositories. Hopefully I found <a href="http://www.hockeypfef.net/index.cfm/2007/3/27/Howto-Configure-the-Zimbra-Evolution-Connector-for-Ubuntu">this interesting blog article
explaining how to build it</a>.</p>
<p>There are some more things to do for it to work:</p>
<ul>
<li>Install all the dependencies: they aren't all listed in the article
and I can't remember which one I have installed. Don't worry the
<code>configure</code> program will tell you what is missing!</li>
<li>Edit the <code>configure.ac</code> file to change the evolution version to the
one matching your installation. In my case I changed into this
because the version 2.10 wasn't taken into account by the script:<div class="highlight"><pre><span></span><code><span class="err"> EVOLUTION_VERSION=`pkg-config --modversion evolution-shell-2.10 2>/dev/null`</span>
<span class="err"> if test -z "$EVOLUTION_VERSION"; then</span>
<span class="err"> AC_MSG_ERROR(Evolution development libraries not installed)</span>
<span class="err"> else</span>
<span class="err"> EVOLUTION_API_VERSION=2.10</span>
<span class="err"> EAPI_MAJOR_VERSION=2</span>
<span class="err"> EAPI_MINOR_VERSION=10</span>
<span class="err"> CAMEL_API_VERSION=1.2</span>
<span class="err"> EDS_API_VERSION=1.2</span>
<span class="err"> fi</span>
</code></pre></div>
</li>
</ul>
<p>After the usual <code>make</code> and <code>make install</code> steps I have a new <em>Zimbra</em>
account type in the wizard. Adding a Zimbra account adds the email
account, the zimbra contacts and the calendar. Zimbra shared email
folders are normal folders in Evolution. For an offline use, there is
only to select the folders to use offline. I still have to see how the
appointment attempts are done by emails.</p>
<p>The only things I could reproach to this Zimbra - Evolution connector
are:</p>
<ol>
<li>the Evolution tags are viewed in Zimbra as <code>$Label1</code>, <code>$Label2</code>,
etc. It could be much better to be able to reuse Zimbra tags in
Evolution and vice-versa.</li>
<li>the connector doesn't show the shared calendars of Zimbra: only the
user calendar</li>
</ol>Discovering VIm2008-04-19T21:50:00+02:002008-04-19T21:50:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-04-19:/discovering-vim.html<p><strong>This post is not intended to participate in any troll
throwing competition and doesn't aim at (re)starting any flame war with
emacs users.</strong></p>
<p>I'm using vim for some times, but in many occasions I could see how few
of its features I am using. I discovered today some interesting …</p><p><strong>This post is not intended to participate in any troll
throwing competition and doesn't aim at (re)starting any flame war with
emacs users.</strong></p>
<p>I'm using vim for some times, but in many occasions I could see how few
of its features I am using. I discovered today some interesting features
for coders like autocompletion, mass insertion, going to matching
parentheses. Here are some useful links:</p>
<ul>
<li><a href="http://www.43things.com/things/view/253990/learn-vim">http://www.43things.com/things/view/253990/learn-vim</a></li>
<li><a href="http://www.cs.utah.edu/~kad/vim/vimnotes.shtml">http://www.cs.utah.edu/~kad/vim/vimnotes.shtml</a></li>
<li><a href="http://www.vim.org/tips/tip.php?tip_id=194">http://www.vim.org/tips/tip.php?tip_id=194</a></li>
</ul>
<p>There is even a page in OpenOffice.org wiki to help <a href="http://wiki.services.openoffice.org/wiki/Editor_Vim">configure Vim for
OpenOffice.org</a> developement. I think that I'll try all this out
soon... </p>ArrayList or Vector ?2008-04-10T18:25:00+02:002008-04-10T18:25:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-04-10:/arraylist-or-vector.html<p>Today I wondered why there is two classes to handle vectors in
Java: <code>java.util.ArrayList</code> and <code>java.util.Vector</code>. After having
carefully read the javadoc, I found that the Vector is synchronized on
the contrary of the ArrayList. Thus, there will be a difference only for
threaded applications.</p>
<p>By …</p><p>Today I wondered why there is two classes to handle vectors in
Java: <code>java.util.ArrayList</code> and <code>java.util.Vector</code>. After having
carefully read the javadoc, I found that the Vector is synchronized on
the contrary of the ArrayList. Thus, there will be a difference only for
threaded applications.</p>
<p>By searching the web a bit more I found this very interesting page at
<a href="http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html">JavaWorld</a>. By reading this, I understood how much there is still to
know about Java to optimize programs... I never had a look at the
<code>LinkedList</code> class, but I certainly should have done it in many
cases... </p>OOo for coders ?2008-04-08T11:48:00+02:002008-04-08T11:48:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2008-04-08:/ooo-for-coders.html<p>From my first project report containing code at school I had
the need to create a syntax highlighting tool for OpenOffice.org. These
last years I had no time to do it. Even if I don't have more currently,
having stopped the Eclipse plugin for OpenOffice.org development gives
me …</p><p>From my first project report containing code at school I had
the need to create a syntax highlighting tool for OpenOffice.org. These
last years I had no time to do it. Even if I don't have more currently,
having stopped the Eclipse plugin for OpenOffice.org development gives
me a little more time for it.</p>
<p>To implement such a tool, I started from <a href="http://qbnz.com/highlighter/">GeSHi</a>, the famous PHP tool
for syntax highlightinh. I'm converting the GeSHi algorithm into a Java
extension for OpenOffice.org. The only problem is that applying
OpenOffice.org styles for the highlighting imposes rethinking some parts
of the algorithm. For example:</p>
<ul>
<li>GeSHi adds the style for a string before having found its end. In
OpenOffice.org I need to get the end of the string before defining
its style.</li>
<li>GeSHi defines the style of the escaped characters first and then
finds the end of the string. In OpenOffice.org I first need to get
the end of the string to set the string style before setting the
escaped characters style.</li>
</ul>
<p>After some other troubles like these there will be an OpenOffice.org
extension to format source code in a clean and easy way. Thus stay
tuned... </p>Alfresco Webscripts contest2008-03-24T18:46:00+01:002008-03-24T18:46:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-03-24:/alfresco-webscripts-context.html<p>Only 7 days before the end of the first period of the Alfresco Webscript
contest. Alfresco has launched a context to stimulate the creation of
nice and useful webscripts from the community. You can read the
<a href="http://www.alfresco.com/partners/programme/webscripts/">Alfresco contest page</a> to get more informations on this context.</p>
<p>During my previous missions …</p><p>Only 7 days before the end of the first period of the Alfresco Webscript
contest. Alfresco has launched a context to stimulate the creation of
nice and useful webscripts from the community. You can read the
<a href="http://www.alfresco.com/partners/programme/webscripts/">Alfresco contest page</a> to get more informations on this context.</p>
<p>During my previous missions an Alfresco, customers often complains that
there is no tool to easily view the permissions of a given user. In the
Alfresco web client, the administrator has to navigate to the space or
document, look for the permissions and possibily needs to look at the
permissions set on the parent spaces. I submitted a webscript for this
problem to the contest. This Alfresco WebScript shows all the
permissions of the selected user on the content. If you click on the
permissions summary you even have all the roles set for the user.</p>
<p>Here is a screenshot of the webscript:</p>
<p><img alt="Admin webscript screenshot" src="https://bosdonnat.fr/data/alfresco/alfresco-admin.png"></p>
<p>The WebScript module can be downloaded from here:</p>
<p><a href="https://bosdonnat.fr/data/alfresco-admin.amp">alfresco-admin.amp</a></p>Filters in OOo2008-03-10T15:55:00+01:002008-03-10T15:55:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-03-10:/filters-in-ooo.html<p>Today, I wanted to get the list of the export and import
filters managed by OpenOffice.org. It took me quite a long time to find
out how to automatically distinguish an import filter form an export
filter.</p>
<p>The first thing to look for is any API to get the …</p><p>Today, I wanted to get the list of the export and import
filters managed by OpenOffice.org. It took me quite a long time to find
out how to automatically distinguish an import filter form an export
filter.</p>
<p>The first thing to look for is any API to get the list of the managed
filters. This can be achieved using the
<code>com.sun.star.document.FilterFactory</code> service. With this service, you
have the internal names of all the filters and you can access there
display name and configuration. Here is an example to get the data for
the HTML filter:</p>
<div class="highlight"><pre><span></span><code><span class="err">Function getHtmlFilter()</span>
<span class="err"> oFilterFactory = createUnoService("com.sun.star.document.FilterFactory")</span>
<span class="err"> getHtmlFilter() = oFilter.getByName("HTML")</span>
<span class="err">End Function</span>
</code></pre></div>
<p>The IDL reference for the FilterFactory service is quite interesting
when you can read the line:</p>
<blockquote>
<p>Flags [integer] They describe the filter more specific.<br>
(e.g. they mark it as IMPORT/EXPORT or DEFAULT filter.)</p>
</blockquote>
<p>The main problem of this documentation is that the <code>Flags</code> property
value contains an integer resulting from added constants. There is no
documentation or API for these constants... Here is the start of the
difficult part of the exercise. I had to look in the sources for some
minutes to find the right file where these constants are defined:
<a href="http://lxr.go-oo.org/source/framework/sfx2/inc/sfx2/docfilt.hxx">framework/sfx2/inc/sfx2/docfilt.hxx</a>. There you can learn that the
value for the <code>IMPORT</code> constant is <code>1</code> and the value for the <code>EXPORT</code>
constant is <code>2</code>. </p>
<p>Here is a sample of OOoBasic code to get the list of the import
filters and the list of the export filters.</p>
<div class="highlight"><pre><span></span><code><span class="n">Sub</span> <span class="n">Main</span><span class="p">()</span>
<span class="n">oFilterFactory</span> <span class="o">=</span> <span class="n">createUnoService</span><span class="p">(</span><span class="ss">"com.sun.star.document.FilterFactory"</span><span class="p">)</span>
<span class="n">aNames</span> <span class="o">=</span> <span class="n">oFilterFactory</span><span class="p">.</span><span class="n">getElementNames</span><span class="p">()</span>
<span class="n">Dim</span> <span class="n">aExports</span><span class="p">()</span>
<span class="n">Dim</span> <span class="n">aImports</span><span class="p">()</span>
<span class="k">For</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span> <span class="k">To</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aNames</span><span class="p">)</span>
<span class="n">sName_i</span> <span class="o">=</span> <span class="n">aNames</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="n">xFilter</span> <span class="o">=</span> <span class="n">oFilterFactory</span><span class="p">.</span><span class="n">getByName</span><span class="p">(</span><span class="n">sName_i</span><span class="p">)</span>
<span class="n">nFlag</span> <span class="o">=</span> <span class="n">getFlag</span><span class="p">(</span><span class="n">xFilter</span><span class="p">)</span>
<span class="k">If</span> <span class="n">nFlag</span> <span class="k">mod</span> <span class="mi">2</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">Then</span>
<span class="n">nNbExport</span> <span class="o">=</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aExports</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">ReDim</span> <span class="k">Preserve</span> <span class="n">aExports</span><span class="p">(</span><span class="n">nNbExport</span><span class="p">)</span>
<span class="n">aExports</span><span class="p">(</span><span class="n">nNbExport</span><span class="p">)</span> <span class="o">=</span> <span class="n">sName_i</span>
<span class="k">Else</span>
<span class="n">nNbImport</span> <span class="o">=</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aImports</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">ReDim</span> <span class="k">Preserve</span> <span class="n">aImports</span><span class="p">(</span><span class="n">nNbImport</span><span class="p">)</span>
<span class="n">aImports</span><span class="p">(</span><span class="n">nNbImport</span><span class="p">)</span> <span class="o">=</span> <span class="n">sName_i</span>
<span class="k">End</span> <span class="k">If</span>
<span class="k">Next</span> <span class="n">i</span>
<span class="n">sExports</span> <span class="o">=</span> <span class="ss">""</span>
<span class="k">For</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span> <span class="k">To</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aExports</span><span class="p">)</span>
<span class="n">sExports</span> <span class="o">=</span> <span class="n">sExports</span> <span class="o">&</span> <span class="n">aExports</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="k">Next</span> <span class="n">i</span>
<span class="n">sImports</span> <span class="o">=</span> <span class="ss">""</span>
<span class="k">For</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span> <span class="k">To</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aImports</span><span class="p">)</span>
<span class="n">sImports</span> <span class="o">=</span> <span class="n">sImports</span> <span class="o">&</span> <span class="n">aImports</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="k">Next</span> <span class="n">i</span>
<span class="n">sStats</span> <span class="o">=</span> <span class="ss">"Nb Filters: "</span> <span class="o">&</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aNames</span><span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="n">sStats</span> <span class="o">=</span> <span class="n">sStats</span> <span class="o">&</span> <span class="ss">"Nb Exports: "</span> <span class="o">&</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aExports</span><span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="n">sStats</span> <span class="o">=</span> <span class="n">sStats</span> <span class="o">&</span> <span class="ss">"Nb Imports: "</span> <span class="o">&</span> <span class="n">UBound</span><span class="p">(</span><span class="n">aImports</span><span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
<span class="n">MsgBox</span> <span class="n">sStats</span>
<span class="n">msgbox</span> <span class="n">sImports</span>
<span class="n">msgbox</span> <span class="n">sExports</span>
<span class="k">End</span> <span class="n">Sub</span>
<span class="k">Function</span> <span class="n">getFlag</span><span class="p">(</span><span class="n">xFilter</span><span class="p">)</span>
<span class="n">getFlag</span><span class="p">()</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">For</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span> <span class="k">To</span> <span class="n">UBound</span><span class="p">(</span><span class="n">xFilter</span><span class="p">)</span>
<span class="n">xProp_i</span> <span class="o">=</span> <span class="n">xFilter</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">If</span> <span class="n">xProp_i</span><span class="p">.</span><span class="n">Name</span> <span class="o">=</span> <span class="ss">"Flags"</span> <span class="k">Then</span>
<span class="n">getFlag</span><span class="p">()</span> <span class="o">=</span> <span class="n">xProp_i</span><span class="p">.</span><span class="n">Value</span>
<span class="k">End</span> <span class="k">If</span>
<span class="k">Next</span> <span class="n">i</span>
<span class="k">End</span> <span class="k">Function</span>
</code></pre></div>
<p>Using this discovery and the <a href="http://api.openoffice.org/docs/common/ref/com/sun/star/document/TypeDetection.html"><code>com.sun.star.document.TypeDetection</code></a> service you can
compute quite the same filters than the one of the standard OpenOffice.org file picker dialog.</p>My first post on Alfresco2008-03-10T10:03:00+01:002008-03-10T10:03:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-03-10:/my-first-post-on-alfresco.html<p>Even if I'm working on <a href="http://alfresco.com/">Alfresco</a> projects for a little bit
more than one year, I haven't posted any message on this development
adventure. Today will be the first post on that topic but maybe not the
only one.</p>
<p>To get introduced to Alfresco development it takes quite a long …</p><p>Even if I'm working on <a href="http://alfresco.com/">Alfresco</a> projects for a little bit
more than one year, I haven't posted any message on this development
adventure. Today will be the first post on that topic but maybe not the
only one.</p>
<p>To get introduced to Alfresco development it takes quite a long time
because of the numerous extension points and concepts to learn. A good
starting point is to read the <a href="http://wiki.alfresco.com/wiki/Developer_Guide">Developers guide on the wiki</a>. However,
unlike many other internet resources you will need to read it quite
sequentially if you want to understand everything... otherwise you will
be told about Data Dictionary and Model and you won't know what it is
(this is an example).</p>
<p>There are several ways to extend Alfresco. The following ones are some
examples:</p>
<ul>
<li>Extend or customize the Web Client using JSF development or Alfresco
actions creation</li>
<li>Create jBPM workflows, Javascript automated rules, Java behaviour
policies</li>
<li>Extend the existing Data Model to match your needs</li>
<li>Extend the Alfresco Core using Spring beans</li>
<li>Extend the remote API using WebScripts and defining your own REST
API</li>
</ul>
<p>I will certainly detail some interesting development points or existing
Alfresco extensions in next posts: stay tuned... </p>No hope for the Eclipse Integration ?2008-02-21T16:38:00+01:002008-02-21T16:38:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-02-21:/no-hope-for-the-eclipse-integration.html<p>I had a look at <a href="http://symphony.lotus.com">Lotus Symphony Beta 4</a> last week and I'm
having a lot of doubts after that. The main difference between Lotus
Symphony Beta 4 and the previous versions is that it comes with an SDK.
Symphony extensions will be based on Eclipse plugins' system, not on …</p><p>I had a look at <a href="http://symphony.lotus.com">Lotus Symphony Beta 4</a> last week and I'm
having a lot of doubts after that. The main difference between Lotus
Symphony Beta 4 and the previous versions is that it comes with an SDK.
Symphony extensions will be based on Eclipse plugins' system, not on
<code>OXT</code> files like OpenOffice.org. The SDK will of course be based on
Eclipse, but as the extension system is completely different the Eclipse
Integration will be of no use for the Lotus Symphony developers.</p>
<p>The main problem here is that I have no time to develop the Eclipse
integration during my spare time anymore and I doubt that Sun will help
developing an Eclipse plugin. As there is an engineer working at full
time on the Netbeans integration at Sun, the Eclipse integration has
much less features and will certainly not be used.</p>
<p>This message is quite an official announcement: <strong>I stop working on the
Eclipse integration as long as there is nobody to help developing it</strong>.
This help could be either financial by paying me doing it or simply by
providing time to somebody else to work on it.</p>
<p>Leaving the Eclipse integration in such a state is quite hard for me
after almost 3 years working on it... I really hope there will be a way
to continue its development. </p>Database client for many RDBMS2008-02-14T18:36:00+01:002008-02-14T18:36:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-02-14:/database-client-for-many-rdbms.html<p>I wanted for a long time to have one database client to access
databases of different types like HSQLDB, MySQL, SQLite, etc. I finally
found an interesting one in Java. It only needs to have the JDBC driver
for the RDBMS that should be accessed. This is a free software …</p><p>I wanted for a long time to have one database client to access
databases of different types like HSQLDB, MySQL, SQLite, etc. I finally
found an interesting one in Java. It only needs to have the JDBC driver
for the RDBMS that should be accessed. This is a free software tool
named SQuirreL SQL (<a href="http://squirrel-sql.sourceforge.net/">home page</a>).</p>
<p>I also wanted to access SQLite databases throught this client or any
Java code. Finding the JDBC driver for SQLite is quite hard, but here is
a <a href="http://www.zentus.com/sqlitejdbc/">working one</a>. To use it with SQuirreL SQL, simply place the JDBC
jar file in the lib directory of SQuirreL installation and add a new
JDBC driver with the class <code>org.sqlite.JDBC</code>. </p>Measures to avoid data loss2008-02-14T00:00:00+01:002008-02-14T00:00:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-02-14:/measures-to-avoid-data-loss.html<p>During the time my website was down, I was afraid of having
lost some data. Among them were the 400 photos of my wedding and some
interesting articles about UNO. To avoid this I decided to setup some
backup scripts. It is easily done using:</p>
<ul>
<li><a href="http://restkultur.ch/personal/wolf/scripts/db_backup/">db_backup</a>: a small PHP tool …</li></ul><p>During the time my website was down, I was afraid of having
lost some data. Among them were the 400 photos of my wedding and some
interesting articles about UNO. To avoid this I decided to setup some
backup scripts. It is easily done using:</p>
<ul>
<li><a href="http://restkultur.ch/personal/wolf/scripts/db_backup/">db_backup</a>: a small PHP tool for dumping databases</li>
<li>wget: to mirror the FTP</li>
</ul>
<p>Now this site will be mirrored by my own computer and maybe soon by
another website... in case of. </p>Why my blog has been down2008-02-11T10:40:00+01:002008-02-11T10:40:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2008-02-11:/why-my-blog-has-been-down.html<p>During more than one month my blog was down. I had several
complains about the missing OpenOffice.org Eclipse integration update
site. This is mainly due to my ISP for not warning when they unactivate
an account. In fact Free.fr as unactivated my account due to too many
spam …</p><p>During more than one month my blog was down. I had several
complains about the missing OpenOffice.org Eclipse integration update
site. This is mainly due to my ISP for not warning when they unactivate
an account. In fact Free.fr as unactivated my account due to too many
spam comments in the database.</p>
<p>On top of that, I had no internet connection during the same time and it
was hard to manage these two problems at the same time with the ISP.</p>
<p>Now everything is up again but you can also get the update site at this
address:
<a href="http://api.openoffice.org/Projects/EclipseIntegration/dev-update/site.xml">http://api.openoffice.org/Projects/EclipseIntegration/dev-update/site.xml</a>. </p>Generating UML diagrams from Java code2007-12-07T12:01:00+01:002007-12-07T12:01:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-12-07:/generating-uml-diagrams-from-java-code.html<p>This morning I was browsing the <code>Javadoc</code> FAQ for some
information, and I found an other really interesting one. <code>Javadoc</code> is a
tool which is mostly know for Java code API documentation generation.
However, you can change the result of <code>Javadoc</code> by setting different
doclets. A <strong>doclet</strong> is a Java …</p><p>This morning I was browsing the <code>Javadoc</code> FAQ for some
information, and I found an other really interesting one. <code>Javadoc</code> is a
tool which is mostly know for Java code API documentation generation.
However, you can change the result of <code>Javadoc</code> by setting different
doclets. A <strong>doclet</strong> is a Java library used by <code>Javadoc</code> to render the
parsed informations.</p>
<p><a href="http://www.umlgraph.org/">UMLGraph</a> is a wonderful doclet generating a <a href="http://www.graphviz.org/">Graphviz</a> file to be
used for UML diagrams creations. Simply have a look at the UMLGraph user
documentation (really complete) for more informations on the doclet
usage.</p>
<p>I'll let you know when I'll have a simple example to
show...</p>Quality for the OOEclipseIntegration2007-11-25T22:37:00+01:002007-11-25T22:37:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-11-25:/quality-for-the-ooeclipseintegration.html<p>I was working very slowly during the last weeks on a major
code cleaning of the OOo Eclipse integration. I did it using
<a href="http://checkstyle.sourceforge.net/">checkstyle</a> rules and the <a href="http://eclipse-cs.sourceforge.net/">eclipse-cs</a> plugin. These rules are
including some importants points like:</p>
<ul>
<li>code complexity</li>
<li>header presence verification</li>
<li>naming conventions checks</li>
<li>Javadoc checks.</li>
</ul>
<p>I was very …</p><p>I was working very slowly during the last weeks on a major
code cleaning of the OOo Eclipse integration. I did it using
<a href="http://checkstyle.sourceforge.net/">checkstyle</a> rules and the <a href="http://eclipse-cs.sourceforge.net/">eclipse-cs</a> plugin. These rules are
including some importants points like:</p>
<ul>
<li>code complexity</li>
<li>header presence verification</li>
<li>naming conventions checks</li>
<li>Javadoc checks.</li>
</ul>
<p>I was very impressed to see the complex methods I had written... and it
was so complex that it took a long time to simplify them correctly. Now
the code is much better and can welcome new developers
;)</p>UNO services constructors2007-11-25T20:36:00+01:002007-11-25T20:36:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-11-25:/uno-services-constructors.html<p>I have already read about the new-style UNO services
constructors, but I had never used them. Last week I discovered the
power hidden in this tiny UNO improvement. Let's consider the following
service specification:</p>
<div class="highlight"><pre><span></span><code>module org { module openoffice { module test {
service Customer <span class="o">:</span> XCustomer {
Customer( [in] <span class="nb">string</span> customerId );
};
}; }; };
</code></pre></div>
<p>To implement such …</p><p>I have already read about the new-style UNO services
constructors, but I had never used them. Last week I discovered the
power hidden in this tiny UNO improvement. Let's consider the following
service specification:</p>
<div class="highlight"><pre><span></span><code>module org { module openoffice { module test {
service Customer <span class="o">:</span> XCustomer {
Customer( [in] <span class="nb">string</span> customerId );
};
}; }; };
</code></pre></div>
<p>To implement such a service we will need to add the
<code>com::sun::star::lang::XInitialization</code> interface to the service
inherited interfaces. The service interface could look like this:</p>
<div class="highlight"><pre><span></span><code>module org { module openoffice { module test {
interface XCustomer <span class="o">:</span> com<span class="o">::</span>sun<span class="o">::</span>star<span class="o">::</span>lang<span class="o">::</span>XInitialization {
[attribute, readonly] <span class="nb">string</span> Id;
};
}; }; };
</code></pre></div>
<p>Then the UNO constructor of the service will be implemented in the
<code>initialize()</code> method specified by the <code>XInitialization</code> interface. Then
the implementation could be like the following in Java:</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span> <span class="kt">void</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">Object</span><span class="o">[]</span> <span class="n">pArgs</span><span class="p">)</span> <span class="kd">throws</span> <span class="n">com</span><span class="p">.</span><span class="na">sun</span><span class="p">.</span><span class="na">star</span><span class="p">.</span><span class="na">uno</span><span class="p">.</span><span class="na">Exception</span> <span class="p">{</span>
<span class="n">String</span> <span class="n">id</span> <span class="o">=</span> <span class="n">args</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">;</span>
<span class="c1">// Do the initialization from the Customer's database (for example)</span>
<span class="p">}</span>
</code></pre></div>
<p>Then to use the service constructor, it's easy in Java:</p>
<div class="highlight"><pre><span></span><code><span class="n">Customer</span> <span class="n">johnDoe</span> <span class="o">=</span> <span class="n">Customer</span><span class="p">.</span><span class="na">Customer</span><span class="p">(</span><span class="s">"johndoe"</span><span class="p">);</span>
</code></pre></div>
<p>To use the constructor in Basic it's slightly more complicated because
you will need to create the service with arguments. It should look like
this:</p>
<div class="highlight"><pre><span></span><code><span class="err">oServiceManager = getProcessServiceManager()</span>
<span class="err">oCustomer = oServiceManager.createInstanceWithArguments("org.openoffice.test.Customer", "johndoe")</span>
</code></pre></div>
<p>This could seem trivial for any common object-oriented language
programmer like Java, C++, but for UNO it's a big step. I hope this
could help someone to better know UNO. </p>Handling URL in OOo2007-11-23T12:07:00+01:002007-11-23T12:07:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-11-23:/handling-url-in-ooo.html<p>As I'm usually using the OOo API from Basic code, I'm using
the <code>convertToUrl()</code> and <code>convertFromUrl()</code> Basic functions to handle
URLs. The problem is that I had to do the same in Java extension. Of
course, the <code>toExternalString()</code> method of a Java URL object doesn't
return an OOo internal URL …</p><p>As I'm usually using the OOo API from Basic code, I'm using
the <code>convertToUrl()</code> and <code>convertFromUrl()</code> Basic functions to handle
URLs. The problem is that I had to do the same in Java extension. Of
course, the <code>toExternalString()</code> method of a Java URL object doesn't
return an OOo internal URL usable in method like
<code>loadComponentFromUrl()</code>.</p>
<p>Hopefully, I found out the <a href="http://api.openoffice.org/docs/common/ref/com/sun/star/uri/ExternalUriReferenceTranslator.html"><code>ExternalUriReferenceTranslator</code></a> service
which convert between OOo internal URLs and normal URLs. Here is a code
sample which could help to see how it works.</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span> <span class="kd">static</span> <span class="n">String</span> <span class="nf">convertToUrl</span><span class="p">(</span><span class="n">String</span> <span class="n">pFilePath</span><span class="p">,</span> <span class="n">XComponentContext</span> <span class="n">pComponentContext</span> <span class="p">)</span> <span class="kd">throws</span> <span class="n">MalformedURLException</span> <span class="p">{</span>
<span class="n">String</span> <span class="n">internalUrl</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="n">URL</span> <span class="n">externalUrl</span> <span class="o">=</span> <span class="k">new</span> <span class="n">File</span><span class="p">(</span><span class="n">pFilePath</span><span class="p">).</span><span class="na">toURL</span><span class="p">();</span>
<span class="n">XExternalUriReferenceTranslator</span> <span class="n">translator</span> <span class="o">=</span> <span class="n">ExternalUriReferenceTranslator</span><span class="p">.</span><span class="na">create</span><span class="p">(</span>
<span class="n">pComponentContext</span><span class="p">);</span>
<span class="n">internalUrl</span> <span class="o">=</span> <span class="n">translator</span><span class="p">.</span><span class="na">translateToInternal</span><span class="p">(</span><span class="n">externalUrl</span><span class="p">.</span><span class="na">toExternalForm</span><span class="p">());</span>
<span class="k">return</span> <span class="n">internalUrl</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>Debugging an OOo extension with Eclipse2007-11-20T12:31:00+01:002007-11-20T12:31:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-11-20:/debugging-an-ooo-extension-with-eclipse.html<p>Every developer needs a way to debug its applications. It goes
the same way for OpenOffice.org Java extensions. At the OOoCon 2008 in
Barcelona, Steffen Grund explained me how he integrated OOo Java
extensions debugging in the Netbeans plugin. Even if it was very
interesting, I only had time …</p><p>Every developer needs a way to debug its applications. It goes
the same way for OpenOffice.org Java extensions. At the OOoCon 2008 in
Barcelona, Steffen Grund explained me how he integrated OOo Java
extensions debugging in the Netbeans plugin. Even if it was very
interesting, I only had time to do it with Eclipse and here is how to do
it.</p>
<h3>Configuring OpenOffice.org</h3>
<p>First, you need to add parameters to the JVM started by OpenOffice.org.
The parameters are:</p>
<ul>
<li><code>-Xdebug</code></li>
<li><code>-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n</code></li>
</ul>
<p>To change them, open the OOo <strong>options</strong> dialog and then the <strong>Java</strong>
configuration item.<br>
Click on the <strong>Parameters</strong> button and add the parameters.</p>
<p>In order to apply the parameters, you need to restart OOo (the
quickstarter too). These parameters will make OpenOffice.org JVM listen
on the 8000 port of the local machine.</p>
<h3>Starting the debug mode from Eclipse</h3>
<p>Open the <strong>Run > Open Debug Dialog</strong> menu.<br>
Create a new Remote Java Application with the following parameters:</p>
<ul>
<li>Connection type: Standard (Socket Attach)</li>
<li>Host: localhost</li>
<li>Port: 8000</li>
<li>Sources: your project directory should be selected</li>
</ul>
<p>Then run the extension from OpenOffice.org (using a Basic macro or
anything else) and then start the newly created debug configuration. It
may be possible that the connection can't be fetched at the first time
because OOo starts the JVM only when it's needed. After a first run, the
started JVM won't be stopped and the port will still be opened.</p>
<h3>Tips & Tricks</h3>
<ul>
<li>Don't forget to add the breakpoints in your code before exporting
it, otherwise they won't be taken into account at the runtime.</li>
<li>You will need to close OpenOffice.org (the quickstarter too) when
exporting the package from Eclipse or you will get an error telling
you that the 8000 port is already in use.</li>
<li>You can change the port to something else than 8000 of course,
change it in the OOo JVM parameters and in the Eclipse Debug
configuration</li>
</ul>List of file types handled by OpenOffice.org2007-11-05T12:32:00+01:002007-11-05T12:32:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-11-05:/list-of-file-types-handled-by-openofficeorg.html<p>I recently wanted to get the list of all file types handled by
OpenOffice.org using the API. Of course I wanted to get their
internationalized names. I discovered a very interesting service while
browsing the API reference: <a href="http://api.openoffice.org/docs/common/ref/com/sun/star/document/TypeDetection.html"><code>com.sun.star.document.TypeDetection</code></a>.
Here is a sample of StarBasic code …</p><p>I recently wanted to get the list of all file types handled by
OpenOffice.org using the API. Of course I wanted to get their
internationalized names. I discovered a very interesting service while
browsing the API reference: <a href="http://api.openoffice.org/docs/common/ref/com/sun/star/document/TypeDetection.html"><code>com.sun.star.document.TypeDetection</code></a>.
Here is a sample of StarBasic code getting the names of the file types.</p>
<div class="highlight"><pre><span></span><code><span class="n">Sub</span> <span class="n">TestTypes</span>
<span class="n">oTypeDetection</span> <span class="o">=</span> <span class="n">createUnoService</span><span class="p">(</span> <span class="ss">"com.sun.star.document.TypeDetection"</span> <span class="p">)</span>
<span class="n">aNames</span> <span class="o">=</span> <span class="n">oTypeDetection</span><span class="p">.</span><span class="n">ElementNames</span>
<span class="n">sTypes</span> <span class="o">=</span> <span class="ss">""</span>
<span class="k">For</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">To</span> <span class="n">UBound</span><span class="p">(</span> <span class="n">aNames</span> <span class="p">)</span>
<span class="n">oType</span> <span class="o">=</span> <span class="n">oTypeDetection</span><span class="p">.</span><span class="n">getByName</span><span class="p">(</span> <span class="n">aNames</span><span class="p">(</span> <span class="n">i</span> <span class="p">)</span> <span class="p">)</span>
<span class="n">sTypes</span> <span class="o">=</span> <span class="n">sTypes</span> <span class="o">&</span> <span class="n">getUIName</span><span class="p">(</span> <span class="n">oType</span> <span class="p">)</span> <span class="o">&</span> <span class="n">chr</span><span class="p">(</span> <span class="mi">10</span> <span class="p">)</span>
<span class="k">Next</span> <span class="n">i</span>
<span class="n">MsgBox</span> <span class="n">sTypes</span>
<span class="k">End</span> <span class="n">Sub</span>
<span class="k">Function</span> <span class="n">getUIName</span><span class="p">(</span> <span class="n">oType</span> <span class="k">As</span> <span class="n">Variant</span> <span class="p">)</span>
<span class="n">sName</span> <span class="o">=</span> <span class="ss">""</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">While</span> <span class="p">(</span> <span class="n">sName</span> <span class="o">=</span> <span class="ss">""</span> <span class="k">And</span> <span class="n">i</span> <span class="o"><=</span> <span class="n">UBound</span><span class="p">(</span> <span class="n">oType</span> <span class="p">)</span> <span class="p">)</span>
<span class="k">If</span> <span class="p">(</span> <span class="n">oType</span><span class="p">(</span> <span class="n">i</span> <span class="p">).</span><span class="n">Name</span> <span class="o">=</span> <span class="ss">"UIName"</span> <span class="p">)</span> <span class="k">Then</span>
<span class="n">sName</span> <span class="o">=</span> <span class="n">oType</span><span class="p">(</span> <span class="n">i</span> <span class="p">).</span><span class="n">Value</span>
<span class="k">End</span> <span class="k">If</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="n">Wend</span>
<span class="n">getUIName</span><span class="p">(</span> <span class="p">)</span> <span class="o">=</span> <span class="n">sName</span>
<span class="k">End</span> <span class="k">Function</span>
</code></pre></div>
<p>I hope that this could help you. </p>Wordpress easy configuration2007-05-06T11:03:00+02:002007-05-06T11:03:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-05-06:/wordpress-easy-configuration.html<p>As you might know, Wordpress is really to setup and use.
However you need to add some PHP code to your theme for many plugins...
including the Original one. A few days ago, I discovered a fantastic
wordpress plugin: <a href="http://automattic.com/code/widgets/">widget</a>, helping users to configure the appearance
of their blog's sidebar …</p><p>As you might know, Wordpress is really to setup and use.
However you need to add some PHP code to your theme for many plugins...
including the Original one. A few days ago, I discovered a fantastic
wordpress plugin: <a href="http://automattic.com/code/widgets/">widget</a>, helping users to configure the appearance
of their blog's sidebar. If other plugins declare their UI additions as
widgets, then the user can drag & drop them in the widget list to change
his sidebar.</p>
<p>Then I took some minutes to widgetize the Original plugin... and the
changes will be available in the next version of the plugin. Thus, stay
tuned... </p>The Gecko and the Gull2007-05-04T08:22:00+02:002007-05-04T08:22:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-05-04:/the-gecko-and-the-gull.html<p>Is it a unknown fable from La Fontaine? Not really, in fact it
has more to do about OpenOffice.org and Mozilla. I was trying to tamper
with some web pages and I wanted to check whether we could integrate
easily a small web-browser inside OpenOffice.org.</p>
<p>Hopefully, there is …</p><p>Is it a unknown fable from La Fontaine? Not really, in fact it
has more to do about OpenOffice.org and Mozilla. I was trying to tamper
with some web pages and I wanted to check whether we could integrate
easily a small web-browser inside OpenOffice.org.</p>
<p>Hopefully, there is an interesting feature coming up with Eclipse 3.3
which helps a lot: <a href="http://download.eclipse.org/eclipse/downloads/drops/S-3.3M6-200703231616/eclipse-news-M6.html">SWT provides the ability to create a Browser</a>
composite which runs the <a href="http://en.wikipedia.org/wiki/XULRunner">xulrunner</a> (<a href="ftp://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/1.8.1.3/contrib/">downloads</a>). This means that
we could perfectly imagine a small Java extension to OpenOffice.org
which provides a UNO service to show any XUL or HTML page.</p>
<p>Here is a small snippet I created to test this on windows:</p>
<div class="highlight"><pre><span></span><code><span class="n">Display</span> <span class="n">display</span> <span class="o">=</span> <span class="n">Display</span><span class="p">.</span><span class="na">getDefault</span><span class="p">();</span>
<span class="kd">final</span> <span class="n">Shell</span> <span class="n">shell</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Shell</span><span class="p">(</span><span class="n">display</span><span class="p">);</span>
<span class="n">shell</span><span class="p">.</span><span class="na">setText</span><span class="p">(</span><span class="s">"My OOo Browser"</span><span class="p">);</span>
<span class="n">shell</span><span class="p">.</span><span class="na">setSize</span><span class="p">(</span><span class="mi">400</span><span class="p">,</span> <span class="mi">300</span><span class="p">);</span>
<span class="n">shell</span><span class="p">.</span><span class="na">setLayout</span><span class="p">(</span><span class="k">new</span> <span class="n">GridLayout</span><span class="p">());</span>
<span class="n">System</span><span class="p">.</span><span class="na">setProperty</span><span class="p">(</span><span class="s">"org.eclipse.swt.browser.XULRunnerPath"</span><span class="p">,</span>
<span class="s">"C:\\Documents and Settings\\Cbosdonnat\\Mes documents\\xulrunner"</span><span class="p">);</span>
<span class="n">Browser</span> <span class="n">browser</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Browser</span><span class="p">(</span><span class="n">shell</span><span class="p">,</span> <span class="n">SWT</span><span class="p">.</span><span class="na">MOZILLA</span><span class="p">);</span>
<span class="n">browser</span><span class="p">.</span><span class="na">setLayoutData</span><span class="p">(</span><span class="k">new</span> <span class="n">GridData</span><span class="p">(</span><span class="n">GridData</span><span class="p">.</span><span class="na">FILL_BOTH</span><span class="p">));</span>
<span class="n">browser</span><span class="p">.</span><span class="na">setUrl</span><span class="p">(</span><span class="s">"http://fr.openoffice.org"</span><span class="p">);</span>
<span class="n">shell</span><span class="p">.</span><span class="na">open</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">shell</span><span class="p">.</span><span class="na">isDisposed</span> <span class="p">())</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">display</span><span class="p">.</span><span class="na">readAndDispatch</span> <span class="p">())</span> <span class="n">display</span><span class="p">.</span><span class="na">sleep</span> <span class="p">();</span>
<span class="p">}</span>
<span class="n">display</span><span class="p">.</span><span class="na">dispose</span> <span class="p">();</span>
</code></pre></div>
<p>I let you imagine the kind of interesting applications we could do using
this... Of course the same principle is working on Linux and I would
like to test it on MacOS, but I let you translate the above code for
it. </p>Beryl and visually impaired persons2007-04-27T09:39:00+02:002007-04-27T09:39:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-04-27:/beryl-and-visually-impaired-persons.html<p>You will probably say that I'm about to write some stupid
thing about 3D effects and visually impaired persons. You are wrong:
Beryl can bring really useful features to the linux desktop for these
persons. Many of them need reversed colors and/or a magnifier on their
screen. Even if …</p><p>You will probably say that I'm about to write some stupid
thing about 3D effects and visually impaired persons. You are wrong:
Beryl can bring really useful features to the linux desktop for these
persons. Many of them need reversed colors and/or a magnifier on their
screen. Even if there already was Orca having these features on Linux,
they were not so good compared to what can be done with Beryl. Just
forget the 3D cubes and lovely effects, but try to play with <super> +
mouse wheel or <super> + m. Those shortcuts can magnify or reverse the
whole screen easily and let me think that we could find some usability
improvements for persons who have some difficulties to read on a screen.
Just see this screenshot, which is the copy of what I saw on my desktop
(it hasn't been cut afterwards).</p>
<p><img alt="Beryl magnified screenshot" src="https://bosdonnat.fr/data/screenshots/desk-reverse-mag.png"> </p>A panorama from Lyon2007-04-15T16:32:00+02:002007-04-15T16:32:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-04-15:/a-panorama-from-lyon.html<p>Yesterday afternoon we were walking in the center of Lyon. Hopefully we
had the digital camera to take some shots of the beautiful colors of
Lyon when the sun starts lowering in the sky. I created a panorama using
<a href="http://hugin.sourceforge.net/">Hugin</a> from 11 pictures: just see why Lyon is a beautiful …</p><p>Yesterday afternoon we were walking in the center of Lyon. Hopefully we
had the digital camera to take some shots of the beautiful colors of
Lyon when the sun starts lowering in the sky. I created a panorama using
<a href="http://hugin.sourceforge.net/">Hugin</a> from 11 pictures: just see why Lyon is a beautiful city!</p>
<p><a href="https://bosdonnat.fr/data/photos/saone-small.png"><img alt="Saône river late in the afternoon" src="https://bosdonnat.fr/data/photos/saone-xsmall.png"></a></p>
<p><a href="https://bosdonnat.fr/data/photos/saone.png">Hight quality</a></p>Crossing the desert2007-04-06T10:56:00+02:002007-04-06T10:56:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-04-06:/crossing-the-desert.html<p>Yesterday, with some friends, we went discovering new games.
We played in an association who owns a lot of author games. One of the
most well known is <strong>the Settlers of Catan</strong> which inspired a free
computer game: <a href="http://pio.sourceforge.net/">pioneers</a>. Yesterday evening we played two interesting
games: <strong>Carcassonne</strong> and <strong>La Traversée …</strong></p><p>Yesterday, with some friends, we went discovering new games.
We played in an association who owns a lot of author games. One of the
most well known is <strong>the Settlers of Catan</strong> which inspired a free
computer game: <a href="http://pio.sourceforge.net/">pioneers</a>. Yesterday evening we played two interesting
games: <strong>Carcassonne</strong> and <strong>La Traversée du Désert</strong>. Here are some
notes on those games.</p>
<p><strong><a href="http://fr.wikipedia.org/wiki/Carcassonne_(jeu)">Carcassone (fr)</a></strong>: a really good game, but I recommend to use some
variants of the rules. To avoid big unfinished constructions, only the
finished elements are counted. To reduce the amount of randomness, we
have chosen to have 3 cards in hand every time instead of one. That
makes the game even better, playing during approximately 45 minutes.</p>
<p><strong><a href="http://fr.wikipedia.org/wiki/La_Travers%C3%A9e_du_d%C3%A9sert">La traversée du Désert (fr)</a></strong>: a game where you have to place your
dromedaries to gain water and oasis and block the enemies. Interesting
quick game with beautiful pieces, it's a bit long to read the rules and
prepare the game. However it should be much better for the next games:
the games mechanic is really easy to understand.</p>Interesting OpenDocument libraries2007-04-05T09:51:00+02:002007-04-05T09:51:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-04-05:/interesting-opendocument-libraries.html<p>By reading the OpenOffice.org mailing lists this morning, I
found out two useful Java libraries handling OpenDocument. These needs
to be investigated, but they seem to be <a href="http://www.artofsolving.com/opensource/jodconverter/adoption">used by big open source
products</a>.</p>
<ul>
<li><a href="http://www.artofsolving.com/opensource/jodconverter">JODConverter</a></li>
<li><a href="http://www.artofsolving.com/opensource/jodreports">JODReports</a></li>
</ul>
<p>The topic on the mailing list was to see whether the ODF Toolkit could …</p><p>By reading the OpenOffice.org mailing lists this morning, I
found out two useful Java libraries handling OpenDocument. These needs
to be investigated, but they seem to be <a href="http://www.artofsolving.com/opensource/jodconverter/adoption">used by big open source
products</a>.</p>
<ul>
<li><a href="http://www.artofsolving.com/opensource/jodconverter">JODConverter</a></li>
<li><a href="http://www.artofsolving.com/opensource/jodreports">JODReports</a></li>
</ul>
<p>The topic on the mailing list was to see whether the ODF Toolkit could
be interesting for those libraries... to be followed. </p>Booking a hotel using the net2007-03-29T10:13:00+02:002007-03-29T10:13:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2007-03-29:/booking-a-hotel-using-the-net.html<p>Last week, I had to go for some days in Rennes. To book a hotel there,
I used the Mappy services to locate hotels near the town center. The
problem is that when Mappy can't find an address in a city, it locates
it near the town hall. Thus I …</p><p>Last week, I had to go for some days in Rennes. To book a hotel there,
I used the Mappy services to locate hotels near the town center. The
problem is that when Mappy can't find an address in a city, it locates
it near the town hall. Thus I found a not-too-expensive hotel near the
town hall: that was what I expected. However when I arrived there, 21h00
in a cold day, I couldn't find the hotel where it was indicated by
Mappy. The problem is that the hotel was 20 minutes far from the city
center by bus... It took me 2h30 to find the correct place of the hotel
and I found it in an industrial zone with nothing around.</p>
<p>The conclusion of this really bad experience is: do not use Mappy-like
services to locate a hotel: better prefer the good old yellow pages and
a real map. By the way some other maps are better and simply tell you
that there is no result for the asked address: at least they are honest
! </p>A wonderful week-end2007-03-12T23:37:00+01:002007-03-12T23:37:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-03-12:/a-wonderful-week-end.html<p>During two days, my fiancee and I have decided to make a break
in a our hight-speed rhythm of life. This break was the occasion for us
to think about our coming wedding. More precisely to think about the
christian wedding and the reasons who leads us to get married …</p><p>During two days, my fiancee and I have decided to make a break
in a our hight-speed rhythm of life. This break was the occasion for us
to think about our coming wedding. More precisely to think about the
christian wedding and the reasons who leads us to get married at the
Church. For this we have participated to a week-end organized by <a href="http://www.chemin-neuf.org/CANA/">CANA
(fr)</a>.</p>
<p>A friendly welcome, interesting testimonies from couples married for
some years, times for reflection (alone then in couple), prayers, all
these made a calm week-end which helped us to grow. I really recommend
these sessions to all the couples having questions about the christian
wedding: this helps you to understand the meaning of the wedding and the
place of God in the couple.</p>
<p>There we have been told about an interesting book that could be added in
the <a href="https://bosdonnat.fr/pages/le-mariage-chretien.html">Christian wedding (fr)</a> page of this website:<br>
<strong>Les langages de l'amour</strong>, <em>by Gary Chapman</em> <a href="http://www.amazon.fr/langages-lamour-Gary-Chapman/dp/2863141929">(fr)</a></p>uno-skeletonmaker and multiple services2007-03-08T14:14:00+01:002007-03-08T14:14:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-03-08:/uno-skeletonmaker-and-multiple-services.html<p>Yesterday evening, I tried to find a way to register several
UNO services implementations using <code>regcomp</code>. The problem is that the
implementations have all been created using the <code>uno-skeletonmaker</code> tool
and contained each their own static registration methods. However there
was nothing to register all the services implementations in the …</p><p>Yesterday evening, I tried to find a way to register several
UNO services implementations using <code>regcomp</code>. The problem is that the
implementations have all been created using the <code>uno-skeletonmaker</code> tool
and contained each their own static registration methods. However there
was nothing to register all the services implementations in the same
<code>jar</code> file.</p>
<p>This has lead me to write a class that will later be used in the Eclipse
integration to help the users implement new services easily. Thus in the
next version of the Eclipse integration, creating a new service will
also imply to create its implementation skeleton and prepare it for
<code>regcomp</code> </p>
<p>For those interested in the class I wrote for the registration of the
services implementations, here is the code. As you can understand from
the code, the implementation classes names are stored in a
<code>RegistrationHandler.classes</code> file: one class name by line.</p>
<div class="highlight"><pre><span></span><code><span class="kn">package</span> <span class="nn">org.openoffice.test.comp</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.io.IOException</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.io.InputStream</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.io.InputStreamReader</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.io.LineNumberReader</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.lang.reflect.Method</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">java.util.ArrayList</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">com.sun.star.lang.XSingleComponentFactory</span><span class="p">;</span>
<span class="kn">import</span> <span class="nn">com.sun.star.registry.XRegistryKey</span><span class="p">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">RegistrationHandler</span> <span class="p">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">XSingleComponentFactory</span> <span class="nf">__getComponentFactory</span><span class="p">(</span>
<span class="n">String</span> <span class="n">sImplementationName</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">XSingleComponentFactory</span> <span class="n">xFactory</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">classes</span> <span class="o">=</span> <span class="n">findServicesImplementationClasses</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="n">classes</span><span class="p">.</span><span class="na">length</span> <span class="o">&&</span> <span class="n">xFactory</span> <span class="o">==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="n">Class</span> <span class="n">clazz</span> <span class="o">=</span> <span class="n">classes</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span> <span class="n">sImplementationName</span><span class="p">.</span><span class="na">equals</span><span class="p">(</span> <span class="n">clazz</span><span class="p">.</span><span class="na">getCanonicalName</span><span class="p">()</span> <span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">getTypes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span><span class="p">{</span><span class="n">String</span><span class="p">.</span><span class="na">class</span><span class="p">};</span>
<span class="n">Method</span> <span class="n">getFactoryMethod</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="na">getMethod</span><span class="p">(</span>
<span class="s">"__getComponentFactory"</span><span class="p">,</span> <span class="n">getTypes</span><span class="p">);</span>
<span class="n">Object</span> <span class="n">o</span> <span class="o">=</span> <span class="n">getFactoryMethod</span><span class="p">.</span><span class="na">invoke</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="n">sImplementationName</span><span class="p">);</span>
<span class="n">xFactory</span> <span class="o">=</span> <span class="p">(</span><span class="n">XSingleComponentFactory</span><span class="p">)</span><span class="n">o</span><span class="p">;</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Nothing to do: skip</span>
<span class="n">System</span><span class="p">.</span><span class="na">err</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"Error happened"</span><span class="p">);</span>
<span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">xFactory</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">boolean</span> <span class="nf">__writeRegistryServiceInfo</span><span class="p">(</span><span class="n">XRegistryKey</span> <span class="n">xRegistryKey</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">classes</span> <span class="o">=</span> <span class="n">findServicesImplementationClasses</span><span class="p">();</span>
<span class="kt">boolean</span> <span class="n">success</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="n">classes</span><span class="p">.</span><span class="na">length</span> <span class="o">&&</span> <span class="n">success</span><span class="p">)</span> <span class="p">{</span>
<span class="n">Class</span> <span class="n">clazz</span> <span class="o">=</span> <span class="n">classes</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">;</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">writeTypes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span><span class="p">{</span><span class="n">XRegistryKey</span><span class="p">.</span><span class="na">class</span><span class="p">};</span>
<span class="n">Method</span> <span class="n">getFactoryMethod</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="na">getMethod</span><span class="p">(</span>
<span class="s">"__writeRegistryServiceInfo"</span><span class="p">,</span> <span class="n">writeTypes</span><span class="p">);</span>
<span class="n">Object</span> <span class="n">o</span> <span class="o">=</span> <span class="n">getFactoryMethod</span><span class="p">.</span><span class="na">invoke</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="n">xRegistryKey</span><span class="p">);</span>
<span class="n">success</span> <span class="o">=</span> <span class="n">success</span> <span class="o">&&</span> <span class="p">((</span><span class="n">Boolean</span><span class="p">)</span><span class="n">o</span><span class="p">).</span><span class="na">booleanValue</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">success</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">success</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="n">Class</span><span class="o">[]</span> <span class="nf">findServicesImplementationClasses</span><span class="p">()</span> <span class="p">{</span>
<span class="n">ArrayList</span><span class="o"><</span><span class="n">Class</span><span class="o">></span> <span class="n">classes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o"><</span><span class="n">Class</span><span class="o">></span><span class="p">();</span>
<span class="n">InputStream</span> <span class="n">in</span> <span class="o">=</span> <span class="n">RegistrationHandler</span><span class="p">.</span><span class="na">class</span><span class="p">.</span>
<span class="nf">getResourceAsStream</span><span class="p">(</span><span class="s">"RegistrationHandler.classes"</span><span class="p">);</span>
<span class="n">LineNumberReader</span> <span class="n">reader</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LineNumberReader</span><span class="p">(</span><span class="k">new</span> <span class="n">InputStreamReader</span><span class="p">(</span><span class="n">in</span><span class="p">));</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">String</span> <span class="n">line</span> <span class="o">=</span> <span class="n">reader</span><span class="p">.</span><span class="na">readLine</span><span class="p">();</span>
<span class="k">while</span> <span class="p">(</span><span class="n">line</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">line</span><span class="p">.</span><span class="na">equals</span><span class="p">(</span><span class="s">""</span><span class="p">))</span> <span class="p">{</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="p">.</span><span class="na">trim</span><span class="p">();</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">Class</span> <span class="n">clazz</span> <span class="o">=</span> <span class="n">Class</span><span class="p">.</span><span class="na">forName</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">writeTypes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span><span class="p">{</span><span class="n">XRegistryKey</span><span class="p">.</span><span class="na">class</span><span class="p">};</span>
<span class="n">Class</span><span class="o">[]</span> <span class="n">getTypes</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Class</span><span class="o">[]</span><span class="p">{</span><span class="n">String</span><span class="p">.</span><span class="na">class</span><span class="p">};</span>
<span class="n">Method</span> <span class="n">writeRegMethod</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="na">getMethod</span><span class="p">(</span>
<span class="s">"__writeRegistryServiceInfo"</span><span class="p">,</span> <span class="n">writeTypes</span><span class="p">);</span>
<span class="n">Method</span> <span class="n">getFactoryMethod</span> <span class="o">=</span> <span class="n">clazz</span><span class="p">.</span><span class="na">getMethod</span><span class="p">(</span>
<span class="s">"__getComponentFactory"</span><span class="p">,</span> <span class="n">getTypes</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">writeRegMethod</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&&</span> <span class="n">getFactoryMethod</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="n">classes</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">clazz</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">line</span> <span class="o">=</span> <span class="n">reader</span><span class="p">.</span><span class="na">readLine</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">IOException</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="n">reader</span><span class="p">.</span><span class="na">close</span><span class="p">();</span>
<span class="n">in</span><span class="p">.</span><span class="na">close</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{};</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">classes</span><span class="p">.</span><span class="na">toArray</span><span class="p">(</span><span class="k">new</span> <span class="n">Class</span><span class="o">[</span><span class="n">classes</span><span class="p">.</span><span class="na">size</span><span class="p">()</span><span class="o">]</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>Making beautiful photos2007-02-24T21:17:00+01:002007-02-24T21:17:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-02-24:/making-beautiful-photos.html<p>This afternoon, I found out by pure chance the blog of an old
friend. My reading stopped on two really interesting articles on <a href="http://r0ug3.dyndns.org/dotclear/index.php/post/2007/02/08/Pyramide-louvre-HDR">HDR
photos</a> and <a href="http://r0ug3.dyndns.org/dotclear/index.php/post/2007/02/18/Photo-Cadrage">centering photos correctly</a>.</p>
<p>Thus I tried to find more informations on HDR photos and how to create
them. This has lead me to an …</p><p>This afternoon, I found out by pure chance the blog of an old
friend. My reading stopped on two really interesting articles on <a href="http://r0ug3.dyndns.org/dotclear/index.php/post/2007/02/08/Pyramide-louvre-HDR">HDR
photos</a> and <a href="http://r0ug3.dyndns.org/dotclear/index.php/post/2007/02/18/Photo-Cadrage">centering photos correctly</a>.</p>
<p>Thus I tried to find more informations on HDR photos and how to create
them. This has lead me to an <a href="http://turtle.as.arizona.edu/jdsmith/exposure_blend.php">interesting Gimp script</a> and I made some
tests:</p>
<p><a href="https://bosdonnat.fr/data/photos/HDR-photos.png"><img alt="HDR photo and the original photos" src="https://bosdonnat.fr/data/photos/HDR-photos.png"></a></p>
<p>The photos 1, 2 and 3 are the original photos where we can see several
different details, and the HDR photo is the one produced by the gimp
script after some layers handling (because I have moved a little between
the photos). Now I should try to make real photos like this. </p>
<p><a href="https://bosdonnat.fr/data/HDR-test.zip">HDR-test.zip</a></p>OOEclipseIntegration: subcomponent in IZ2007-02-06T21:49:00+01:002007-02-06T21:49:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-02-06:/ooeclipseintegration-subcomponent-in-iz.html<p>Now OOEclipseIntegration bugs will have to be filed on IZ, Component:
<strong>sdk</strong>, Subcomponent: <strong>eclipse-integration</strong>. This new step in the
project development will help to split the work between different
developers (when there will be more) and to keep a track of the bugs. IZ
has probably a better memory of …</p><p>Now OOEclipseIntegration bugs will have to be filed on IZ, Component:
<strong>sdk</strong>, Subcomponent: <strong>eclipse-integration</strong>. This new step in the
project development will help to split the work between different
developers (when there will be more) and to keep a track of the bugs. IZ
has probably a better memory of the issues than me.</p>
<p>Adding a new issue:
<a href="http://qa.openoffice.org/issues/enter_bug.cgi?component=sdk">http://qa.openoffice.org/issues/enter_bug.cgi?component=sdk</a></p>Conf at SolutionLinux, slides2007-02-02T10:38:00+01:002007-02-02T10:38:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-02-02:/conf-at-solutionlinux-slides.html<p>Wednesday evening, I presented the Eclipse Integration plugin
for OpenOffice.org at Solution Linux in Paris. The room wasn't full, but
I had some interesting contacts. For those who are interested in the
slides, you can download them from here even if you may have to
translate them from french …</p><p>Wednesday evening, I presented the Eclipse Integration plugin
for OpenOffice.org at Solution Linux in Paris. The room wasn't full, but
I had some interesting contacts. For those who are interested in the
slides, you can download them from here even if you may have to
translate them from french.</p>
<p><a href="https://bosdonnat.fr/data/SL2007-OOEclipse.odp">The slides</a></p>OOEclipseIntegration on EclipsePluginCentral2007-02-01T16:20:00+01:002007-02-01T16:20:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-02-01:/ooeclipseintegration-on-eclipseplugincentrall.html<p>At the conference on the OOEclipseIntegration yesterday at
SolutionLinux 2007 in Paris, someone recommended me to register the
project on <a href="http://www.eclipseplugincentral.com/">EclipsePluginCentral</a>. It's now done. Do not hesitate to
use it and give me your feedbacks.</p>
<p><a href="http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-870.html">http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-870.html</a></p>OpenOffice.org Eclipse Integration v1.1 released2007-01-16T13:31:00+01:002007-01-16T13:31:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2007-01-16:/openofficeorg-eclipse-integration-v11-released.html<p>After a long time waiting for it, a new version of the
OpenOffice.org Eclipse Integration has just been released. There are
important new features and the existing wizards have been modified for a
better user experience. Just report to the relase notes below for more
details.</p>
<h2>Installation</h2>
<p>For fresh …</p><p>After a long time waiting for it, a new version of the
OpenOffice.org Eclipse Integration has just been released. There are
important new features and the existing wizards have been modified for a
better user experience. Just report to the relase notes below for more
details.</p>
<h2>Installation</h2>
<p>For fresh installations or updates, please use this <a href="/ooeclipseintegration/">update site</a> from
your Eclipse installation:</p>
<h2>Release notes</h2>
<ul>
<li>Integration of the <em>uno-skeletonmaker</em> tool. The component wizard
now creates the basic implementation code for you: you only have to
concentrate on your code.</li>
<li>UNO package export wizard: this wizard build your code and package
it properly for use as an OpenOffice.org extension. The wizard even
proposes to deploy the freshly created extension on your
OpenOffice.org instance.</li>
<li>Tools for the creation of URE applications. This includes a wizard
generating the skeleton of the application, the support of a new
launch configuration to run the application easily from Eclipse.</li>
<li>The component creation wizard now let you define your own interface
for your service</li>
<li>The interface configuration page in both interface and component
wizards let you define the interface methods and properties</li>
<li>Of course, the on-line documentation has been update to the new
features. However a new URE application tutorial has been added as
well as a document to help new developers to get introduced to the
integration development.</li>
</ul>uno-skeletonmaker in OOo Eclipse Integration2006-11-15T14:10:00+01:002006-11-15T14:10:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-11-15:/uno-skeletonmaker-in-ooo-eclipse-integration.html<p>I just have read <a href="http://blogs.sun.com/GullFOSS/entry/what%27s_new_in_the_sdk">this article from Jürgen</a> and would like to add
some explanations about the use of the uno-skeletonmaker in the Eclipse
integration. This is not already released and you need to build the
plugin from the sources to get it right now. However, there will be a …</p><p>I just have read <a href="http://blogs.sun.com/GullFOSS/entry/what%27s_new_in_the_sdk">this article from Jürgen</a> and would like to add
some explanations about the use of the uno-skeletonmaker in the Eclipse
integration. This is not already released and you need to build the
plugin from the sources to get it right now. However, there will be a
new release ASAP which will include the uno-skeletonmaker use. </p>Geek or not geek ?2006-11-12T20:41:00+01:002006-11-12T20:41:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-11-12:/geek-or-not-geek.html<p>There is a big while since my last post. In fact I took some time after
the OpenOffice.org conferences to have some non-geek activities. That's
part of why I'm not really active in the OpenOffice.org project these
last months.</p>
<p>Among my non-geek activities I really like cooking, but …</p><p>There is a big while since my last post. In fact I took some time after
the OpenOffice.org conferences to have some non-geek activities. That's
part of why I'm not really active in the OpenOffice.org project these
last months.</p>
<p>Among my non-geek activities I really like cooking, but not just pizzas
and noodles. What a pleasure to prepare some good meals and cakes for my
beloved darling. Some days ago, I had the idea to write some <em>"HOW-TO
learn cooking for Geeks"</em>. But I can't imagine how to do it... you just
have to read the manual. Here is a good one for french cooking:
<a href="http://www.letscookfrench.com">http://www.letscookfrench.com</a>. </p>A complete document template2006-10-30T12:39:00+01:002006-10-30T12:39:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-10-30:/a-complete-document-template.html<p>I just remembered that I still don't have brought back all the
content of my old wiki. Today, I'ld like to highlight an interesting
document... which was my first contribution to OpenOffice.org. It's a
writer document template to use in project documentation. I designed it
for a school project …</p><p>I just remembered that I still don't have brought back all the
content of my old wiki. Today, I'ld like to highlight an interesting
document... which was my first contribution to OpenOffice.org. It's a
writer document template to use in project documentation. I designed it
for a school project documentation quality management, but it can be
applied to many other circumstances. You can also have a look at this
document, because it contains interesting macros too.</p>
<p><a href="https://bosdonnat.fr/data/modeleprojet.ott">modeleprojet.ott</a></p>
<p><strong>Beware, the document is in french</strong></p>Press around the OOoCon20062006-09-19T15:26:00+02:002006-09-19T15:26:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-09-19:/press-around-the-ooocon2006.html<p>There were several journalists present at the OOoCon2006 last week.
They have spread the word around them to bring OpenOffice.org to
everyone. This article exposes some local TV grabs or newspapers. If you
found other articles about OOoCon2006 that aren't listed here, please
tell me: I'll add them.</p>
<p><strong>The …</strong></p><p>There were several journalists present at the OOoCon2006 last week.
They have spread the word around them to bring OpenOffice.org to
everyone. This article exposes some local TV grabs or newspapers. If you
found other articles about OOoCon2006 that aren't listed here, please
tell me: I'll add them.</p>
<p><strong>The videos can be read using any player supporting Theora and Vorbis,
eg: <a href="http://www.videolan.org">Videolan</a></strong> </p>
<p><a href="https://bosdonnat.fr/data/ooocon2006/20mn_Lyon_2006-09-11.jpg">20 minutes</a>
<a href="https://bosdonnat.fr/data/ooocon2006/metro1-2006-09-12.png">Metro #1</a>
<a href="https://bosdonnat.fr/data/ooocon2006/metro2-2006-09-12.png">Metro #2</a>
<a href="https://bosdonnat.fr/data/ooocon2006/Lyon-Capitale_2006-09-05.pdf">Lyon Capitale 2006-09-05</a>
<a href="https://bosdonnat.fr/data/ooocon2006/Lyon-Capitale_2006-09-12.png">Lyon Capitale 2006-09-12</a>
<a href="https://bosdonnat.fr/data/ooocon2006/m6_Lyon_2006-09-12.ogm">M6 Lyon</a>
<a href="https://bosdonnat.fr/data/ooocon2006/France3_Rhone-Alpes_2006-09-12.ogm">France 3 Rhone-Alpes</a></p>OOoCon2006, it's over2006-09-19T08:12:00+02:002006-09-19T08:12:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-09-19:/ooocon2006-its-over.html<p>Now the OpenOffice.org conferences 2006 are closed and the normal life
has taken its old rythm now. This article is only about to thank you all
for making this year's conferences a big event, quite like a family one.</p>
<p>Being prepared during several month by many persons on both …</p><p>Now the OpenOffice.org conferences 2006 are closed and the normal life
has taken its old rythm now. This article is only about to thank you all
for making this year's conferences a big event, quite like a family one.</p>
<p>Being prepared during several month by many persons on both
OpenOffice.org and INSA Lyon side, my first thanks are coming to all
those who helped us making it possible: Sophie, Marie-Jo, Jean-François
and Charles from OpenOffice.org and Yves Condemine, Patrick Pollet,
Cédric Grand, Anne Mouriquand from INSA. I am sure to forget many
persons here, but I think that they will recognize themselves.</p>
<p>To help us keep the conferences in our mind, the <a href="http://ooocon.kiberpipa.org/">kiberpipa team</a> who
did an extraordinary job, provides us the video archives of the
conferences and offers to host your photos of the event.</p>
<p>Again, thanks to you all. </p>About this site2006-08-23T23:55:00+02:002006-08-23T23:55:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-08-23:/about-this-site.html<p>As you might have seen, I had some problems with my old
dokuwiki. Thus I have decided to use something else: and I found
WordPress. There was a quite long time where this site was unavailable
for me to install WordPress and some util plugins. The content of the
old …</p><p>As you might have seen, I had some problems with my old
dokuwiki. Thus I have decided to use something else: and I found
WordPress. There was a quite long time where this site was unavailable
for me to install WordPress and some util plugins. The content of the
old dokuwiki is not back, but just stay tuned...</p>Uno IDL syntax highlighting in PHP2006-08-20T11:20:00+02:002006-08-20T11:20:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-08-20:/uno-idl-syntax-highlighting-in-php.html<p>Uno IDL is the component specification language of OpenOffice.org. Here
is a solution to show some highlighted Uno IDL code. It uses <a href="http://qbnz.com/highlighter/">GeSHi</a>
and you need to add a language file describing how to parse and colorize
you Uno IDL code. As this language file doesn't exist I created …</p><p>Uno IDL is the component specification language of OpenOffice.org. Here
is a solution to show some highlighted Uno IDL code. It uses <a href="http://qbnz.com/highlighter/">GeSHi</a>
and you need to add a language file describing how to parse and colorize
you Uno IDL code. As this language file doesn't exist I created one.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/idl.phps">Download the GeSHi language file now</a></p>OOEclipseIntegration release 1.0.3.a2006-08-20T11:11:00+02:002006-08-20T11:11:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-08-20:/ooeclipseintegration-release-103a.html<p>A new release is available on the usual <a href="/ooeclipseintegration">update site</a>.</p>
<p>It mainly contains fixes for windows version as some code cleaning. This
version warns the user that white spaces in the SDK or project paths may
lead to problems of builds. This problem is due to some bugs of the …</p><p>A new release is available on the usual <a href="/ooeclipseintegration">update site</a>.</p>
<p>It mainly contains fixes for windows version as some code cleaning. This
version warns the user that white spaces in the SDK or project paths may
lead to problems of builds. This problem is due to some bugs of the idlc
compiler and will be fixed in a future release of the OpenOffice.org
SDK.</p>
<p>The next release will contain new interesting features like a Java
skeleton generation, services.rdb or component exports, and may be URE
application run in eclipse. Thus stay tuned...</p>OOoEclipseIntegration release 1.0.32006-06-26T11:05:00+02:002006-06-26T11:05:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2006-06-26:/oooeclipseintegration-release-103.html<p>I'm glad to announce that 1.0.3 release of the OOoEclipseIntegration
plugin is out. Here are the changes:</p>
<ul>
<li>Basic URE support</li>
<li>User documentation</li>
<li>Developer documentation: Javadoc API completed and “howto extend”
tutorial</li>
<li>Moving the language specific code into a new plugin</li>
<li>Ant scripts to automate the update site build …</li></ul><p>I'm glad to announce that 1.0.3 release of the OOoEclipseIntegration
plugin is out. Here are the changes:</p>
<ul>
<li>Basic URE support</li>
<li>User documentation</li>
<li>Developer documentation: Javadoc API completed and “howto extend”
tutorial</li>
<li>Moving the language specific code into a new plugin</li>
<li>Ant scripts to automate the update site build</li>
<li>Internal model refactoring</li>
<li>Fixed some bugs</li>
</ul>
<p>In fact there are many internal changes preparing future extensions of
the plugin. For the user, the important new thing is the URE support.
Now you can create a new UNO project using a URE instance, the type
browser will show you only the URE types and in a future version you
will be able to create a new URE application and run it.</p>
<p>The <a href="/ooeclipseintegration">update site</a> is still the same.</p>
<p>Any report is welcomed and stay tuned...</p>UNO-IDL types introspection in Java2006-03-11T10:57:00+01:002006-03-11T10:57:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-03-11:/uno-idl-types-introspection-in-java.html<p>Since the beginning of the Google Summer of Code 2005 when I started the
OpenOffice.org Eclipse Integration project, I wanted to provide a code
completion feature for UNO-IDL. At the beginning I thought at a huge
mecanism using IDL parsers to fetch the informations. However, I
investigate a bit …</p><p>Since the beginning of the Google Summer of Code 2005 when I started the
OpenOffice.org Eclipse Integration project, I wanted to provide a code
completion feature for UNO-IDL. At the beginning I thought at a huge
mecanism using IDL parsers to fetch the informations. However, I
investigate a bit more on Juergen and Laurent ideas: using the UNO
reflection API to introspect any type.</p>
<p>After a small test, I could manage to do it in a small Java application.
I'll try to explain what I did. All the code provided is in very simple
Java main and should be launched with a correct ClassPath (the
OpenOffice.org jars) and <code>LD_LIBRARY_PATH</code> set to your OpenOffice.org
program directory. This is because OOo Jars use the OOo shared
libraries.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/ReflectionTest.java">Download the whole code now</a></p>
<p>First thing to do is to bootstrap OpenOffice.org to get a component
context. There is no mystery in this code: using the Bootstrap class and
one of its method is the best way to do it.</p>
<div class="highlight"><pre><span></span><code><span class="k">try</span> <span class="p">{</span>
<span class="c1">//*****************************************************************************</span>
<span class="c1">// 1- Bootstrap of OpenOffice.org</span>
<span class="c1">//*****************************************************************************</span>
<span class="n">String</span> <span class="n">sofficepath</span> <span class="o">=</span> <span class="s">"file:///opt/openoffice.org2.0/program"</span><span class="p">;</span>
<span class="n">String</span> <span class="n">unoini</span> <span class="o">=</span> <span class="n">sofficepath</span> <span class="o">+</span> <span class="s">"/unorc"</span><span class="p">;</span> <span class="c1">// To change in uno.ini for Windows</span>
<span class="n">Hashtable</span> <span class="n">params</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Hashtable</span><span class="p">();</span>
<span class="n">params</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="s">"SYSBINDIR"</span><span class="p">,</span> <span class="n">sofficepath</span><span class="p">);</span>
<span class="n">XComponentContext</span> <span class="n">xCtx</span> <span class="o">=</span> <span class="n">Bootstrap</span><span class="p">.</span><span class="na">defaultBootstrap_InitialComponentContext</span><span class="p">(</span>
<span class="n">unoini</span><span class="p">,</span> <span class="n">params</span><span class="p">);</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> OOo has been bootstrapped"</span><span class="p">);</span>
</code></pre></div>
<p>This second part of code loads a types registry external to
OpenOffice.org. You will have to load some if you want to introspect in
addons or components types (I mean types which aren't defined in the
OpenOffice.org API)</p>
<div class="highlight"><pre><span></span><code> <span class="c1">//*****************************************************************************</span>
<span class="c1">// 2- Opening a local types regitry</span>
<span class="c1">//*****************************************************************************</span>
<span class="n">String</span> <span class="n">localRegistry</span> <span class="o">=</span> <span class="s">"file:///path/to/your/types.rdb"</span><span class="p">;</span>
<span class="n">XMultiComponentFactory</span> <span class="n">xMCF</span> <span class="o">=</span> <span class="n">xCtx</span><span class="p">.</span><span class="na">getServiceManager</span><span class="p">();</span>
<span class="n">XSimpleRegistry</span> <span class="n">xReg</span> <span class="o">=</span> <span class="p">(</span><span class="n">XSimpleRegistry</span><span class="p">)</span><span class="n">UnoRuntime</span><span class="p">.</span><span class="na">queryInterface</span><span class="p">(</span>
<span class="n">XSimpleRegistry</span><span class="p">.</span><span class="na">class</span><span class="p">,</span>
<span class="n">xMCF</span><span class="p">.</span><span class="na">createInstanceWithContext</span><span class="p">(</span><span class="s">"com.sun.star.registry.SimpleRegistry"</span><span class="p">,</span>
<span class="n">xCtx</span><span class="p">));</span>
<span class="n">xReg</span><span class="p">.</span><span class="na">open</span><span class="p">(</span><span class="n">localRegistry</span><span class="p">,</span> <span class="kc">true</span><span class="p">,</span> <span class="kc">false</span><span class="p">);</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> Local Registry opened"</span><span class="p">);</span>
</code></pre></div>
<p>The thirsd part is the interesting one for this blog article. The first
thing to do before introspecting, is to create a
<code>com.sun.star.reflection.CoreReflection</code> service. This one will provide
two simple methods:</p>
<ul>
<li><code>forName()</code>: gets a type definition from a string representing the
type<br>
name (dot-separated, eg: <code>com.sun.star.uno.XInterface</code>)</li>
<li><code>getType()</code>: gets a type definition from an any UNO object.</li>
</ul>
<p>In our case, we imagine that we don't have any running object to
introspect, but we have just its name (remain that is for code
completion purpose), thus we will use the <code>forName()</code> method (see point
3.1 in the code).</p>
<p>When we have the desired <code>XIdlClass</code>, we can do what we like with:
asking its name, its methods or attributes and so on. To get more help
on this please report to the <a href="http://api.openoffice.org/docs/common/ref/com/sun/star/reflection/XIdlClass.html"><code>com.sun.star.reflection.XIdlClass</code>
API</a>.</p>
<div class="highlight"><pre><span></span><code> <span class="c1">//*****************************************************************************</span>
<span class="c1">// 3- Getting the methods of XInterface</span>
<span class="c1">//*****************************************************************************</span>
<span class="c1">//**** 3.1 - Creating a CoreReflection service</span>
<span class="n">Object</span> <span class="n">oReflection</span> <span class="o">=</span> <span class="n">xCtx</span><span class="p">.</span><span class="na">getServiceManager</span><span class="p">().</span><span class="na">createInstanceWithContext</span><span class="p">(</span>
<span class="s">"com.sun.star.reflection.CoreReflection"</span><span class="p">,</span> <span class="n">xCtx</span><span class="p">);</span>
<span class="n">XIdlReflection</span> <span class="n">xReflection</span> <span class="o">=</span> <span class="p">(</span><span class="n">XIdlReflection</span><span class="p">)</span><span class="n">UnoRuntime</span><span class="p">.</span><span class="na">queryInterface</span><span class="p">(</span>
<span class="n">XIdlReflection</span><span class="p">.</span><span class="na">class</span><span class="p">,</span> <span class="n">oReflection</span><span class="p">);</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> Reflection service fetched"</span><span class="p">);</span>
<span class="c1">//**** 3.2 - Using XIdlReflexion.forName() like Class.forName() in Java</span>
<span class="n">XIdlClass</span> <span class="n">xClazz</span> <span class="o">=</span> <span class="n">xReflection</span><span class="p">.</span><span class="na">forName</span><span class="p">(</span><span class="s">"com.sun.star.uno.XInterface"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">xClazz</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> IdlClass found: "</span> <span class="o">+</span> <span class="n">xClazz</span><span class="p">.</span><span class="na">getName</span><span class="p">());</span>
<span class="c1">// Check for it's methods</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> Methods:"</span><span class="p">);</span>
<span class="c1">//**** 3.3 - A simple use of XIdlClass to list the methods</span>
<span class="n">XIdlMethod</span><span class="o">[]</span> <span class="n">methods</span> <span class="o">=</span> <span class="n">xClazz</span><span class="p">.</span><span class="na">getMethods</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">methods</span><span class="p">.</span><span class="na">length</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">" * "</span> <span class="o">+</span> <span class="n">methods</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">.</span><span class="na">getName</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">">>> No IdlClass found"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>
<p>The rest is the normal ending of a try-catch block and is provided only
for the reader to copy-paste the code.</p>
<div class="highlight"><pre><span></span><code><span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">e</span><span class="p">.</span><span class="na">printStackTrace</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">System</span><span class="p">.</span><span class="na">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</code></pre></div>
<p>So you can imagine that I will now have a lot of work to integrate this
in the plugin, but you will have it in an indetermined delay...
depending on my time.</p>Patch for OOoBean and the office termination2006-03-04T10:55:00+01:002006-03-04T10:55:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-03-04:/patch-for-ooobean-and-the-office-termination.html<p>I experienced some problems properly <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=60473">closing OpenOffice.org from the
OOoBean</a>. Joachim Lingner told me there was an issue for this. As the
solution was quite simple to realize and test, I did it.</p>
<p>I just added a terminateOOo() method that terminate OOo if there is only
the bean on …</p><p>I experienced some problems properly <a href="http://qa.openoffice.org/issues/show_bug.cgi?id=60473">closing OpenOffice.org from the
OOoBean</a>. Joachim Lingner told me there was an issue for this. As the
solution was quite simple to realize and test, I did it.</p>
<p>I just added a terminateOOo() method that terminate OOo if there is only
the bean on the desktop and stops the bean connection otherwise. The
method returns a boolean to indicate whether the office is terminated or
not.</p>The OpenOffice.org development plugin for Eclipse is still alive2006-02-19T10:49:00+01:002006-02-19T10:49:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-02-19:/the-openofficeorg-development-plugin-for-eclipse-is-still-alive.html<h3>Version 1.0.2 released</h3>
<p>This new version contains a few changes with the previous one, but will
be quite important for users. The OpenOffice.org development plugin for
Eclipse took some lessons from my previous experience of UNO and the
URE:</p>
<ul>
<li>All the files generated from IDL files are …</li></ul><h3>Version 1.0.2 released</h3>
<p>This new version contains a few changes with the previous one, but will
be quite important for users. The OpenOffice.org development plugin for
Eclipse took some lessons from my previous experience of UNO and the
URE:</p>
<ul>
<li>All the files generated from IDL files are in a build directory</li>
<li>The generated UNO-IDL project classpath has been extended with JRE
libraries (was forgotten) and build directory with the generated class
files</li>
</ul>
<p>The other main changes are concerning the plugin development. The plugin
online help has now a small structure and the Javadoc API will be
integrated into this help. Now the documentation have to be written and
the Javadoc API completed to help new developers.</p>
<h3>Creating an Eclipse update site</h3>
<p>This new version comes with a new build organization: there is no more
need for Eclipse feature and site projects to produce an update site.
There is only to execute the ant build.xml file to generate it.
Afterwards, just copy the following file and unzip it to get your update
site.</p>
<div class="highlight"><pre><span></span><code><span class="err">bin/ant/ooeclipseintegration_site.zip</span>
</code></pre></div>
<p>For example, to create the <em>http://sample.org/ooeclipseintegration</em>
update site, we will unzip the file on the server and put an
'<em>ooeclipseintegration</em>' alias to the directory where we unzipped the
file.</p>
<p>Before executing the ant script, you have to change some properties to
make it fit to your platform:</p>
<div class="highlight"><pre><span></span><code><span class="err"><property name="eclipse.home" value="/path/to/eclipse/directory" /></span>
<span class="err"><property name="openoffice.home" value="/path/to/openoffice.org2.0/directory" /></span>
</code></pre></div>
<h3>What could be done...</h3>
<p>With this script, it would be great to have a page on the OpenOffice.org
API project, to explain the different steps to install the plugin an
provide an update site... This would give more visibility to the project
and it would be easier for users to remember an url like
http://api.openoffice.org/ooeclipseintegration instead of searching the
web in order to find the plugin.</p>
<h3>The next steps</h3>
<p>Now, there is still many features to add to this plugin. For example,
URE support, C++ and python languages supports, some other wizards,
integrating the skeletonmaker. However the most urgent to do now is to
improve the plugin to help other people to help developping with me,
which means:</p>
<ul>
<li>Reviewing all the Javadoc API comments and complete them</li>
<li>Filling the online help pages that have just been created with a
user manual and reiviewing the cheatsheets and adding other ones</li>
<li>Refactoring the UnoIdlProject class to easily add a new language
using an extension point and fragments for new languages</li>
<li>The french translation as an example for other ones</li>
</ul>
<p>So, don't be too impatient, this will be done in a indetermined delay ;)</p>Handling GStreamer throught UNO2006-01-23T10:45:00+01:002006-01-23T10:45:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2006-01-23:/handling-gstreamer-throught-uno.html<p>Big news, I have a first working version of an UNO component to handle
GStreamer from UNO code. This will allow using gstreamer features within
UNO framework such as macro but also Java, c++ or pyUNO programs.</p>
<p>This component has many advantages for OpenOffice.org: it uses a free
multimedia …</p><p>Big news, I have a first working version of an UNO component to handle
GStreamer from UNO code. This will allow using gstreamer features within
UNO framework such as macro but also Java, c++ or pyUNO programs.</p>
<p>This component has many advantages for OpenOffice.org: it uses a free
multimedia framework, and provide an API. This API has to be extended
and doesn't give access to every GStreamer feature.</p>
<p><em>Of course this is still under development, and may not work in some
cases. However, every feedback is welcome. Note that the component's
page will be back soon.</em> Many thanks to Laurent Godard who help me to
debug and test the component</p>Creating an URE application in C++2005-12-07T10:42:00+01:002005-12-07T10:42:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2005-12-07:/creating-an-ure-application-in-c.html<p>I just have finished to write a tutorial on how to create a simple C++
application based on the URE. This paper is written for URE and UNO
beginners and might be missing some important informations.</p>
<p>I would really appreciate every return to modify this tutorial and make
it better …</p><p>I just have finished to write a tutorial on how to create a simple C++
application based on the URE. This paper is written for URE and UNO
beginners and might be missing some important informations.</p>
<p>I would really appreciate every return to modify this tutorial and make
it better: it may be a tool to spread UNO around the world. The tutorial
is refering to an article I wrote earlier: " <a href="https://bosdonnat.fr/a-uno-ure-exercise.html">A UNO/URE exercise</a>".</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/uretutorial.odt">Download the tutorial now</a></p>OOEclipse Integration isn't dead2005-11-29T10:40:00+01:002005-11-29T10:40:00+01:00Cédric Bosdonnattag:bosdonnat.fr,2005-11-29:/ooeclipse-integration-isnt-dead.html<h3>A new version</h3>
<p>I have released a new version (1.0.1) of the Eclipse plugin to support
OpenOffice.org development. Here are the changes from the previous
release:</p>
<ul>
<li>a new UNO-IDL interface wizard</li>
<li>the new UNO project wizard was extended with the new service wizard
as a second page …</li></ul><h3>A new version</h3>
<p>I have released a new version (1.0.1) of the Eclipse plugin to support
OpenOffice.org development. Here are the changes from the previous
release:</p>
<ul>
<li>a new UNO-IDL interface wizard</li>
<li>the new UNO project wizard was extended with the new service wizard
as a second page</li>
<li>definition of default values in the wizards</li>
<li>build bug fixed (was just a workspace refreshing problem)</li>
</ul>
<p><strong>Important:</strong> <em>The plugin doesn't work with the gij and gcj</em></p>
<h3>Getting the new version</h3>
<ul>
<li>Sources available on the api/ooeclipseintegration CVS</li>
<li>Add <a href="/ooeclipseintegration">this link</a> as an Eclipse update
site.</li>
</ul>
<h3>What's next ?</h3>
<ul>
<li>C++ language support: This mainly includes the cppumaker use</li>
<li>detection of the Eclipse available plugins to configure the wizards</li>
<li>complete the code documentation and the user help</li>
<li>update of the Cheat Sheets</li>
<li>fix some configuration bugs.</li>
</ul>A UNO-URE exercise2005-10-29T10:33:00+02:002005-10-29T10:33:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2005-10-29:/a-uno-ure-exercise.html<p>I just have completed to write and document a small exercise to learn
the basis for C++ URE based applications. Just get the joint archive and
look at the README file for the instructions.</p>
<p>In the archive you will find: the correction, the question and the
makefile for the build …</p><p>I just have completed to write and document a small exercise to learn
the basis for C++ URE based applications. Just get the joint archive and
look at the README file for the instructions.</p>
<p>In the archive you will find: the correction, the question and the
makefile for the build. In a few words, the exercise consists in writing
the specifications and implementation of an application using a Banker
and a Customer asking for money. Completing the exercise without looking
at the answer takes approximatly working 2 or 3 days ;)</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/exercise.tgz">Download the exercise now</a></p>UNO Component for URE test.2005-10-18T10:20:00+02:002005-10-18T10:20:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2005-10-18:/uno-component-for-ure-test.html<p>I have written an example of URE application just saying Hello URE world
in two languages: C++ and Java. To run this example you will need an
UNIX environment, that is to say a UNIX or an emulation like cygwin. It
uses the following tools:</p>
<ul>
<li>GNU Make</li>
<li>G++ 3.3 …</li></ul><p>I have written an example of URE application just saying Hello URE world
in two languages: C++ and Java. To run this example you will need an
UNIX environment, that is to say a UNIX or an emulation like cygwin. It
uses the following tools:</p>
<ul>
<li>GNU Make</li>
<li>G++ 3.3</li>
<li>OpenOffice.org 2.0 SDK</li>
<li>URE installed in /opt/openoffice.org/ure/</li>
</ul>
<h3>Howto run the example ?</h3>
<p>You just have to launch <strong>make</strong> to build the component. Launch
<strong>unotest</strong> to run the URE starting with the C++ implementation and the
Java one. To clear the directory, use <strong>make purge</strong>.</p>
<h3>How does it work ?</h3>
<p>This example is the one given in <a href="https://bosdonnat.fr/my-first-ure-component-in-java.html">this post of my blog</a>. It has been
completed by a C++ implementation. The principle in C++ is the same than
in Java: the major problem is the compilation chain. You can study it by
reading the content of the makefile contained in the archive. To
understand the makefile syntax, please refer to <a<br></a<br>
href="http://theory.uwinnipeg.ca/localfiles/infofiles/make/make_5.html#SEC4">
this page</a>.</p>
<p><a href="https://bosdonnat.fr/data/OpenOffice.org/unotest.tgz">Download the test now</a></p>A very nice summer for OpenOffice.org2005-10-10T10:17:00+02:002005-10-10T10:17:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2005-10-10:/a-very-nice-summer-for-openofficeorg.html<p>During my Summer I was selected in the <a href="http://code.google.com/summerofcode.html">Google Summer of Code</a> to
produce a Eclipse plugin that will help OpenOffice.org developpers in
their task. This project is very wide and could be expanded with a lot
of new features.</p>
<!--more-->
<p>The initial goal is to provide a tool for …</p><p>During my Summer I was selected in the <a href="http://code.google.com/summerofcode.html">Google Summer of Code</a> to
produce a Eclipse plugin that will help OpenOffice.org developpers in
their task. This project is very wide and could be expanded with a lot
of new features.</p>
<!--more-->
<p>The initial goal is to provide a tool for new OOo developpers, with code
generation, UNOIDL syntax highlighting, OpenOffice.org or URE and SDK
configuration and of course many creation wizards. At this point, there
are a few basic features added, however there is still many work to do.</p>
<h3>Where to find it ?</h3>
<p>You can find the sources on the <a href="http://api.openoffice.org/source/browse/api/ooeclipseintegration/">OpenOffice.org api project CVS, module
ooeclipseintegration</a>. I am trying to build an update site on my own
website... but it is still under construction. The plugin archive can be
found in the <strong>build</strong> directory. Let me know if your feelings about
this piece of work, but do never forget that it has to be continued.</p>My first URE Component in Java2005-10-10T10:11:00+02:002005-10-10T10:11:00+02:00Cédric Bosdonnattag:bosdonnat.fr,2005-10-10:/my-first-ure-component-in-java.html<p>How to create a new URE based application ? The documentation is quite
hard to find, but the main important thing is: create a UNO component
implementing the <code>com.sun.star.lang.XMain</code> interface. This one will
contain a method <em>run()</em>. I'll explain how to create a "Hello URE World"
application …</p><p>How to create a new URE based application ? The documentation is quite
hard to find, but the main important thing is: create a UNO component
implementing the <code>com.sun.star.lang.XMain</code> interface. This one will
contain a method <em>run()</em>. I'll explain how to create a "Hello URE World"
application.</p>
<!--more-->
<p>The project will be organized in the following way:</p>
<ul>
<li><strong>idl</strong> diretory containing the application UNOIDL specifications</li>
<li><strong>source</strong> directory containing the implementation of the UNOIDL
types</li>
<li><strong>program</strong> directory which will contain the application registries
and libraries</li>
<li><strong>MANIFEST.MF</strong> file which will describe the registration class of
the component</li>
<li><strong>Makefile</strong> file to make the build much easier</li>
<li><strong>unotest</strong> file to launch the newly created application</li>
</ul>
<h3>UNOIDL file definition</h3>
<p>The file <code>idl/org/unotest/Main.idl</code> will describe a simple service
<code>org.unotest.Main</code> exporting the XMain interface this gives the
following code:</p>
<div class="highlight"><pre><span></span><code><span class="err">module org { module unotest {</span>
<span class="err"> service Main: com::sun::star::lang::XMain {</span>
<span class="err"> create ();</span>
<span class="err"> }</span>
<span class="err">}; };</span>
</code></pre></div>
<p>Note that this service is a new style one: defining constructors and
exporting a single interface.</p>
<h3>Java implementation</h3>
<p>Now just create a <code>org.unotest.comp.MyMain</code> Java class in the
<code>source/org/unotest/comp/MyMain.java</code> file. This class will implement
the following three methods:</p>
<div class="highlight"><pre><span></span><code><span class="kd">public</span> <span class="kt">int</span> <span class="nf">run</span> <span class="p">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">arguments</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Printing Hello URE World ;) and exit</span>
<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"Hello URE World ;)"</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<p>__getServiceFactory(...) and __writeRegistryServiceInfo(...) are
used for the component registration. They implementation is fully
described in the <a href="http://api.openoffice.org/docs/DevelopersGuide/Components/Components.htm#1+5+Simple+Component+in+Java">chapters 4.5.3 and 4.5.4 of the OpenOffice.org
Developer Guide</a></p>
<h3>Generation of the component</h3>
<p>The component generation works like the OpenOffice.org components
generation, however there are some tricky things to know:</p>
<ul>
<li><strong>use the URE regmerge and regcomp tools</strong>. Otherwise you will get
some Loader exceptions when trying to use regcomp on your component.</li>
<li>do not put your class files directly in your current directory: this
is a new issue that will be corrected. If you do not respect this
advice, the regcomp tool will use the class files in your current
directory before the one in your jar file.</li>
</ul>
<p>In our unotest case, the build instructions are written in the Makefile.
It should use the following tools:</p>
<ol>
<li>idlc -Ourd -I\$(SDK_HOME}/idl idl/org/unotest/Main.idl</li>
<li>\$(URE_HOME)/bin/regmerge program/types.rdb UCR urd/Main.urd</li>
<li>javamaker -Torg.unotest.Main -BUCR program/types.rdbb
-X\$(URE_HOME)/share/misc/services.rdb
-X\$(URE_HOME)/share/misc/types.rdb</li>
<li>javac -d . -cp \$(CLASSPATH) source/org/unotest/comp/MyMain.java</li>
<li>jar cfm program/unotest.uno.jar MANIFEST.MF
org/unotest/compMyMain.class org/unotest/Main.class</li>
<li>rm -Rf org</li>
<li>\$(URE_HOME)/bin/regcomp -register -br
\$(URE_HOME)/share/misc/types.rdb -br
\$(URE_HOME)/share/misc/services.rdb -r program/services.rdb -c
file://\$(PWD)/program/unotest.uno.jar -classpath \$(CLASSPATH)</li>
</ol>
<p>What will these commands do ?</p>
<ol>
<li>Compile your UNOIDL specification to create the urd/Main.urd
registry</li>
<li>Merge the generated urd file in the program/types.rdb registry</li>
<li>Create the org/unotest/Main.class file</li>
<li>Compile your java implementation of the service</li>
<li>Create the jar file of the component</li>
<li>Delete the unused class files to avoid problems with regcomp</li>
<li>Register the component in the URE</li>
</ol>
<h3>Launching the application</h3>
<p>In the unotest file, you just have to put a call to the uno tool
contained in the URE:</p>
<div class="highlight"><pre><span></span><code> <span class="err">$</span><span class="n">URE_HOME</span><span class="o">/</span><span class="n">bin</span><span class="o">/</span><span class="n">uno</span> <span class="o">-</span><span class="n">c</span> <span class="n">org</span><span class="p">.</span><span class="n">unotest</span><span class="p">.</span><span class="n">comp</span><span class="p">.</span><span class="n">MyMain</span>
<span class="o">-</span><span class="n">l</span> <span class="n">file</span><span class="p">:</span><span class="o">//</span><span class="ss">`pwd`</span><span class="o">/</span><span class="n">program</span><span class="o">/</span><span class="n">unotest</span><span class="p">.</span><span class="n">uno</span><span class="p">.</span><span class="n">jar</span>
<span class="o">-</span><span class="n">ro</span> <span class="n">program</span><span class="o">/</span><span class="n">services</span><span class="p">.</span><span class="n">rdb</span>
<span class="o">-</span><span class="n">ro</span> <span class="n">program</span><span class="o">/</span><span class="n">types</span><span class="p">.</span><span class="n">rdb</span>
<span class="o">-</span><span class="n">ro</span> <span class="err">$</span><span class="n">URE_HOME</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">misc</span><span class="o">/</span><span class="n">services</span><span class="p">.</span><span class="n">rdb</span>
<span class="o">-</span><span class="n">ro</span> <span class="err">$</span><span class="n">URE_HOME</span><span class="o">/</span><span class="n">share</span><span class="o">/</span><span class="n">misc</span><span class="o">/</span><span class="n">types</span><span class="p">.</span><span class="n">rdb</span>
</code></pre></div>
<p>Thus when launching the unotest file, you will launch the URE with you
org.unotest.comp.MyMain as the main class to load at the beginning. This
will print you the expected "<em>Hello URE World ;)</em>"</p>
<p>The next step is to do the same with a C++ component... but I'm still
working on it.</p>