Search code examples
cocoaprintingnsprintoperation

Setting printer-specific options on an NSPrintOperation without a panel


this question has bothered me on and off for about a year, and I thought perhaps someone else would have experience with a similar situation.

Goal: on Mac OS X 10.6-7, to print multiple NSViews to EPSON Stylus Pro 4880 printers using a defined resolution and 'high speed' setting, without showing a print panel.

Current situation: I can create successful NSPrintOperations for each NSView, but if I do not show a print panel, it appears the printer's default resolution is used, which is far too high, and slow, for my needs.

Best solution I have so far: I have tried showing the print panel and defining a Mac OS 'preset' which has the correct print resolution and high speed settings already enabled. The downside here is that the Mac preset overrides the number of copies I have set via NSCopies, which is a problem. The other difficulty of course is having someone always around to press the 'OK' button a few thousand times a day.

Where I'm up to

  • When the NSPrintOperation runs its panel, it has to set the EPSON-specific printer settings somewhere, but I cannot find where it is saved. They don't appear to be set in [NSPrintInfo printSettings].

  • I have looked at the PPD for the printer, but I can't find the high speed setting anywhere, and the default resolution defined in the PPD is not actually used as the default when printing. It appears EPSON has their own driver settings which are not taken from the PPD I have, and I am not sure how to set them manually.

  • Basically, running the NSPrintOperation with a print panel and preset overrides all the settings, including the ones I don't want to override. Running it without the print panel leaves all the settings as default, which is not what I want. Can anyone point me in the right direction to find a solution in between those two?


Solution

  • This is unfortunately the best solution I have found so far though I hate to call it 'best', or even a 'solution'. It comes back to this: run an operation with a panel, and then programmatically 'click' the Print button.

    [op runOperationModalForWindow: self.window delegate: self didRunSelector: nil contextInfo: nil];
    NSPanel *panel = (NSPanel*)self.window.attachedSheet;
    for (NSView *view in ((NSView*)panel.contentView).subviews)
    {
        if (view.class == [NSButton class])
        {
            NSButton *button = (NSButton*)view;
            if ([button.title isEqualToString: @"Print"])
                [button performClick: self];
        }
    }
    

    or

    op.runOperationModalForWindow(window, delegate: nil, didRunSelector: nil, contextInfo: nil)
    (window.attachedSheet?.contentView.subviews.filter({ $0 is NSButton }) as [NSButton]).filter({ $0.title == "Print" }).first?.performClick(self)
    

    The downside obviously is a window is needed, while I was hoping to run this as a headless server application. I have tried working with Core Printing and PMPrinter/PMPrintSettings and so forth to no avail. The only thing I have not yet tried is talking to CUPS directly. Maybe I'll save that for a rainy day!