First, some background: O4W runs in what we call non-UI context ; that is, it runs on an OpenInsight OEngine that doesn t have access to OpenInsight s Windows desktop, so it can t do things that require the Windows GUI. One of the things that OpenInsight does that requires the Windows GUI is generate PDFs, so if we want O4W to generate a PDF we have to find some way to ask a regular OpenInsight to do this for us. For OpenInsight 9.x and above, we ve implemented the ability to run OpenInsight as a task manager . One OpenInsight (or OpenEngine) can request that another OpenInsight execute a specified task. If desired, a single OpenInsight instance can be designated as the task dispatcher, and it can create additional OpenInsights to actually execute the request; or OpenInsights can be created dynamically to handle the requests as they come up. [Note that the task management system must be properly configured, via the CFG_AUTOEXEC record in SYSENV]
Inside the routine that wishes to submit the task, the steps to follow are:
- Submit the task with RTI_TASK_SUBMIT, returning a task ID ;
- Periodically check the task status with RTI_TASK_STATUS until the task is complete
In the O4W_RUN_REPORT, when the Generate PDF button is clicked, we gather what information we need, and call the task submit:
Case CtlEntId _eqc "BTNPDF" Or CtlEntID _eqc "BTNPDF_DETAIL"
* Return all or selected results as PDF
O4WResponse()
taskCounter = 0
* Must copy our list item into SYSLISTS for PDF retrieval
whichID = ListID
If ctlEntId _eqc "BTNPDF_DETAIL" Then whichID = UniqueID:"*BRK*IDS"
Read idList From O4WTempFile%, whichID Then
Write idList On List.fl, whichID
taskID = RTI_Task_Submit("","O4WI_CSVTOPDF", ReportDef, whichID)
* Display the 'please wait' dialog
Gosub PleaseWait
End Else
O4WError("Unable to generate PDF - cannot access ID list")
End
In the call to RTI_TASK_SUBMIT, the first parameter is the request type (we leave this null for the default, Execute Immediately ). The second parameter is the name of the routine that we want the new OpenInsight to execute; in this case, we wrote a procedure O4WI_CSVTOPDF which is responsible for actually generating a PDF when given the name of the O4W report and a list of IDs to operate on. We pass in 2 parameters to that routine (in this case, the report name, and the ID of the record in the temp file that contains the list of records to operate on); you can pass in up to 10 parameters.
The call to RTI_TASK_SUBMIT returns a task ID (if the request is successful). We then go to the PleaseWait routine, which generates a dialog (NOT a popup), storing away some required information, and setting a timer so that we can check if the request is done:
PleaseWait: * Generate 'please wait' dialog
O4WSectionStart("pleaseWait", O4WResponseOptions():O4WMarkedOptions(1))
O4WText(O4WI_FORMATMSG(O4W_MESSAGE_PLEASE_WAIT$):O4WI_FORMATMSG(O4W_MESSAGE_GENERATING$, "PDF"):str(".", taskCounter))
O4WBreak()
O4WBreak()
O4WSectionStart("showImage", "DESELECTED":@SVM:"STDALIGN")
O4WImage("please wait", "../images/pleasewait2.gif",,
,,
,O4WSizeStyle(,'100%'))
O4WSectionEnd("showImage")
O4WBreak()
O4WButton("Cancel", "BTN_QUIT")
O4WQualifyEvent("BTN_QUIT", "CLICK")
O4WStore("", "CANCELLED")
O4WTimer(1, "", "TASKID=":taskid:"&COUNTER=":taskCounter)
O4WSectionEnd("pleaseWait")
* display this as a dialog
O4WDialog("pleaseWait", O4WI_FORMATMSG(O4W_MESSAGE_GENERATING$,"PDF"):str(".",taskCounter))
Return
A lot of this is related to showing the image and the dots as the PDF is being generated; the crucial bit is the O4WTimer call. It tells the browser to call us each second, and passes in 2 name/value pairs: COUNTER (which is again related to those dots in the display) and TASKID (which is our task ID).
After we generate the dialog, our O4W routine is finished (for now). But in 1 second, it gets called with the timer event:
Case event _eqc "TIMER"
* Hide our dialog
O4WResponse();
O4WDialog("pleaseWait")
taskID = O4WGetValue("TASKID")<1,1>
taskCounter = O4WGetValue("COUNTER")<1,1>
bIsCancelled = O4WGetValue("CANCELLED")
If bIsCancelled = "" then
If taskID <> "" then
myStatus = RTI_Task_Status(taskID, results)
If myStatus _eqc "COMPLETED" Or myStatus _eqc "ERROR" then
O4WDownload(results,
,'','O4WREPORT.PDF')
End Else
* redisplay dialog
taskCounter += 1
If taskCounter > 5 Then taskCounter = 0
Gosub PleaseWait
End
End Else If taskCounter <> "-1" Then
* taskCounter = -1 ⇒ user requested cancel
O4WError(O4WI_FORMATMSG(O4W_MESSAGE_GENERATE_ERROR$, "PDF"))
End
End
First, we dismiss the dialog. Then we check for our passed-in values. If the cancelled button wasn t clicked by someone (handled in a separate click event for the cancel button), we get our task id, and call RTI_TASK_STATUS. This will return a status value, and (when completed) some results. If the status is completed (or we got an error), we re done; call the O4WDownload routine with those results to allow the user to download to their PC. If we re _not_ done, we redisplay the dialog, after updating our counter (so more or fewer dots will appear); remember, in the dialog, we set up a timer, so that in another second this same routine will get called again. This loop (timer event ⇒ generate dialog ⇒ start timer) is how we keep checking the status.