Search code examples
delphicomopenoffice.orgoleopenoffice-writer

How to update the "table of contents" in an ODT document with Delphi and the com interface


at first to the background what I try to achieve. I am basically creating a report and depending on the user selecting export it to different formats (odt, doc & pdf).

So my approach is that I generate the whole document in the open document format odt (Which is very neat after you worked your way through the specification and XML), then I use the openoffice com interfaces to open the document programmatically and save it in word or in pdf.

This works perfect so far but I have the problem that the table of content doesn't get updated.

It doesn't matter so much in the DOC format, because the user can do it manually afterwards, but in PDF the user doesn't get this option.

I recorded the macro of the TOC update and tried to use it but somehow it doesn't work. I doesn't give me an error message but it just doesn't fire.. Below is the Makro:

sub Main

  dim document   as object
  dim dispatcher as object
  document   = ThisComponent.CurrentController.Frame
  dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
  dispatcher.executeDispatch(document, ".uno:UpdateCurIndex", "", 0, Array())

end sub

Basically I use this to create it:

oDispatcher := fOpenOffice.createInstance('com.sun.star.frame.DispatchHelper');

oDispatcher.executeDispatch(fDocument.CurrentController.Frame
                          , '.uno:UpdateCurIndex', '', 0
                          , VarArrayCreate([0, 0], varVariant));

with those variants:

fOpenOffice := CreateOleObject('com.sun.star.ServiceManager');
wProperties := VarArrayCreate([0, 0], varVariant);
wProperties[0] := MakePropertyValue('Hidden', True);
fDocument := fDesktop.loadComponentFromURL('file:///' + FileName
               , '_blank', 0, wProperties);`

Is there anything I forgot in the process? I haven't listed the whole source code which is pretty standard and works perfect. It is just those two lines with the "oDispatcher" which don't do the job.


Solution

  • Ok, now I found out about the problem and come up with an work around! 1. The update of the Table of Contents only works when the documnet is opened NOT hidden! So I had to change my code to:

    wProperties[0] := MakePropertyValue('Hidden', False);
    
    1. I used a very simple and efficient work around by adding a global Makro to OpenOffice which will automatically execute my Makro when a document is opened. All the Makro is doing is to look the text "Content", move one line down and update the selected Table of content. But this only works when openOffice ist started visible to he user. Otherwise it doesn't work. The script for updating it is below:

      sub UpdateTOC
      dim document   as object
      dim dispatcher as object
      document   = ThisComponent.CurrentController.Frame
      sub UpdateTOC
      dim document   as object
      dim dispatcher as object
      document   = ThisComponent.CurrentController.Frame
      dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
      dim args1(18) as new com.sun.star.beans.PropertyValue
      args1(0).Name = "SearchItem.StyleFamily"
      args1(0).Value = 2
      args1(1).Name = "SearchItem.CellType"
      args1(1).Value = 0
      args1(2).Name = "SearchItem.RowDirection"
      args1(2).Value = true
      args1(3).Name = "SearchItem.AllTables"
      args1(3).Value = false
      args1(4).Name = "SearchItem.Backward"
      args1(4).Value = false
      args1(5).Name = "SearchItem.Pattern"
      args1(5).Value = false
      args1(6).Name = "SearchItem.Content"
      args1(6).Value = false
      args1(7).Name = "SearchItem.AsianOptions"
      args1(7).Value = false
      args1(8).Name = "SearchItem.AlgorithmType"
      args1(8).Value = 0
      args1(9).Name = "SearchItem.SearchFlags"
      args1(9).Value = 65536
      args1(10).Name = "SearchItem.SearchString"
      args1(10).Value = "Contents"
      args1(11).Name = "SearchItem.ReplaceString"
      args1(11).Value = ""
      args1(12).Name = "SearchItem.Locale"
      args1(12).Value = 255
      args1(13).Name = "SearchItem.ChangedChars"
      args1(13).Value = 2
      args1(14).Name = "SearchItem.DeletedChars"
      args1(14).Value = 2
      args1(15).Name = "SearchItem.InsertedChars"
      args1(15).Value = 2
      args1(16).Name = "SearchItem.TransliterateFlags"
      args1(16).Value = 1024
      args1(17).Name = "SearchItem.Command"
      args1(17).Value = 0
      args1(18).Name = "Quiet"
      args1(18).Value = true
      dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())
      dim args2(1) as new com.sun.star.beans.PropertyValue
      args2(0).Name = "Count"
      args2(0).Value = 1
      args2(1).Name = "Select"
      args2(1).Value = false
      dispatcher.executeDispatch(document, ".uno:GoDown", "", 0, args2())
      dispatcher.executeDispatch(document, ".uno:UpdateCurIndex", "", 0, Array())
      end sub