xTuple.com xTupleU Blog & News Customer Support

Rptrender run-time switch to print without prompting any window

My intention is to add to rptrender a new run-time switch in order to print a report automatically without prompting any window, so the user doesn’t needs to specify a printer.

This could be useful for applications using openRPT as a printing solution, in which the user might want to print several files at once, instead of prompting X windows asking X times the printer in which the user wants to print, for the X reports that must be printed, the application asks for the printer itself, and after that, runs the rptrender command with the -printerName parameter set and the new run-time switch, so it prints automatically without asking again the printer the user wants to print to.

I’m going to code this feature myself, and post the code when I’m done.

Right now, the name of the run-time switch might be “-autoPrint”, but it could be changed to be named the way xTuple wants.

Greetings.

Josep Rodríguez López

Sorry, I’ve been busy this days and I haven’t been able to send the patch, as cryan says that it has already reviewed and included in the repository, I guess I don’t need to do it again, if so, just say it.

Best regards

Josep

We have reviewed the patch submission and included it in the SVN repository. It will be part of the next release which will likely be 3.2.2.

The code i modified was located at openRPT/renderapp folder in your source code posted in sourceforge (i used the version 3.2.0, because the 3.2.1 code wasn’t uploaded to your sourceforge project).

I just had to modify the main.cpp file, adding the run-time switch to the ones you had already defined, using a boolean called autoPrint to add the feature I needed.

After reading the command line parameters, i added the autoPrint boolean to the renderWindow class, so it could be aware when the users want to print without prompting the QPrintDialog or not, and set it with the value false if -autoPrint wasn’t in the arguments received or true if it was.

The changes I made to the code who is responsible to show the window and make it print or not are in the next lines:

If autoPrint is true, we don’t need to show the renderWindow.

  if (!pdfOutput and !autoPrint)
    mainwin.show();

If autoprint or print is true, we have to print numCopies of the report

  if(print or autoPrint)                        //AUTOPRINT
    mainwin.filePrint( numCopies );

The rest of the modifications are located in the renderWindow class. (renderwindow.h and renderwindow.cpp).

In the renderwindow.h i added a boolean parameter so the window is aware of the election of the user (autoprint or not). I declared this parameter in the public section:

public:
    RenderWindow(QWidget* parent = 0, Qt::WindowFlags fl = 0);
    ~RenderWindow();

    QString _printerName;
    bool _autoPrint;                //AUTOPRINT

In the renderwindow.cpp the modifications are located just in the print function:

void RenderWindow::print(bool showPreview, int numCopies )      //AUTOPRINT
{
  ORPreRender pre;
  pre.setDom(_doc);
  pre.setParamList(getParameterList());
  ORODocument * doc = pre.generate();

  if(doc)
  {
    QPrinter printer(QPrinter::HighResolution);
    printer.setNumCopies( numCopies );
    if(!_printerName.isEmpty())
    {
      printer.setPrinterName(_printerName);
      _printerName = QString::null;
    }

    if(showPreview) 
    {
      PreviewDialog preview (doc, &printer, this);
      if (preview.exec() == QDialog::Rejected) 
        return;
    }

    ORPrintRender render;
    render.setupPrinter(doc, &printer);

    if(_autoPrint){                             //AUTOPRINT
        render.setPrinter(&printer);
        render.render(doc);
    }
    else{
        QPrintDialog pd(&printer);
        pd.setMinMax(1, doc->pages());
        if(pd.exec() == QDialog::Accepted)
        {
          render.setPrinter(&printer);
          render.render(doc);
        }
    }
    delete doc;
  }
}

as marked by the //AUTOPRINT comment, I added an if statement in which, if autoPrint is set, the report is directly printed without prompting the QPrintDialog. If autoPrint is not set, it just does the regular functionality

I attach a .zip with the three files i had to modify in your code.

Best regards.

Josep

Hey Josep, that sounds fantastic! Can you post an issue in our Feature Requests system (http://www.xtuple.org/features) with that .zip file? That is our internal queue system for getting features developed. Make sure you set the severity to “patch” which tells us you’ve already done the work and submitted it. That will automatically give it a higher priority and therefore a higher chance of getting into the next release.

Regards,

John

You are good to go. Nothing else needs to be done for this issue.

How do I set autoprint?

This is not a checkbox within the GUI client, it is a command line parameter to the rptrender binary for use from a shell script or a custom command in the GUI client. So a sample shell/terminal command, including -autoPrint from this patch:

rptrender -databaseURL=psql://SERVER/demo384:5432 -username=admin -passwd=PASSWORD -loadfromdb=WOSchedule -autoPrint

Would print the work order schedule to the default printer without prompting. If you wanted to be able to pass in parameters to the report, add -param=PARAMETER=VALUE The lack of spaces is intentional.

Expanded Example:

rptrender -databaseURL=psql://SERVER/demo384:5432 -username=admin -passwd=PASSWORD -loadfromdb=WOSchedule -autoPrint -param=search_pattern=ytruck

Would print a work order schedule for only the yellow trucks from the demo database.

David

is there any functionality to do the same thing in the JS environment?

Something like:

  var printer = new QPrinter();
  // will go to default printer otherwise
  printer.setPrinterName("DYMO LabelWriter 450 Turbo");
  var printparams = {};
  printparams.item_id = 1234;

  var report = new orReport("ReportNameHere", printparams);

  if (report.isValid()) {
    report.print(printer, false);
  }
2 Likes

I cant tell you how helpful this bit of script will be.

Being able to define printers in the script has saved me a ton of time. But now I am at the point that employees are waiting on the printer. The problem is that I am sending all my reports as individual print jobs. Is there any way to add all the reports to a single print job? I see orReport.beginMultiPrint() I don’t know where to find docs for this but think it may be part of my answer. Another solution would be something like Green Cloud printer by obvious idea. The problem with that solution is that it leaves out pages randomly. Does anyone know of a more reliable way to combine print jobs or how to do this in js

Caleb,

We don’t have documentation for orReport.beginMultiPrint() but look at printWoTraveler. This is a C++ example but it should be easy to translate into JavaScript.

Gil

1 Like

At its simplest you wrap the following around your normal print script. This initialises the multiPrint job and the final command sends all the prints to the printer in one job

orReport.beginMultiPrint(printer, userCanceled)
...
            var report = new orReport("reportname", p);
            if (! report.isValid() || ! report.print(printer, (i == 0)))
            {
              report.reportError(mywindow);
              return false;
            }
...
 orReport.endMultiPrint(printer);