Samstag, 19. Dezember 2015

Duplicate rows in SWT TableViewer

When working with SWT/JFace TableViewers problems occured with identical rows.

The following picture shows the TableViewer (left one). The input is a List<String>. The input contains 2 equal strings "Trenner" (marked red).


I implemented a delete button (red array, center). My first implementation used the viewer.getSelection() method to obtain the current selection. I iterated over the selected strings and removed them from the list and from the viewer.

List input = ...

IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();

for (Iterator i=sel.iterator(); i.hasNext(); ) {
   String action = (String) i.next();
   input.remove(action);
   viewer.remove(action);
}

The code worked but failed when removing the second "Trenner" in the above scenario. The first "Trenner" was removed and the second remained in the TableViewer.

The reason is obvious: java.util.List.remove(Object o) and TableViewer.remove(Object o) both remove the first occurence of the specified object. So the first "Trenner" is removed.

As far as I see there is no way to do it with JFace. So I used SWT fallback:

List input = ...

int[] selection = viewer.getTable().getSelectionIndices();
    
if (selection.length > 0) {     
  for (int index: selection) {
     input.remove(index);
  }            

  // Refresh the viewer
  viewer.refresh();
}

The solution is to work with the getSelectionIndecies() of the SWT-Table. Iterate over the idicies and remove the objects from the java.util.List input.
After that call TableViewer.refresh() and you are done.


Freitag, 18. Dezember 2015

SWT Table or JFace TableViewer height problem with preloaded data

When implementing a new function to a SWT/JFace bases dialog I encountered a problem when data is loaded into the table before it is visible.

The TableViewer is placed in a GridLayout and should grab available vertical und horizontal space. Therefor I applied th follwing GridData:

viewer.getControl().setLayoutData(
    new GridData(SWT.FILL, SWT.FILL, true, true));

The layout was fine since I loaded no data via the setInput() method of the TableViewer. As soon as I loaded data into the TableViewer the Table height increased to display all rows without scrollbars. The scrollbars then appeared in DetailsPart where the TableViewer was placed in.

The following picture illustrates the problem:

Messy scrollbars

This is pretty aweful because the buttons also scroll up and the form is unusable.

I tried several code-changes to bring the scrollbars to the TableViewer. When data is loaded after the GUI showed up everything was fine. Unfortunately I could not manage to get it working in the JFace master/details pattern.

The I remembered the GridDataFactory and modified the setLayoutData call for the TableViewer:

viewer.getControl().setLayoutData(GridDataFactory.defaultsFor(
    viewer.getControl()).grab(true, true).align(SWT.FILL, SWT.FILL)
   .create());

And that did the trick!

The defaultsFor() does something more so the scrollbars always appear at the TableViewer even if a large amount of data is loaded before the GUI shows up.

Scrollbars display correctly at the TableViewer





Mittwoch, 9. Dezember 2015

Erstellen einer technischen Dokumentation mit DocBook

In einem älteren Blog habe ich bereits die Ergebnisse meiner Versuche mit Mediawiki und der PDF-Buchfunktion gepostet. Ziel der Übung war, eine Lösung zur Erstellung vielseitig nutzbarer technischer Dokumentationen zu finden.

Im wesentlichen brauche ich folgendes:

  1. Web-Version der Dokumentation
  2. PDF-Version der Dokumentation (auch zum Ausdrucken)
  3. Zentrale Pflege der Inhalte. Im Idealfall also eine vollständige Trennung des Inhalts von der Präsentation
  4. Unterstützung für Inhaltsverzeichnis, Bilder, Tabellen usw.

Vieles davon ließ sich mit MediaWiki und dem PDF BookGenerator lösen. Allerdings bin ich nun darauf gestoßen, dass Tabellen nicht unterstützt werden. Diese fehlen im PDF einfach.
Darüberhinaus ist das Einrichten der benötigten Dienste (Offline Content Generator und Parsiod) aufwändig und alles andere als selbsterklärend.

Ich habe also weiter gesucht und bin auf DocBook (XML) gestossen. Damit hatte ich vor ein paar Jahren schon einmal experimentiert, jedoch gab es auch dabei Schwierigkeiten die letztendlich zum Abbruch meiner Versuche führten.
Ich habe jetzt einen neuen Versuch gestartet.

Wie funktioniert DocBook - ganz kurz


Die Inhalte der Dokumentation werden in einem oder mehreren XML-Files verwaltet. Das Docbook-XML bietet viele Sprachelemente zur Erstellung von Kapiteln, Sektionen, Tabellen, Einbinden von Medien usw.
Das XML enthält jedoch nur inhaltliche Aspekte und keinerlei Formatierung. Wenn man sich mit den Tags beschäftigt merkt man sofort, dass dort schon eine Menge Gehirnschmalz drinsteckt ;)

Um das XML in irgendetwas direkt nutzbares zu überführen gibt es eine Reihe von XSLT-Stylesheets. Ich nutze im Moment die Stylesheets zur Erzeugung einer HTML-Version bzw. XSLFO. Aus dem XSLFO kann im nächsten Schritt ein PDF erzeugt werden.


Einfaches Beispiel


Das folgende Listing zeigt ein Buch (book) mit 2 Kapiteln, einem Bild und einer Tabelle.

 <?xml version="1.0" encoding="utf-8"?>  
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V5.0//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">  
 <book lang="de">  
   <title>System Concept DMS</title>  
   <subtitle>Benutzerhandbuch</subtitle>  
     <bookinfo>  
         <title>System Concept DMS</title>  
         <subtitle>Benutzerhandbuch</subtitle>  
         <author>              
             <firstname>Peter</firstname>  
             <surname>Pinnau</surname>  
             <email>peter@pinnau.biz</email>  
         </author>  
         <date>2015-12-09</date>  
         <releaseinfo>Status: In Arbeit</releaseinfo>  
         <pubdate>2015-12-09</pubdate>  
     </bookinfo>  
   <chapter>  
       <title>Einleitung</title>  
 <para>Alle reden davon, nur wenige haben es: <emphasis role="bold">Das papierlose Büro</emphasis> - oder zumindest eine umfassende Digitalisierung und  
 systematische Ablage von Dokumenten. Unzählige Document Management Systeme (DMS) verschiedener Hersteller versprechen dazu die richtige Software zu liefern. Einige halten was sie versprechen.</para>  
 </chapter>  
 <chapter>  
     <title>Einführung Programmoberfläche</title>  
     <para>Hier fehlt der Text</para>  
     <table frame="all">  
         <caption>Sample HTML Table</caption>  
             <thead>  
                 <tr>  
                     <th>Head 1</th>  
                     <th>Head 2</th>  
                 </tr>  
             </thead>  
             <tbody>  
             <tr>  
                 <td>Body 1</td>  
                 <td>Body 2</td>  
             </tr>  
         </tbody>  
     </table>    
     <mediaobject>  
         <imageobject condition="web">  
             <imagedata fileref="../../img/web/db5d_ref09.png" format="PNG" scale="70"/>  
         </imageobject>
         <textobject>  
             <phrase>The Eiffel Tower</phrase>  
         </textobject>  
         <caption>  
             <para>Designed by Gustave Eiffel in 1889, The Eiffel Tower is one  
               of the most widely recognized buildings in the world.  
             </para>  
         </caption>  
     </mediaobject>          
 </chapter>  
 </book>  


Erzeugung HTML Version


Um aus dem zuvor gelisteten XML eine HTML Version zu generieren benötigt man zunächst die Docbook XSLT-Stylesheets. Diese gibt es hier:

http://sourceforge.net/projects/docbook/files/docbook-xsl

Ich habe mit der am 9.12.2015 aktuellen Version 1.79.0 gearbeitet. Mit Hilfe der Stylesheets wird das XML in HTML überführt. Hierzu benötigt man einen XSLT-Prozessor. Unter Ubuntu habe ich dazu den über die Paketverwaltung installierbaren saxon-xslt (Paket libsaxon-java) verwendet und das hat auf Anhieb funktioniert:

peter@gorgonzola:~ saxon-xslt xml/test.xml tools/docbook-xsl-1.79.0/html/chunk.xsl

Der erste Parameter ist die Input-Datei, der zweite das entsprechende Stylesheet. Im Unterordner html sind mehrere Stylesheets vorhanden. chunk.xsl erzeugt eine HTML-Datei pro Kapitel und eine index.html mit dem Inhaltsverzeichnis. Saxon legt die html-Files im aktuellen Verzeichnis ab.

Im Moment fehlen bei der Tabelle im HTML noch die Borders. Das ist jedoch sicher einfach lösbar.

Erzeugung PDF Version

Auch hierfür werden die Docbook XSLT-Stylesheets benötigt. Mit saxon wird das XML zunächst in XSLFO und dann mittels Apache FOP in ein PDF überführt. FOP kann unter Ubuntu ebenfalls einfach über die Paketverwaltung installiert werden (Paket fop).

XML nach XSLFO mittels saxon
peter@gorgonzola:~ saxon-xslt -o docu.fo xml/test.xml tools/docbook-xsl-1.79.0/fo/docbook.xsl

ACHTUNG: saxon-xslt braucht hier den -o Parameter, da das XSLFO anderenfalls auf STDOUT ausgegeben wird.

XSLFO nach PDF mittels fop
peter@gorgonzola:~ fop output/pdf/docu.fo output/pdf/docu.pdf


NLS - National language support


Da ich dem <book> das Attribut lang="de" mitgegeben habe, verwenden die Stylsheets automatisch deutsche Textkonstanten (z.B. Kapitel, Inhaltsverzeichnis, Anfang usw.).
Ohne das lang-Attribute werden die englischen Begriffe verwendet.


Fazit


Mit Docbook habe ich nun endlich eine solide Basis zur Erstellung von Dokumentationen gefunden. In allen wesentlichen Punkten waren die Tests erfolgreich. Detailprobleme lassen sich mit Sicherheit lösen.


Links


DocBook - creating a docbook:
http://www.docbook.org/tdg5/en/html/ch02.html

Docbook-XSLTStylesheets Download:
http://sourceforge.net/projects/docbook/files/docbook-xsl/