Export filter framework

From Apache OpenOffice Wiki
Jump to: navigation, search

Where to Start

The best thing to do in order to have a good understanding of what OO.o does when you save or export a file is to read the relevant code. A good place to start would be the SfxObjectShell::SaveTo_Impl(...) method in sfx2/source/doc/objstor.cxx. This method depicts the overall flow of the file save / file export operation, so reading that code will give you a good overview of the process. Beware, though, that the SaveTo_Impl method has roughly 600-lines of code in it. So, tracing the code there will probably drain a lot of your energy. Take a lot of vitamin before you start! :-)

The basic export framework is set by class SfxObjectShell, which is sub-classed by the document shell class of each application (Writer, Calc and Draw/Impress) to implement several virtual functions of SfxObjectShell. Class SfxMedium represents the document to be saved, and class SfxFilter represents the filter that saves the document.

The export process also makes the following distinction.

  • Native OO.o format (such as ODF) - call SfxObjectShell::SaveAsOwnFormat(...)
  • Non-native, "alien" format - call SfxObjectShell::ExportTo(...) or SfxObjectShell::ConvertTo(...), the latter being a virtual function that is overwritten by each application.

SfxFilter - The Filter Class

This method SfxFilterContainer::ReadSingleFilter_Impl() (located in sfx2/source/bastyp/fltfnc.cxx) reads each filter from the XML filter configuration files, and creates an instance of SfxFilter for each filter defined therein.

Filter configuration files

The filter configuration files are found in filter/source/config/fragments/filters, and all have an extension of .xcu. When the module is built, those fragment configuration files get merged into a single configuration file named fcfg_*_filters.xcu. These files eventually wind up in the installation tree. Look under

 <root installation directory>/share/registry/modules/org/openoffice/TypeDetection/Filter

in your OO.o installation directory.

Properties

Flags

Filter flags affect the run-time behavior of the filter. A combination of any number of the following values can be used.

  • 3RDPARTYFILTER - the filter is a UNO component filter, as opposed to the internal C++ filter. This flag is directly mapped to the internal SFX_FILTER_STARONEFILTER flag.
  • ALIEN - the filter may lose some information upon saving.
  • ASYNCHRON
  • DEFAULT
  • EXPORT - the filter supports service com.sun.star.document.ExportFilter. Provide both IMPORT and EXPORT to display the filter in the File->Save As dialog.
  • IMPORT - the filter supports service com.sun.star.document.ImportFilter. Provide both IMPORT and EXPORT to display the filter in the File->Save As dialog.
  • INTERNAL
  • NOTINCHOOSER
  • NOTINFILEDIALOG
  • OWN - the filter is a native OO.o format (ODF or otherwise).
  • PACKED
  • PREFERRED - the filter is preferred in case of multiple filters for the same file type.
  • READONLY
  • SILENTEXPORT
  • SUPPORTSSELECTION
  • TEMPLATE
  • TEMPLATEPATH
  • USESOPTIONS

These flags are loosely mapped to their corresponding internal flags named SFX_FILTER_*. Look in sfx2/inc/docfilt.hxx.

UIComponent
FilterService

The name of the service that implements the UNO filter component.

UIName
Type
DocumentService

The name of the document service that this filter belongs to. For instance, if it's a Calc-related filter, the value of this property will be com.sun.star.sheet.SpreadsheetDocument.

Export to external (alien) format

This probably covers the vast majority of the export filters. The main flow moves to either ExportTo(...) in SfxObjectShell, or ConvertTo(...) in the same class. ConvertTo(...) is a virtual function overwritten by the current application's document shell class; ScDocShell for Calc, SwDocShell for Writer, and ::sd::DrawDocShell for Draw/Impress. Whether the code path goes to ExportTo(...) or ConvertTo(...) is determined based on whether the filter has SFX_FILTER_STARONEFILTER flag turned on. This flag is on when the filter has the 3RDPARTYFILTER flag in its Flags property. Refer to the previous section for more details of filter configuration.

A filter that has 3RDPARTYFILTER flag on is expected to be a full-fledged UNO component filter, and method ExportTo(...) makes that assumption when it instantiates a filter class. If it's not a UNO component filter, then the file save/export operation will simply fail.

Zip-based package format

Overview

There is a UNO API for creating a zip-based package format - com.sun.star.packages.zip. There is also an internal UNO API called com.sun.star.packages.comp.ZipPackage, which is used when

  • saving to ODF, or
  • exporting XML filters as package (Tools > XML Filter Settings > Save as Package).

The code for ODF export is pretty complex, so a good code to look at to see how it works is the XML filter package export code. Have a look at filter/source/xsltdialog/xmlfilterjar.cxx and see how it creates a jar package and stuff folders and files therein.

The aforementioned com.sun.star.packages.comp.ZipPackage service is implemented in package/source/zippackage/*. The name of the implementation classes and their relationship suggest that this framework was modeled after Java's corresponding zip framework java.util.zip.

ZipPackage implementation class relationship.

OStorageHelper

UNO Component Filter

It's official! From this point on, all new file format filters must be implemented as UNO component filters. So, the traditional internal filters are officially deprecated, and destined to be gradually re-written into UNO filters.

Filter Configuration

Change directory into filter/source/config/fragments/. Add a new filter config file in ./filters/ directory, and a new type config file in ./types/ directory. Also add a new filter UI file in ./filters/ directory.

Now, add those new files to the appropriate makefile (fcfg_*.mk). Once done, re-build the filter module. It'll compile all the fragment filters and types files into complete configuration files. The configuration files have names like fcfg_*_(filters|types).xcu. The UI strings are packed into the fcfg_langpack_<locale>.zip.

To update the filter configuration files during hacking, you need to:

  • update the fcfg_*_(filters|types).xcu files in the installation directory with the ones you have just re-built,
  • unpack the Filters.xcu file from the fcfg_langpack_<locale>.zip, and place it in <install dir>/share/registry/res/<locale>/org/openoffice/TypeDetection/ as the replacement of the old one, and
  • rm -rf <config dir>/user/registry/cache - to remove old configuration cache.

General Export Flow

The general export flow is depicted in SfxObjecShell::ExportTo(...) located in sfx2/source/doc/objstor.cxx. It generally goes as follows:

  • Instantiate the filter factory com.sun.star.document.FilterFactory.
  • Get the properties of the right filter based on the filter name.
  • Query the FilterService property of the filter for the implementation name of the filter. That filter class is expected to implement com.sun.star.document.XFilter and com.sun.star.document.XExporter interfaces.
  • Instantiate that filter class (This will call method initialize(...) of com.sun.star.lang.XInitialization if that interface is implemented).
  • Set the source document to the filter instance via setSourceDocument(...). The source document here is the model of the document, and is passed as com.sun.star.lang.XComponent.
  • Retrieve a set of properties from SfxMedium and reformat it as MediaDescriptor. This will be passed to the filter instance later.
  • Create a new output stream and store it into the MediaDescriptor.
  • Finally, call the filter(...) method of the filter instance, and pass the MediaDescriptor to it.
  • At this point, the flow moves to the filter(...) method, and that method is expected to complete the content export process, and return true on success, or false on failure.
  • That's it!

Export Filter Code Organization (by module)

filter (UNO filter)

The filter module contains code for export filters such as PDF, SVG, and Flash, and the code that implements the export of XML filter settings as a jar package.

oox (UNO filter)

The oox module contains some initial code for Office Open XML export which is still under development. Class ::oox::core::XmlStorage has a hook for export operation.

sc (internal filter)

The sc (Calc) module contains code for export filters such as CSV, HTML, RTF, and DIF all in this one class ScImportExport (sc/source/ui/docshell/impex.cxx). The method for each export type is named Doc2Text, Doc2HTML and so on. Method ScDocShell::ConvertTo(...) creates an instance of ScImportExport and calls its method ExportStream(...), which detects the desired export format, and calls appropriate Doc2.... function.

sd (internal filter)

The definition of the sd::DrawDocShell::ConvertTo(...) function is found in sd/source/ui/docshell/docshel4.cxx. This function is fairly short compared to the ones for Writer and Calc.

Similar to the arrangement of the sw module, the sd module also uses separate classes for each individual filter that are all derived from class SdFilter. The following filter classes are found:

  • SdCGMFilter
  • SdGRFFilter
  • SdHTMLFilter
  • SdPPTFilter
  • SdXMLFilter

The ConvertTo() method instantiates the correct filter class based on the filter type, and does the export operation.

svtools (UNO filter?)

There are some filter codes in svtools/source/filter.vcl/filter/ that are (probably) used cross-application for graphic exports, such as BMP, JPEG, GIF, PNG....

sw (internal filter)

The sw (Writer) module implements export filters as individual classes, each one representing a single filter, that are sub-classes of class Writer. The following classes are found:

  • SwASCWriter - for ASCII text export
  • SwHTMLWriter - for HTML export
  • SwRTFWriter - for RTF export
  • SwW4WWriter - ?

All of Writer's export filters are found in sw/source/filter/. Now, when SwDocShell::ConvertTo(...) is called, this method instantiates the correct Sw...Writer class based on the user input, and executes the export operation.

Strategy for OOXML Export

Mikhail Viotenko's post on dev@framework.openoffice.org mailing list.

See also

Personal tools