Documentation/WollMux/External interface

    From The Document Foundation Wiki
    Other languages:

    WollMux can be controlled externally via various interfaces. Clerks do not normally need to know about these control options, since communication via these interfaces runs in the background for them. The article is intended for advanced template creators and developers who create templates and program libraries based on WollMux.

    Adding additional buttons to the LibreOffice toolbar

    Some WollMux functionalities can be included in the form of buttons in the LibreOffice toolbar.

    The integration goes as follows:

    1. Tools/Customize.../"Toolbars" tab.
    2. Select target "Standard
    3. Select the "LibreOffice Writer" section
    4. Select category "Macros
    5. Select the desired functionality on the left
    6. Arrow button
    7. Button "OK

    The following functionalities are currently available through this interface:

    • Kill: closes all LibreOffice processes without confirmation (see also #wollmux:Kill)
    • About: shows the dialog "Info about templates and forms" (see also #wollmux:About)

    Technically, this interface is a basic library called "WollMux" with the module "Call" in which the corresponding Dispatch-commands of WollMux are dispatched. The module is automatically installed with the WollMux.uno.pkg.

    Set shortcut for an interface

    An Tastenkuerzel entry in configuration files can be used to set an LibreOffice Writer key combination for an interface (e.g. ctrl+t for wollmux:TextbausteinEinfuegen).

    Programming interfaces

    The dispatch commands of the WollMux

    WollMux provides a set of so-called "dispatch commands", which are included via LibreOffice's dispatch framework and cause WollMux to perform various actions.

    The following program example in LibreOffice-Basic shows how to invoke WollMux's dispatch commands:

    Sub About
      dispatchURL("wollmux:About") # here is the <URL>
    End Sub
    
    Sub dispatchURL(urlStr` `as` `String)
      dim url as new com.sun.star.util.URL
      url.Complete = urlStr
     
      frame = ThisComponent.currentController.Frame
      dispatch = frame.queryDispatch(url, "_self", com.sun.star.frame.FrameSearchFlag.SELF)
     
      dim args() as new com.sun.star.beans.PropertyValue
      dispatch.dispatch(url, args)
    End Sub

    Here, the dispatchURL(urlStr as String) function expects one of the following URLs:

    wollmux:AbsenderAuswaehlen

    Syntax of the URL:

    wollmux:AbsenderAuswaehlen

    Opens the "Select Sender" dialog which can be used to specify the current sender of the letterhead system. Here is an example of such a dialog:

    Dialog for selecting the sender
    Dialog for selecting the sender


    wollmux:PALVerwalten

    URL syntax:

    wollmux:PALVerwalten

    Opens the "Manage Sender List" dialog through which the current Personal Sender List (PAL) of the letterhead system can be managed. Here is an example of such a dialog:

    Dialog for managing the sender list
    Dialog for managing the sender list


    wollmux:Open

    WARNING This dispatch is no longer supported.

    wollmux:OpenTemplate

    Syntax of URL:

    wollmux:OpenDocument#<FRAG_ID>

    wollmux:OpenDocument#<FRAG_ID1>&<FRAG_ID2>&<FRAG_ID3>...

    Opens the template with the FRAG_ID "<FRAG_ID>". Depending on the type of the document and the possibly contained Document command setType, the (other) contained Document commands are processed or not. For use in conjunction with the insertContent command, multiple FRAG_IDs can be specified. These are separated by "&".

    wollmux:OpenDocument

    Syntax of the URL:

    wollmux:OpenDocument#<FRAG_ID>

    Opens the template with the FRAG_ID "<FRAG_ID>" for editing. When doing so, the Document commands contained in the template are not evaluated.

    wollmux:FunctionDialog

    Syntax of the URL:

    wollmux:FunctionDialog#<dialog identifier>

    Opens the function dialog with the name "<dialog identifier>" defined globally in the configuration file wollmux.conf and transfers the function values selected there to the insertFormValue commands contained in the currently open document.

    wollmux:FormularMax4000

    URL syntax:

    wollmux:FormularMax4000

    Opens the FormularMax 4000, the graphical interface for creating forms.

    wollmux:ZifferEinfuegen

    URL syntax:

    wollmux:ZifferEinfuegen

    All lines selected by the cursor are marked as disposition points for Content based directives and are assigned the corresponding Roman numerals. If the cursor is already on such a line, the marking is removed again and the Roman numeral is removed. The behavior is described in more detail on the page "Content based directives".

    wollmux:Abdruck

    URL syntax:

    wollmux:Abdruck

    Starting from the current cursor position, a new paragraph "<digit> imprint of ..." is inserted and marked as a disposition point of Content based directives. If the cursor is already on such a paragraph, the impression is removed. The behavior is described in more detail on the "Content based directives" page.

    wollmux:Zuleitungszeile

    URL syntax:

    wollmux:Zuleitungszeile

    All paragraphs of the current foreground document selected via the cursor will be marked as feed lines of Content based directives, or any existing marking will be deselected. The behavior is described in more detail on the "Content based directives" page.

    wollmux:DumpInfo

    URL syntax:

    wollmux:DumpInfo

    Causes WollMux to create a file $HOME/.wollmux/dump<DateAndTime> that contains important information for troubleshooting issues related to WollMux. DumpInfo is especially useful for WollMux administrators who encounter errors during WollMux installation and setup that require D-III-ITD-5.1 support to resolve. In this case, the dump file generated via dumpInfo should be attached to an appropriate incident ticket.

    wollmux:Kill

    Syntax of URL:

    wollmux:Kill

    Closes all LibreOffice windows without any security prompts(!).

    Note: Crashed LibreOffice processes are not killed by this, not even the quick launcher.

    wollmux:About

    Syntax of the URL:

    wollmux:About

    wollmux:About#<version of the WollMuxBar>

    Causes WollMux to display the "About Templates and Forms (WollMux)" dialog, which contains the following important version information:

    • The release version of the WollMux core component WollMux.uno.pkg.
    • The release version of the underlying WollMux configuration.
    • The DEFAULT_CONTEXT from which the configuration is obtained.

    Here is an example of such a dialog:

    Info dialog of WollMux
    Info dialog of WollMux


    wollmux:TextbausteinEinfuegen

    Syntax of the URL:

    wollmux:TextbausteinEinfuegen

    After pressing a previously assigned button or key combination, a backwards search is started starting from the cursor, which runs until no more text modules are found in a paragraph. All text blocks found in the process are resolved accordingly.

    wollmux:TextbausteinVerweisEinfuegen

    URL syntax:

    wollmux:TextbausteinVerweisEinfuegen

    After pressing a previously assigned button or key combination, a backwards search is started starting from the cursor, which runs until no more text modules are found in a paragraph. For all text modules found, text marks are set with the document command 'insertFrag', but these are not evaluated immediately, but only after saving as a template and later opening.

    wollmux:PlatzhalterAnspringen

    URL syntax:

    wollmux:PlatzhalterAnspringen

    After pressing a previously assigned button or key combination, the next placeholder is jumped to starting from the cursor. If there is no placeholder but a marker WM(CMD 'setJumpMark') it will be jumped to.

    wollmux:Seriendruck

    Syntax of the URL:

    wollmux:Seriendruck

    Opens the mail merge bar of WollMux via which all mail merge functions of WollMux can be accessed. If a mail merge bar is already open, the existing mail merge bar remains in the foreground.

    WollMux offers a corresponding button automatically in the menu of the Writer under "Extras→Serial print (WollMux)".

    The UNO service de.muenchen.allg.itd51.wollmux.WollMux

    In addition to the dispatch commands, WollMux provides a central UNO service that can be created using the following LibreOffice-Basic line:

    In LibreOffice-Basic:

    mux = createUNOService("de.muenchen.allg.itd51.wollmux.WollMux")

    In Java:

    XWollMux mux = UnoRuntime.queryInterface(XWollMux.class, UNO.createUNOService("de.muenchen.allg.itd51.wollmux.WollMux");

    The interface XWollMux is defined as follows:

    /**
      This interface describes all methods exported by the WollMux service.
    */
    interface XWollMux
    {
       // Methods to register/deregister XPALChangeEventListeners.
       interface XPALChangeEventBroadcaster;
    
       /**
        * Register or deregister the methods described in this interface.
        * corresponding listeners of type XEventListener, which inform WollMux * about the status of document processing.
        * informs about the status of document processing (e.g. if a document is * completely processed/expanded).
        * has been completely processed/expanded). The register method ignores all
        * XEventListenener instances that have already been registered.
        * Multiple registrations of the same instance are therefore not possible.
        *
        * If a corresponding event occurs, then the call of the
        * corresponding methods XEventListener.notifyEvent(...) is always called simultaneously
        * (i.e. for each listener in a separate thread).
        *
        * The WollMux currently delivers the following events:
        *
        * OnWollMuxProcessingFinished: This event is generated when a
        * text document has been completely processed by WollMux after opening and
        * expanded or for all other document types directly after * opening.
        * opening. I.e. for each document opened in LibreOffice sooner or later * such an event is generated.
        * such an event occurs. If a new EventHandler is registered, then it is assigned
        * for all already open LibreOffice documents the
        * OnWollMuxProcessingFinished events are delivered to it.
        */
       interface com::sun::star::document::XEventBroadcaster;
    
       /**
         This method sets the current sender of the Personal Sender List
         (PAL) to the sender sender. The sender is only set if the
         parameters sender and idx in the alphabetically sorted sender list of the
         WollMux match - i.e. the sender list of the initiating
         SenderBox was consistent with the PAL of WollMux at the time of selection.
         The method uses the same format for sender as is used by the
         XPALProvider:getCurrentSender().
        */
       void setCurrentSender([in] string sender, [in] short index);
    
       /**
         Returns the sender data selected in WollMux at the current time (the
         document command WM(CMD'insertValue' DB_SPALTE'<dbColumn>') into a document) in a
         document) in an array of PropertyValue objects.
         back. Here the attributes PropertyValue.Name represent the
         available DB_SPALTEs and the PropertyValue.Value attributes represent the
         DB_SPALTE related sender data.
    
         Each call creates a completely new and independent object with all the
         entries that are valid at that time. A change of the values of the
         return object therefore has no effect on the WollMux.
    
         @return Array of PropertyValue objects with the sender data currently set in the WollMux.
                 sender data. If there is no sender data, the array is empty (but
                 != null).
        */
       com::sun::star::beans::PropertyValues getInsertValues();
    
       /**
         This method returns the value of the sender data to the database column dbColumn,
         which corresponds to the value returned by the document command WM(CMD'insertValue'
         DB_SPALTE'<dbColumn>') would insert into the document, or the empty string ""
         if this value cannot be determined (e.g. if an invalid
         column name dbColumn was passed).
    
         Note: This method is complemented by the getInsertValues() method which will
         can return all column names and column values.
    
         @param dbColumn
                  Name of the database column whose value is to be returned.
         @return The value of the database column dbSpalte of the currently selected
                 sender or "" if the value cannot be determined.
        */
       string getValue([in] string dbColumn);
    
       /**
         Does the same as XWollMuxDocument wdoc = getWollMuxDocument(doc); if (wdoc !=
         null) wdoc.addPrintFunction(functionName) and should be replaced with these instructions
         statements accordingly.
    
         @param doc
                  The document to which the print function functionName should be added.
                  should be added.
         @param functionName
                  the name of a print function that must be defined in the "Print Functions" section of the
                  WollMux configuration.
         @deprecated since 2009-09-18
        */
       void addPrintFunction([in] com::sun::star::text::XTextDocument doc, [in] string functionName);
    
       /**
         Does the same as XWollMuxDocument wdoc = getWollMuxDocument(doc); if (wdoc !=
         null) wdoc.removePrintFunction(functionName) and should be replaced by these instructions
         statements accordingly.
    
         @param doc
                  The document from which the functionName print function should be taken.
         @param functionName
                  the name of a print function set in the document.
         @deprecated since 2009-09-18
       */
       void removePrintFunction([in] com::sun::star::text::XTextDocument doc, [in] string functionName);
    
       /**
         Allows access to WollMux functions that are specific to the document
         doc. Currently, only a c.s.s.t.TextDocument is possible as doc. If a
         document is passed, for which WollMux does not offer any functions (currently for example a
         for example a Calc document), then null is returned. The fact that this function
         returns a non-null object, however, does not necessarily mean that the
         WollMux provides meaningful functions for the document. It is possible that
         calls to the corresponding functions of the XWollMuxDocument interface do nothing.
         do.
    
         Note on synchronization: Calls of the functions of XWollMuxDocument may
         be done immediately without further synchronization. However
         getWollMuxDocument() in no way replaces synchronization with WollMux.
         In particular, it is possible that getWollMuxDocument() returns BEFORE the
         WollMux has processed the document doc. Compare the description of
         XWollMuxDocument.
    
         @param doc
                  A LibreOffice document in which document specific functions of the
                  WollMux should be called.
         @return Returns null, if doc is not processed by WollMux and an instance of XWollMuxDocument is defined.
                 instance of XWollMuxDocument if doc is a WollMux document in principle.
                 WollMux document.
        */
       XWollMuxDocument getWollMuxDocument([in] com::sun::star::lang::XComponent doc);
    };

    The following sections describe how this interface can be used in a useful way based on scenarios that have been relevant in practice so far:

    Synchronization of other applications with the WollMux

    WollMux offers many features, such as the ability to merge multiple fragments into one document, which can and should be of interest in other extensions to LibreOffice. To allow these applications to access the results of document processing by WollMux, an event mechanism has been introduced to achieve synchronization with WollMux. For this purpose, the other application registers a com.sun.star.document.XEventListener object in WollMux, which is informed when the status of document processing changes. The other application can thus react specifically to certain events of the WollMux.

    The WollMux service created above implements the com.sun.star.document.XEventBroadcaster interface with the following methods for this purpose:

    published interface XEventBroadcaster: com::sun::star::uno::XInterface
    {
     /**
      * This method registers a listener in WollMux, through which WollMux will be
      * informs about the status of the document processing (e.g. when a document is
      * has been completely processed/expanded). The method ignores all
      * XEventListenener instances that have already been registered.
      * Multiple registration of the same instance is therefore not possible.
      *
      * If a corresponding event occurs, then the call of the
      * corresponding methods XEventListener.notifyEvent(...) is always called simultaneously
      * (i.e. for each listener in a separate thread).
      *
      * The WollMux currently delivers the following events:
      *
      * OnWollMuxProcessingFinished: This event is generated when a
      * text document has been completely processed by WollMux after opening and
      * expanded or for all other document types directly after * opening.
      * opening. I.e. for each document opened in LibreOffice sooner or later * such an event is generated.
      * such an event occurs. If a new EventHandler is registered, then it is assigned
      * for all already open LibreOffice documents the
      * OnWollMuxProcessingFinished events are delivered to it.
      *
      * @param l
      * The XEventListener that should be informed in case of status changes of the
      * document processing should be informed.
      *
      * @author Christoph Lutz (D-III-ITD-5.1)
      */
     [oneway] void addEventListener( [in] XEventListener Listener );
    
     /**
      * This method deregisters an XEvent registered with registerEventListener(XEventListener
      * l) registered XEventListener.
      *
      * @param l
      * the XEventListener to deregister.
      *
      * @author Christoph Lutz (D-III-ITD-5.1)
      * @see com.sun.star.document.XEventBroadcaster#removeEventListener(com.sun.star.document.XEventListener)
      */
     [oneway] void removeEventListener( [in] XEventListener Listener );
    };

    The following WollMux document events can currently be intercepted via this mechanism:

    • OnWollMuxProcessingFinished: This event is generated when a text document has been fully processed and expanded by WollMux after opening, or for all other document types, immediately after opening. I.e. for every document opened in LibreOffice sooner or later such an event is generated. If a new EventHandler is registered, then for all already open LibreOffice documents the OnWollMuxProcessingFinished' events will be delivered to it.

    If such an event occurs, then WollMux calls the XEventListener.notifyEvent(com.sun.star.document.EventObject event) method on all registered XEventListener objects. This EventObject contains two important values:

    • EventObject.EventName: Contains the name of the event as described above as a string.
    • EventObject.Source: Contains the corresponding document of type com.sun.star.lang.XComponent to which the event refers.

    Example implementation - loadComponentFromURLAndWaitForWollMux

    The following Java class contains an example of how the event mechanism can be used. It provides a loadComponentFromURLAndWaitForWollMux(...) method that can be used to open a document in LibreOffice. However, the method does not return until WollMux has fully processed the document. The class can also be used directly in custom applications if needed:

    import com.sun.star.beans.PropertyValue;
    import com.sun.star.document.EventObject;
    import com.sun.star.document.XEventBroadcaster;
    import com.sun.star.document.XEventListener;
    import com.sun.star.io.IOException;
    import com.sun.star.lang.IllegalArgumentException;
    import com.sun.star.lang.XComponent;
    import com.sun.star.uno.UnoRuntime;
    import de.muenchen.allg.afid.UNO;
    
    public class WollMuxSensitiveLoader {
    
    /**
     * Does the same as UNO.loadComponentFromURL(URL, asTemplate,
     * allowMacros), but waits after execution until the WollMux
     * has finished its document processing. Only then does the method
     * returns. If no WollMux is installed, then the method returns directly after
     * execution of loadComponentFromURL(...).
     *
     * @param URL
     * see
     * {@link UNO#loadComponentFromURL(String, boolean, boolean)}
     * @param asTemplate
     * see
     * {@link UNO#loadComponentFromURL(String, boolean, boolean)}
     * @param allowMacros
     * see
     * {@link UNO#loadComponentFromURL(String, boolean, boolean)}
     * @param hidden
     * see
     * {@link UNO#loadComponentFromURL(String, boolean, boolean, boolean)}
     * @param timeoutSeconds
     * number of seconds to wait for the WollMux.
     * (if it is installed) before the method returns after loading * the document in any case.
     * the document in any case.
     * @return Returns an instance on the new loaded XComponent.
     * @throws IOException
     * @throws IllegalArgumentException
     *
     * @author Christoph Lutz (D-III-ITD-5.1)
     */
     public static XComponent loadComponentFromURLAndWaitForWollMux(String URL,
         boolean asTemplate, boolean allowMacros, boolean hidden,
         int timeoutSeconds) throws IOException, IllegalArgumentException {
    
       final XComponent[] compo = new XComponent[2];
    
       final XEventBroadcaster broadcaster = UNO.XEventBroadcaster(UNO.createUNOService("de.muenchen.allg.itd51.wollmux.WollMux"));
    
       if (broadcaster != null) {
    
         // WollMux installed:
         broadcaster.addEventListener(new XEventListener() {
           public void disposing(com.sun.star.lang.EventObject arg0) {}
    
           public void notifyEvent(EventObject e) {
             synchronized (compo) {
               if ("OnWollMuxProcessingFinished".equalsIgnoreCase(e.EventName)
                   && UnoRuntime.areSame(compo[0], e.Source)) {
                 broadcaster.removeEventListener(this);
                 compo[1] = compo[0];
                 compo.notify();
               }
             }
           }
         });
    
         synchronized (compo) {
           // Execute LoadComponentFromURL:
           compo[0] = UNO.loadComponentFromURL(URL, asTemplate, allowMacros, hidden);
           // Wait until the WollMux is ready or timeoutSeconds have passed:
           try {
             long endTime = timeoutSeconds * 1000 + System.currentTimeMillis();
             while (compo[1] == null) {
               long ctime = System.currentTimeMillis();
               if (ctime >= endTime) break;
               compo.wait(endTime - ctime);
             }
           } catch (InterruptedException i) {}
         }
    
       } else {
    
         // No WollMux - execute LoadComponentFromURL normally:
         compo[0] = UNO.loadComponentFromURL(URL, asTemplate, allowMacros, hidden);
    
       }
       return compo[0];
     }
    }

    This method checks if the WollMux service exists and exports the XEventBroadcaster interface. If this condition is not met, then the WollMux directly calls the UNO.loadComponentFromURL(...) method. If the condition is met, then an XEventListener object is created via an anonymous class and registered with broadcaster.addEventListener(...). After the document has been loaded and the WollMux has called the notifyEvent method of the anonymous listener object, the listener is deregistered again.

    The following example method illustrates how the above class can be used:

    public static void main(String[] args) throws Exception {
    
       UNO.init();
       XComponent compo = loadComponentFromURLAndWaitForWollMux("file:///tmp/test.ott)",true, true, 20);
    
       System.out.println("The document is now completely built (if at least WollMux 3.11.2 is used).");
    
       // Check - is the sender data complete?
       try {
          XTextFrame frame = UNO.XTextFrame(UNO.XTextFramesSupplier(compo).getTextFrames().getByName("Sender data"));
    
          System.out.println("Sender data" + frame.getText().getString() + "'");
       } catch (NoSuchElementException e) {
          System.out.println("This document is missing the text frame 'Sender Data' or the WollMux is not installed.");
       }
    
       System.exit(0);
    }

    This method opens the /tmp/test.ott template. The call to loadComponentFromURLAndWaitForWollMux(...) will not return until the WollMux has completely built the document or a timeout of 20 seconds has elapsed. To check whether the document has actually been completely built, the program checks whether a text frame "Sender data" exists in the generated document and outputs the contents of this text frame if necessary. To test this function, a template created via a mixed template for the external letterhead was used for /tmp/test.ott. It contains the instructions that ensure that the "Sender data" text frame is subsequently included in the document.

    Attention: In all examples above a helper class de.muenchen.allg.afid.UNO is used. This class is available in a separate GitHub project WollMux/UNOHelper. However, above examples can be rewritten relatively easily if needed so that this dependency is no longer necessary. All other imported modules are components of the standard JAR packages of LibreOffice and/or the Java environment. No WollMux-specific JAR packages are required to run the above examples. For this mechanism to work, at least a WollMux 3.11.2 must be installed.

    Embedding a SenderBox

    A SenderBox is able to display the Personal Sender List (PAL) of the letterhead system and select a specific sender from it. Such a SenderBox is currently included in the WollMuxBar, for example. Access to the contents of the PAL works via a listener callback mechanism. The WollMux service created above implements the interface de.muenchen.allg.itd51.wollmux.XPALChangeEventBroadcaster for this purpose:

    /**
      The interface XPALChangeEventBroadcasteristener defines a broadcaster that reports on
      Changes to the personal sender list (PAL) can inform. It contains
      Methods to register and deregister XPALChangeEventListeners.
     */
    interface XPALChangeEventBroadcaster
    {
       /**
         This method registers an XPALChangeEventListener which receives updates
         when the PAL changes. After registration, an
         ON_SELECTION_CHANGED event is triggered, which ensures that a first update of all
         a first update of all listeners is executed. The method ignores
         all XPALChangeEventListener instances that have already been registered.
         So multiple registration of the same instance is not possible.
        */
       void addPALChangeEventListener( [in] XPALChangeEventListener listener);
    
       /**
         This method registers an XPALChangeEventListener, which receives updates
         when the PAL changes; after registration it checks if the WollMux and the
         the WollMux and the XPALChangeEventListener use the same WollMux configuration, which
         for which the listener sends the hash code wollmuxConfHashCode of the current WollMux configuration.
         WollMux configuration. If wollmuxConfHashCode does not match with the
         HashCode of the WollMux configuration of the WollMux, a dialog appears which
         dialog appears, which warns about possible errors. After registration immediately
         an ON_SELECTION_CHANGED event is triggered, which ensures that an
         immediately a first update of all listeners is executed. The method
         ignores all XPALChangeEventListenener instances that have already been registered.
         have been registered. So multiple registration of the same instance is not possible.
    
         @param l
                  The XPALChangeEventListener to be registered.
         @param wollmuxConfHashCode
                  The HashCode of the WollMux-Config which is used for the consistency check.
                  and will be retrieved via
                  WollMuxFiles.getWollMuxConf().getStringRepresentation().hashCode()
                  is generated.
        */
       void addPALChangeEventListenerWithConsistencyCheck( [in] XPALChangeEventListener listener, [in] long wollmuxConfHashCode);
    \
       /**
         This method deregisters an XPALChangeEventListener if it was already registered.
         registered.
        */
       void removePALChangeEventListener( [in] XPALChangeEventListener listener);
    };

    Via addPALChangeEventListener an object of type de.muenchen.allg.itd51.wollmux.XPALChangeEventListener can be registered in WollMux. This XPALChangeEventListener must of course be implemented beforehand, e.g. via a Java class written by the user:

    /**
      The interface XPALChangeEventListener defines a listener, which can change the
      Personal Sender List (PAL) can handle.
    
      See also XPALChangeEventBroadcaster, where the listener can be registered.
     */
    interface XPALChangeEventListener
    {
        // Derivation from the standard XEventListener
        interface com::sun::star::lang::XEventListener;
    
        /**
          The method will be called on every change (adding and removing entries or
          when a new sender is set) to the personal sender list.
          The eventObject.Source contains the XPALProvider whose PAL has changed. The
          passed XPALProvider can be used to rebuild the sender list.
         */
        void updateContent( [in] com::sun::star::lang::EventObject eventObject );
    };

    Immediately after registration and whenever the PAL is changed, the de.muenchen.allg.itd51.wollmux.XPALChangeEventListener is informed via the updateContent(EventObject eventObject) method. Now the eventObject.Source field contains an instance of type de.muenchen.allg.itd51.wollmux.XPALProvider:

    /**
      The interface XPALProvider provides methods for reading the current
      Personal Sender List (PAL).
     */
    interface XPALProvider
    {
        /**
          This method returns an alphabetically ascending sorted list of
          string representations of all entries in the personal sender list (PAL)
          in a string array. The exact form of the string representations is not
          by this interface, but in the case of WollMux it depends on the value of
          depends on the value of SENDER_DISPLAYTEMPLATE in the WollMux configuration.
          Independent of SENDER_DISPLAYTEMPLATE, the string representations returned by this method contain
          method will always contain the string "§" at the end of the string.
          the string "§§&amp;=&amp;§§" followed by the key of the corresponding entry!
          corresponding entry!
         */
         sequence< string > getPALEntries();
    
        /**
          This method returns a string representation of the entry currently selected from the
          personal sender list (PAL).
          The exact form of the string representation is not prescribed by this interface.
          but, in the case of WollMux, depends on the value of
          SENDER_DISPLAYTEMPLATE in the WollMux configuration.
          Independently of SENDER_DISPLAYTEMPLATE the string representation returned by this method contains
          method always contains the string "§§&amp;§§&amp;§§" at the end.
          the string "§§&amp;=&amp;§§" followed by the key of the currently selected sender.
          sender.
          If the PAL is empty or if no sender has been selected yet, the method
          returns the empty string "". This special case should of course be handled accordingly
          by the calling method.
    
          @return the sender currently selected from the PAL as a string. If no
                  sender is selected, the empty string "" is returned.
         */
         string getCurrentSender();
    };

    Using the getPALEntries() and getCurrentSender() methods, there is now read access to the contents of the Personal Sender List and the currently selected sender.

    To set a new sender the above WollMux service offers the method setSender(...). The method is defined in the interface de.muenchen.allg.itd51.wollmux.XWollMux, which the WollMux service also implements.

    /**
      This interface describes all methods exported by the WollMux service.
    */
    interface XWollMux
    {
        [...]
    
        /**
          This method sets the current sender of the personal sender list
          (PAL) to the sender sender. The sender will only be set if the
          parameters sender and idx in the alphabetically sorted sender list of the
          WollMux match - i.e. the sender list of the initiating
          SenderBox was consistent with the PAL of WollMux at the time of selection.
          The method uses the same format for sender as is used by the
          XPALProvider:getCurrentSender().
         */
        void setCurrentSender([in] string sender, [in] short index);
    
        [...]
    };

    Read data of the sender currently set in WollMux

    The main task of WollMux is to process and manipulate text documents. However, it is conceivable that WollMux data should also be processed in other applications, for example, to transfer data of the sender currently set in WollMux to a Calc table. The corresponding access is provided by the methods getInsertValues() and getValue(dbColumn), which are defined in the interface XWollMux:

    /**
      This interface describes all methods exported by the WollMux service.
    */
    interface XWollMux
    {
        [...]
    
       /**
         Returns the sender data selected in WollMux at the current time (the
         the document command WM(CMD'insertValue' DB_SPALTE'<dbSpalte>') into a
         document) in an array of PropertyValue objects.
         back. Here the attributes PropertyValue.Name represent the
         available DB_SPALTEs and the PropertyValue.Value attributes represent the
         DB_SPALTE related sender data.
    
         Each call creates a completely new and independent object with all the
         entries that are valid at that time. A change of the values of the
         return object therefore has no effect on the WollMux.
    
         @return Array of PropertyValue objects with the sender data currently set in the WollMux.
                 sender data. If there is no sender data, the array is empty (but
                 != null).
        */
        com::sun::star::beans::PropertyValues getInsertValues();
    
       /**
         This method returns the value of the sender data to the database column dbColumn,
         which corresponds to the value returned by the document command WM(CMD'insertValue'
         DB_SPALTE'<dbColumn>') would insert into the document, or the empty string ""
         if this value cannot be determined (e.g. if an invalid
         column name dbColumn was passed).
    
         Note: This method is complemented by the getInsertValues() method which will
         can return all column names and column values.
    
          @param dbColumn
                   Name of the database column whose value is to be returned.
          @return The value of the database column dbSpalte of the currently selected
                  sender or "" if the value cannot be determined.
         */
        string getValue([in] string dbColumn);
    
        [...]
    };

    The following example (in LibreOffice Basic) shows how this method can be used to transfer the column values "First Name" and "Last Name" (of the currently set sender) into the first two cells of a Calc table:

    Sub clerkDataInCalcInsert
       mux = createUNOService("de.muenchen.allg.itd51.wollmux.WollMux")
       firstname = mux.getValue("firstname")
       lastname = mux.getValue("lastname")
    
       sheet = ThisComponent.Sheets.getByIndex(0)
    
       cell1a = sheet.getCellByPosition(0,0)
       cell1b = sheet.getCellByPosition(1,0)
    
       cell1a.setString(firstName)
       cell1b.setString(lastName)
    End Sub

    Execute document specific actions

    In addition to the global WollMux functions described above, the WollMux API offers certain actions exclusively in connection with documents that are currently being processed. The use of these functions therefore only affects a specific document and is therefore document-specific. To access document-specific functions, the XWollMux interface provides the getWollMuxDocument(XComponent compo) method:

    /**
      This interface describes all methods exported by the WollMux service.
    */
    interface XWollMux
    {
    
       [...]
    
       /**
         Provides access to WollMux functions which are specific to the document
         doc. Currently only a c.s.s.t.TextDocument is possible as doc. If a
         document is passed, for which WollMux does not offer any functions (currently for example a
         for example a Calc document), then null is returned. The fact that this function
         returns a non-null object, however, does not necessarily mean that the
         WollMux provides meaningful functions for the document. It is possible that
         calls to the corresponding functions of the XWollMuxDocument interface do nothing.
         do.
    
         Note to synchronization: Calls of the functions of XWollMuxDocument may
         be done immediately without further synchronization. However
         getWollMuxDocument() in no way replaces synchronization with WollMux.
         In particular, it is possible that getWollMuxDocument() returns BEFORE the
         WollMux has processed the document doc. Compare the description of
         XWollMuxDocument.
    
         @param doc
                  A LibreOffice document in which document specific functions of the
                  WollMux should be called.
         @return Returns null, if doc is not processed by WollMux and an instance of XWollMuxDocument is defined.
                 instance of XWollMuxDocument, if doc is a WollMux document in principle.
                 WollMux document.
        */
       **XWollMuxDocument getWollMuxDocument([in]
    com::sun::star::lang::XComponent doc);**\
    \
       [...]
    };

    The interface XWollMuxDocument is defined as follows:

    /**
      This interface describes methods of WollMux, which are only document specific.
      specific. An instance of the interface can be requested via the method
      XWollMux.getWollMuxCocument(c.s.s.l.XComponent compo). It is possible that
      calls to some functions do nothing in the context of the associated document
      (e.g. if the document contains no inserts and setFormValue(...) is called).
      is called).
    
      Note about synchronization: function calls in XWollMuxDocument are usually
      automatically synchronized with WollMux. Nevertheless it should be ensured that
      that WollMux has completely processed the corresponding document before using the methods of this interface.
      of this interface are used. Otherwise it could be, for example, that the document has not yet been
      document is not yet completely built, and actions like setFormValue() have no effect, although the
      even though the fully constructed document has insertFormValue insertions.
      are present.
    */
    interface XWollMuxDocument
    {
    
       /**
          Sets the value to be inserted with insertValue document commands with DB_SPALTE "dbColumn"\
          to be inserted to value. It is not guaranteed that the new value will be visible in the
          document before updateInsertFields() is called. A
          implementation with a queue is possible.
    
          Remark: A list of all available DB_SPALTEs can be retrieved with the method
          XWollMux.getInsertValues().
    
          @param dbColumn
                   contains the name of the sender data column whose value is to be changed.
                   should be changed.
          @param value
                   contains the new value for dbColumn.
        */
       void setInsertValue([in] string dbColumn, [in] string value);
    
       /**
          Sets the value with ID id in the form GUI to value with all the consequences that this entails (PLAUSIs).
          (PLAUSIs, AUTOFILLs, fade in/out,...). It is not
          guaranteed that the function is executed before updateFormGUI() is called.
          has been called. An implementation with a queue is possible.
    
          Remark: A list of all available IDs can be retrieved using the method
          XWollMuxDocument.getFormValues().
    
                @param id
                   ID to which the new form value should be set.
          @param value
                   The new form value to be set.
        */
    void setFormValue([in] string id, [in] string value);
    
       /**
          Returns the form values set at the current time for this
          WollMux document in an array of PropertyValue objects. Here
          the attributes PropertyValue.Name represent the available IDs
          and the attributes PropertyValue.Value represent the form values associated to ID.
    
          Each call creates a completely new and independent object with all the
          entries that are valid at that time. A change of the values of the
          return object therefore has no effect on the WollMux.
    
          @return Array of PropertyValue objects with the currently set
                  form values of this WollMux document. If there are no form values
                  in the document, the array is empty (but != null).
        */
       com::sun::star::beans::PropertyValues getFormValues();
    
       /**
          Ensures execution of all setInsertValue() commands not yet executed.
          commands. The method is guaranteed not to return until all the
          setInsertValue() commands have had their effect in WollMux and in the corresponding
          document.
        */
       void updateInsertFields();
    
       /**
          Ensures execution of all setFormValue() commands that have not yet been executed.
          commands. The method is guaranteed to return only after all the
          setFormValue() commands have had their effect in WollMux and in the corresponding
          document.
        */
       void updateFormGUI();
    
          /**
          Adds the print function functionName to the list of print functions of the
          document. The print function is automatically activated when the document is
          document is to be printed the next time with File->Print. If the
          function is already in the list of print functions of the document, nothing happens.
    
          Note: The execution is asynchronous, i.e. addPrintFunction() may return BEFORE the
          may return BEFORE the method has taken effect.
    
          @param functionName
                   the name of a print function that must be defined in the "Print Functions" section of the
                   WollMux configuration.
        */
       void addPrintFunction([in] string functionName);
    
       /**
          Deletes the print function functionName from the list of print functions of the
          document. The print function will thus no longer be called after the next call of
          File->Print will no longer be called. If the print function is not in the list of
          of the document's print functions, nothing happens.
    
          Note: The execution is asynchronous, i.e. removePrintFunction() returns
          may return BEFORE the method has taken effect.
    
          @param functionName
                   the name of a print function set in the document.
        */
       void removePrintFunction([in] string functionName);
    
    };

    This interface can be used in practice for the following scenarios, for example:

    Modifying fields in WollMux documents

    An important use case is the subsequent modification of values set by WollMux or the user. Thus, an external application can emulate certain WollMux or user inputs. In doing so, the external application can access all other features that WollMux provides, e.g. for user inputs. This includes in particular the execution of transformation functions (TRAFOS) and the control of fade in/out via certain form values. The interface XWollMuxDocument allows the subsequent manipulation of sender information and the setting of form values:

    • The void setInsertValue(\[in\] string dbColumn, \[in\] string value) method: This method allows to re-execute

    insertValue commands already processed by WollMux. All insertValue commands contained in the document whose DB_SPALTE attributes match dbColumn will be re-executed and recalculated for the value value, taking into account any TRAFO functions that may have been set, and written to the document. The sender information previously set by WollMux will be overwritten. The new values may only be active in the document after execution of the updateInsertFields() function.

    • The void updateInsertFields() method: this method ensures that previous setInsertValue(\[in\] string dbColumn, \[in\] string value) commands were actually executed.
    • The com::sun::star::beans::PropertyValues getFormValues() method: This method can be used to read the form values currently set in the form. The method returns an array of PropertyValue objects whose Name attributes represent the IDs available in the document and whose Value attributes represent the form values set at the time of the call. For example, this method can be used to determine which ID-value pairs can be set via setFormValue(id, value).
    • The void setFormValue(\[in\] string id, \[in\] string value) method: This method allows setting specific form values. If the document has a form description, a value value is entered directly in the form field with id id in the associated form GUI and all consequences of this entry (AUTOFILLS, PLAUSIS, show/hide) are executed. If the document does not have a form description, but has form fields with the ID id (such as RecipientLineN in the external letterhead), only the form fields in the document are adjusted accordingly. The new values may not be active in the document until the updateFormGUI() function is executed.
    • The void updateFormGUI() method: this method ensures that previous void setFormValue(\[in\] string id, \[in\] string value) commands were actually executed.

    The following code example (in Java) demonstrates how changing fields is possible via the WollMux service:

    XWollMux mux = (XWollMux) UnoRuntime.queryInterface(XWollMux.class, UNO.createUNOService("de.muenchen.allg.itd51.wollmux.WollMux"));
    if (mux != null)
    {
      XWollMuxDocument doc = mux.getWollMuxDocument(compo);
      if (doc != null)
      {
        // Setzen von insertValues:
        doc.setFormValue("EmpfaengerZeile1", "My dear Mr. Choral Society");
        doc.setFormValue("SGAnrede", "Mr");
        doc.updateFormGUI();
        System.out.println("SetFormValues done");
    
        // Set form values:
        doc.setInsertValue("LastName", "WholeMilk");
        doc.setInsertValue("Phone", "1234567");
        doc.setInsertValue("Title", "Prof.");
        doc.updateInsertFields();
        System.out.println("SetInsertFields done");
      }
    }

    Programmatic setting of convenience print functions

    Comfort print functions can either be set manually during template creation via FormularMax 4000 or programmatically. This can be useful in some cases, e.g. if an external macro is to recognize on the basis of a certain logic whether a convenience print function is useful for a certain document. In this case, the following methods are available in the XWollMuxDocument interface:

    • The method void addPrintFunction(\[in\] string functionName): This method adds the print function functionName to the list of print functions of the document. The print function is thereby automatically active the next time the document is to be printed with File->Print. If the print function is already included in the list of print functions of the document, nothing happens. Here the parameter functionName expects the name of a print function, which must be defined in the section "Print functions" of the WollMux configuration.
    • The void removePrintFunction(\[in\] string functionName) method: this method deletes the functionName print function from the document's list of print functions. The print function is thus no longer called from the next call to File->Print. If the print function is not in the document's list of print functions, nothing happens.

    Example of using addPrintFunction(...) in a Basic macro:

    Sub Main
      doc = ThisComponent
      mux = createUNOService("de.muenchen.allg.itd51.wollmux.WollMux")
      wmDoc = mux.getWollMuxDocument(doc)
      if(NOT isNull(wmDoc)) then
        wmDoc.addPrintFunction("PrintSerialWithoutSelection")
      endif
    End Sub

    Include your own convenience print functions

    When printing a document via "File→Print..." or the Print button in the toolbar, WollMux can call self-defined convenience print functions instead of the normal print dialog. Thereby several comfort print functions can be stored in each document and can be chained together in a defined order. For example, it is possible to link the convenience print function for Content based directives with the convenience print function for serial letters. This can save users a great deal of time and unnecessary manual work.

    Inclusion in document or template

    The information which print functions are currently to be used is persistently stored under the metadata key 'PrintFunction' in the corresponding document or template and read from there. Helpful is the menu item 'PrintFunction' of the FormularMax 4000, through which the print functions of the document can easily be edited manually. Via the now obsolete document command setPrintFunction, it is also possible to add individual print functions to the list of print functions. Furthermore, WollMux offers the possibility to programmatically set or remove convenience print functions from a document. This possibility is described in more detail in section programmatic setting of comfort print functions.

    Registration in the print functions section

    All print functions listed in the document must be globally defined in a section Print functions in the wollmux.conf configuration file. Each entry in this section consists of the function identifier and the reference to a physically existing function, which must be written in Java. For example, the definition of the function with the function identifier "SachleitendeVerfuegung" looks like the following:

    Print Functions(
      SachleitendeVerfuegung(EXTERN(URL "java:en.muenchen.allg.itd51.wollmux.func.StandardPrint.sachleitendeVerfuegung") ORDER "10")
    )

    In the example, the associated print function is written in Java. Here is an excerpt from the corresponding Java file StandardPrint.java:

    public static void sachleitendeVerfuegung(XPrintModel pmod)
    {
      // [...] start dialog
    }

    XPrintModel

    Each print function is passed an object of type de.muenchen.allg.itd51.wollmux.XPrintModel. Through this interface, the print function can access print operations or other functionality of WollMux in a simplified way:

    /**
      Each print function is passed an XPrintModel object when it is called.
      access to the document and convenience methods for printing.
      are available. Different print functions can be combined to a
      call chain.
     */
    interface XPrintModel
    {
    
       /**
        * Each print function can use this interface to set any function-specific
        * properties in the XPrintModel, which can be evaluated by other print functions in the * call chain of the XPrintModel.
        * call chain of the XPrintModel. Deviating from the
        * default behavior of XPropertySet, this implementation accepts all * property names and adds new
        * property names and adds new properties if they do not already exist.
        * are.
        */
       interface com::sun::star::beans::XPropertySet;
    
       /**
        * Loads the print function defined in wollmux.conf with the name
        * functionName into the XPrintModel and places it according to the ORDER attribute at the
        * correct position in the call chain of the print functions to be processed.
        * If the print function is called, then it gets exactly one argument
        * (this XPrintModel) is passed.
        *
        * @param functionName
        * Name of the print function to be managed by the MasterPrintModel.
        * should be managed.
        * @throws NoSuchMethodException.
        * Thrown if the print function is not defined.
        */
       void usePrintFunction([in] string functionName) raises ( com::sun::star::lang::NoSuchMethodException );
    
       /**
        * Returns the XTextDocument with which the print function was called.
        */
       com::sun::star::text::XTextDocument getTextDocument();
    
       /**
        * This method calls numberOfCopies times printWithProps().
        */
       void print( [in] short numberOfCopies);
    
       /**
        * Prints the TextDocument to the currently set printer or forwards * the request to the next available printer.
        * the request to the next available print function in the call chain,
        if another print function is available; depending on the * print function set, various properties are
        * print function, different properties are set, which can be set via
        * setPropertyValue(...) are evaluated. The method returns only
        * only returns when the entire print operation of this and the underlying * print functions has been completed.
        * print functions has been completely executed.
        */
       void printWithProps();
    
       /**
        * If the associated document is a form document (with a form description), the
        * a form description), the form field with the ID id
        * is set to the new value and all form fields that depend on * this form field are adjusted accordingly.
        * will be adjusted accordingly. If the
        * associated document is a document without a form description, then
        * only all insertFormValue commands of this document that have the ID
        * id.
        *
        * @param id
        * The ID of the form field whose value is to be changed.
        * If the FormGUI is active, all id-dependent
        * form values will be reset.
        * @param value
        * The new value of the form field id
        */
       void setFormValue( [in] string id, [in] string value);
    
       /**
        * Returns true, if the document is marked as "modified" and therefore
        * e.g. the "Save?" prompt appears before closing.
        *
        * Some print functions may modify the contents of documents. Nevertheless
        * it may be that such a print function must not change the "Modified" status of the * document to avoid unwanted "Save?
        * document to prevent unwanted "Save?" prompts from appearing.
        * queries. In this case, the "Modified" status can be left unchanged * with the following construct within the print function.
        * construct within the print function to keep it unchanged:
        *
        * boolean modified = pmod.getDocumentModified();
        *
        * ...the actual print function that modifies the document....
        *
        * pmod.setDocumentModified(modified);
        */
       boolean getDocumentModified();
    
       /**
        * This method sets the DocumentModified status to modified.
        */
       void setDocumentModified( [in] boolean modified);
    
       /**
        * Collects all form fields of the document that are not surrounded by
        * WollMux commands, but are still understood and filled by WollMux.
        * and filled (currently c,s,s,t,textfield,database fields). Thus
        * e.g. mail merge fields are recognized, which have been added * manually after opening the document.
        * manually after opening the document.
        */
       void collectNonWollMuxFormFields();
    
       /**
        * This method sets the properties "Visible" and the * display of the background color.
        * display of the background color (showHighlightColor) for all print blocks
        * of a given block type blockName (e.g. "AllVersions").
        *
        * @param blockName
        * The block type whose print blocks are to be handled.
        * The following block names are currently supported: "AllVersions",
        * "DraftOnly", "OriginalOnly", "CopyOnly" and "NotInOriginal "*.
        * @param visible
        * The block will be visible if visible==true and invisible if
        * visible==false.
        * @param showHighlightColor
        * specifies whether the background color should be shown (applies only,
        * if a background color is also specified for an * affected print block).
        * is specified).
        *
        * @author Christoph Lutz (D-III-ITD-5.1)
        */
       void setPrintBlocksProps([in] string blockname, [in] boolean visible, [in] boolean showHighlightColor);
    
       /**
        * Sets the visibility status of the visibility group groupID to the
        * new status visible and thus affects all document commands.
        * WM(CMD'setGroups'...) or all text areas that have a * GROUPS assignment.
        * GROUPS assignment linked the visibility group groupId.
        *
        * @param groupID
        * Name of the visibility group whose visibility status is to be * changed.
        * is to be changed
        * @param visible
        * If true, the visibility group is visible, and if * false, it is invisible.
        * false invisible.
        */
       void setGroupVisible([in] string groupID, [in] boolean visible);
    
       /**
        * Returns true if printing was aborted due to user input or a * previous error.
        or a previous error (see cancel()) and should be * evaluated especially by print
        * especially be evaluated by print functions which print several times
        * printWithProps() several times and have to perform time-consuming pre- and post-processing
        * (which in this case can be set as soon as reasonably possible).
        */
       boolean isCanceled();
    
       /**
        * Sets the flag isCanceled() to true and makes sure that future calls
        * of printWithProps() return immediately without effect. The method can be called by
        * any print function if errors occur or if the print * operation is canceled by the user.
        * printing process has been canceled by the user.
        */
       void cancel();
    
       /**
        * This method activates the progress bar display and initializes * the number of versions expected by this print function to maxValue.
        * the number of versions expected from this print function to maxValue,
        * if maxValue is greater than 0, or removes the print function from the * progress bar if maxValue is greater than 0.
        * progress bar if maxValue is equal to 0. The progress indicator is
        * in principle capable of displaying the print status of various concatenated * print functions.
        * print functions. The calculation of the total number of copies and the
        * current total status is taken over by the progress indicator. This means that
        * each print function must also set here only the number of versions generated by the * print function itself.
        * print function itself.
        *
        * @param maxValue
        * the maximum value of the copies to be printed by this * print function.
        * copies.
        */
       void setPrintProgressMaxValue([in] short maxValue);
    
       /**
        * This method sets a new progress status to the progress bar.
        * value (=number of versions actually printed so far) of the current * print function.
        * print function. The value value must be in the range 0 <= value <=
        * maxValue (see setPrintProgressMaxValue(maxValue)).
        *
        * @param value
        * The number of versions actually printed by this print function so far.
        * printed versions. It must be true: 0 <= value <= maxValue
        */
       void setPrintProgressValue([in] short value);
    };

    The methods print(n) or printWithProps() and the corresponding properties:

    The XPrintModel.printWithProps() method plays a special role in the concept of convenience print functions. If no further convenience print function is set for this document, a final print function is started automatically, which displays a dialog for the printer settings when the document is called for the first time and prints it directly on the printer. If another convenience print function is assigned to the document, it ensures that the next convenience print function in the call chain is called. The method print(n) does nothing else than call printWithProps() n times. With both methods it is possible to influence the behavior of the called subsequent function via so-called properties. Each convenience print function in the call chain can set any properties and access all properties already set.

    Using the XPrintModel, a simple convenience print function could look like this, for example:

    public static void mySimplePrintfunction(XPrintModel pmod)
    {
       // start print
       pmod.print((short)` `2);
    }

    The example always prints the current document in duplicate on the currently set printer. Clearly, this example is not yet a function that will actually have application in practice. It only becomes interesting when the print functions make slight changes to the document before the printWithProps() method is called. For this purpose, the method getTextDocument() is available, through which full access to the TextDocument is possible. The methods setGroupVisible(...), setPrintBlocksProps(...) and setFormValue(...) can be used to make changes to the document before it is printed with pmod.printWithProps().

    Each time a method of pmod is called, it is ensured that the call is synchronous and the function does not return until the action is completely finished. So it is possible to adjust the document, then call a method of pmod (e.g. printWithProps()), change the document again and call printWithProps() again. This would always print the document in the previously set state.

    Notes:

    • Unlike normal functions, print functions are always started asynchronously in a separate thread. WollMux does not monitor whether the print function returns and whether errors occurred.
    • The external print function must accept as first and only parameter an object of type en.muenchen.allg.itd51.wollmux.XPrintModel.
    • The external print function must not return a return value, or return values are ignored.

    Chaining print functions

    The possibility of chaining print functions is presented here using the example of the convenience print functions "SachleitendenVerfuegung" and "Seriendruck". The intention is that the convenience print dialog for the Content based directives and the dialog for the mail merge are called exactly once (otherwise a separate mail merge dialog would appear for each copy of the Content based directives). In the two dialogs, the desired settings for combined printing should be made exactly once. Only after all settings have been set, the actual printing on the printer starts. To achieve this, the print function SachleitendeVerfuegung has been divided into two parts, a GUI part and an output part. Together with the print function "mail merge", the configuration section print functions therefore looks like the following, for example:

    Print functions(
      SachleitendeVerfuegung(EXTERN(URL "java:en.muenchen.allg.itd51.wollmux.func.StandardPrint.sachleitendeVerfuegung") ORDER "10")
      Mail merge(EXTERN(URL "java:en.muenchen.allg.itd51.wollmux.func.StandardPrint.mail merge") ORDER "20")
      SachleitendeVerfuegungOutput(EXTERN(URL "java:en.muenchen.allg.itd51.wollmux.func.StandardPrint.sachleitendeVerfuegungOutput") ORDER "30")  
    )

    The convenience print function "SachleitendeVerfuegung" consists thereby only of the necessary dialog, over which the associated output convenience print function "SachleitendeVerfuegungOutput" is supplied with appropriate data over properties. The print function "Serial print" also contains a dialog and is started directly after the dialog of the Content based directives. It provides a mass output as mail merge and forwards all print requests to the output convenience print function "SachleitendeVerfuegungOutput". In order for this procedure to work, the convenience print functions must therefore be called in exactly the same order as SubjectDirectiveDirective → PrintSerial → SubjectDirectiveDirectiveOutput.

    This sequence is defined in the configuration section Print functions via the attribute ORDER. All print functions that are assigned to a document are linked by WollMux to a call chain and sorted by the ORDER value. Print functions with a small order value come before print functions with a higher order value in the call chain.

    Display of the progress bar

    Print functions may have long processing times. An example of this is mail merge, whose processing time depends on the number of records in the mail merge data source. To get a better overview of the overall progress in these cases, a progress bar has been introduced. Each print function can use this progress bar to show the progress of the print process. A print function only needs to call the pmod.setPrintProgressMaxValue(maxValue) method to do this, and thus tell how many print versions are to be expected from this print function. It is thus automatically displayed the progress bar. After that, the current status of the print function can be passed to the progress bar using pmod.setPrintProgressValue(value).

    For chained print functions, the progress bar is able to automatically correctly determine the total number of print versions resulting from multiplying the maximum values of the individual print functions. Thus, each print function must set only the progress values that also occur in that print function.

    The "STAGE" property - display title of the progress window

    In addition to the display of the progress bar, the property "STAGE" can also be used to change the display title of the progress window. This makes sense e.g. if several (possibly time-consuming) steps are necessary to generate a mail merge and the user should be able to distinguish between these steps. The following code framework in Java shows how this might look:

    public static void myPrintFunction(XPrintModel pmod) {
      
        pmod.setPropertyValue("STAGE", "Print` `prepare");
     
        // ... Code that makes lengthy preparations
     
        pmod.setPropertyValue("STAGE", "Print` `perform");
     
        // ... code that starts printing, e.g. with pmod.printWithProps()
     
    }

    A set display title also applies to all print functions called by a print function until they themselves set the display title. When a print function returns (to the print function that called it), the display title is automatically set to the value that was valid before the print function was called. If the display title is not set at all, the default setting with the string "Print" will take effect.

    Integration of the WollMux interfaces into own Java components

    To use the WollMux interfaces listed in the previous sections (e.g. XWollMux, XPrintModel, ...) in own Java components, the necessary .class files must be known in the classpath of the Java compiler. To simplify the integration, there is a separate jar file called WollMuxInterfaces.jar in the download area of the WollMux binary packages since WollMux 6.7.1. You only have to add this jar file to the classpath and all X-interfaces exported by WollMux are accessible.