Objects perform actions on behalf of the user. Sometimes it is desirable to inform the application user of progress, status or problems. In older applications, the action code often contained knowledge about the environment in which the object was embedded. This harms reusability and therefore XPCE provides a generic mechanism to deal with such messages.
Whenever an object needs to inform the user, the programmer can use 
the
`object->report' 
method. The definition of this method is below.
->format' 
for a description of the C printf-like formatting syntax of XPCE. type 
describes the nature of the message and is used by the reporting 
mechanism to decide on the presentation-style. See section 
10.7.2.1 for the available types and their meaning.
The object posting the report message will normally not be able to display the message. The main task of the implementations of this method in class object, visual, frame and dialog is to divert the report to an object that can present it. By default, this is either a label or the display object (@display).
The implementation of `object->report' 
will simply check whether there is a current event (see @event), 
which implicates the action was initiated by the user and then forward 
the ->report message to the
`event<-receiver', 
which is normally the controller activated by the user. If there is no 
current event, the action must be initiated by a user query to the 
host-language and therefore `object->report' 
will print its feedback to the host-language console using `@pce->format'.
The implementation of `visual->report' 
will simply forward the message to its containing visual object. If the 
message arrives at an instance of class frame, 
the implementation of `frame->report' 
will broadcast the message to each of its windows, but avoid sending it 
back to the window it came from. If this fails and the frame is a 
transient frame for another frame, the report is forward to the main 
frame. Class
dialog will look for an 
object named reporter. If it can find such an object (typically 
a label), the report is 
sent to this object.
If all fails, the report will arrive at the @display object, which takes care of default handling. See section 10.7.2.1 on how the different report types are handled.
The report type indicates the semantic category of the report and defines how it is handled. The following report types are defined:
->inform', 
presenting a messagebox.
->flush' 
to take immediate effect. A sequence of progress reports should 
be closed with a
done report.
->report: progress 
messages.
->alert' 
suffices. If there is an appropriate location for the message it will be 
formatted there.
->inform' 
is used to bring the message to the attention of the user.
There are two aspects in which the reporting mechanism can be 
redefined. The first concerns the location and the other the presentation 
of the report. The location is changed by defining the method <-report_to. 
All the generic implementations of this method will first invoke <-report_to 
on itself. If this method yields an answer, the report is forwarded to 
this answer. For example, class
text_buffer 
defines a <-report_to that forwards all reports 
to its associated editor object.
The presentation is changed by changing the implementation 
of
`label->report' 
or `display->report. 
As this determines the look and feel of an application, applications 
should be reluctant using this.
The typical way to exploit the report mechanism is by attaching a label named reporter to a dialog window of the applications frame. For example, an application consisting of a menu-bar, browser and a graphical window window could choose to make place for a small dialog for feedback at the bottom. The following fragment would build the window layout of such an application:
reportdemo :-
        new(Frame, frame('Reporter demo')),
        new(B, browser),
        send(new(picture), right, B),
        send(new(MD, dialog), above, B),
        send(new(RD, dialog), below, B),
        send(Frame, append, B),
        
        send(MD, append, new(MB, menu_bar)),
        send(MD, pen, 0),
        send(MD, gap, size(0,0)),
        send(MB, append, new(File, popup(file))),
        send_list(File, append,
                  [ menu_item(load,
                              message(@prolog, load, Frame),
                              end_group := @on),
                    menu_item(quit, message(Frame, destroy))
                  ]),
        send(RD, append, label(reporter)),
        send(RD, gap, size(5, 0)),
        send(Frame, open).
Now suppose the implementation of the `load' action takes considerable time. The implementation below reads a file assuming each line in the file contains a word.
:- pce_autoload(finder, library(find_file)).
:- pce_global(@finder, new(finder)).
load(Frame) :-
        get(@finder, file, exists := @on, FileName),
        send(Frame, report, progress,
             'Loading %s ...', FileName),
        get(Frame, member, browser, Browser),
        new(File, file(FileName)),
        send(File, open, read),
        (   repeat,
                (   get(File, read_line, Line)
                ->  send(Line, strip),
                    send(Browser, append, Line),
                    fail
                ;   !,
                    send(File, close)
                )
        ),
        send(Frame, report, done).
The result is shown in figure 18.
 
| Figure 18 : The `reporter' demo |