2

I am using OpenOffice Writer, and I wish to Print under Program control. However, I do not wish to print to the default printer, but rather direct certain documents to certain printers, according to the type of document I generate.

Using Bernard Marcelly's OOoTools library, for Delphi, to do OLE Automation, talking to OpenOffice, 4.0, the following code works to Print to the current printer,

procedure TMyOODocClass.Print;
var
   docObj : variant; // Current OOo Document, implements IXPrintable
   printProps : variant;
begin
  docObj := GetMyActiveDocument; // method not shown, pretty standard stuff.
  try
     // empty array, I think this is where I would fill in PrinterName?
     printProps := VarArrayCreate([0, -1], varVariant); 
     docObj.print(printProps);
  except
     on E:EOleException do
     begin
      raise Exception.Create('OpenOffice Document Print failed. '+E.Message);
     end;
  end;
end;

I am not able to locate the documentation for OpenOffice Writer Document Print method or the properties it supports, I think I am supposed to define some properties, something like this:

printProps := VarArrayCreate([0, 1], varVariant);
printProps[0] := MakePropertyValue('PrinterName', 'PrinterNameHere') ;

Question Part A, is there a thorough HTML online reference for all the properties that Print, and all other similar Document methods accept? And Part B, is what is the property or technique to set the above. I do believe that the Document objects in OO implement an interface called IXPrintable, and so what I am wondering how to find is all the methods of IXPrintable, and what parameters or properties the Print method within that method, accepts.

Update Following the comment suggestion, I tried using a property named 'Name', like this:

procedure TMyOODocClass.PrintTo(PrinterName:String);
var
   docObj : variant; // Current OOo Document, implements IXPrintable
   printProps : variant;
begin
  docObj := GetMyActiveDocument; // method not shown, pretty standard stuff.
  try
     if PrinterName='' then
       printProps := dummyArray
     else
     begin
       printProps := VarArrayCreate([0, 1], varVariant);
       printProps[0] := MakePropertyValue('Name',PrinterName);
     end;
     docObj.print(printProps);
  except
     on E:EOleException do
     begin
      raise EOOoError.Create('OpenOffice Document Print failed. '+E.Message);
     end;
  end;
end;

The above does not work, so there must be something missing or wrong. I tried calling docObj.SetPrinter as well, but I get a parameter type mismatch error.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • 1
    Maybe [`this example`](http://wiki.openoffice.org/wiki/API/Samples/Java/Office/DocumentHandling#DocumentPrinter) might help. – TLama Sep 25 '13 at 18:55
  • Thanks, that example worked, but I had a hard time translating it into Delphi-sprache. :-) – Warren P Sep 25 '13 at 19:24

1 Answers1

3

Okay I got it to work, the problem was I wasn't creating the Property values properly. Also I stupidly assumed that you pass the parameters to Print when what you do is call SetPrinter, with property Name set to printer name, then call Print, still with no parameters. The url linked by TLama clearly stated this, but I missed it initially, I think I need more coffee.

Also it seems that the Unicode VarType 258 (varUString) values are not particularly OLE Automation friendly, so I am explicitly using AnsiString in the code below.

uses
      ComObj,
      Classes,
      SysUtils,
      Dialogs,
      Controls,
      Windows,
      oOoConstants,
      OOoTools,
      DB,
      Variants,
      StdCtrls,
      Forms;

procedure TMyOODocClass.PrintTo(PrinterName:AnsiString);
var
   docObj : variant; // Current OOo Document, implements IXPrintable
   emptyProps, printProps: variant;
   propName:AnsiString;
begin
  docObj := GetMyActiveDocument; // method not shown, pretty standard stuff.
  try
    emptyProps := dummyArray;
     if PrinterName <> '' then
     begin
       propName := 'Name';
       printProps := createProperties( [propName,PrinterName]  ); // OOTools helper
       docObj.SetPrinter( printProps ); 
     end;
     docObj.print(emptyProps);
  except
     on E:EOleException do
     begin
      raise EOOoError.Create('OpenOffice Document Print failed. '+E.Message);
     end;
  end;
end;

A complete demo that compiles and runs is on bitbucket here as delphi_openoffice_demo01

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • Yes, the use of ANSI strings for property names is correct. Anyway, you might use `MakePropertyValue` function from that helper to create a single property (that wrapper seems to be for ANSI versions of Delphi, however explicit use of `AnsiString` might have been there for certain function parameters). – TLama Sep 25 '13 at 19:35
  • That `createProperties` call seems to work fine, and has some safety-checking stuff in it. – Warren P Sep 25 '13 at 19:40
  • That `createProperties` does safe checks just because it takes `array of Variant` as an input, which must be pair of `[AnsiString, Variant]` types. For this case it creates unnecessary variant array, because for your [`setPrinter`](http://www.openoffice.org/api/docs/common/ref/com/sun/star/view/XPrintable.html#setPrinter) method call you use just one parameter. And for making one parameter is the `MakePropertyValue` function from that wrapper, or e.g. my [`CreateProperty`](http://stackoverflow.com/a/7819626/960757) nested function. They're the same (assuming that wrapper is for ANSI Delphi). – TLama Sep 25 '13 at 19:57
  • Oh I see. Yes, that would be simplest. – Warren P Sep 25 '13 at 20:27