Commit 211df6b6 authored by Clinton Stimpson's avatar Clinton Stimpson

ENH:  Integrate Python testing framework with ParaView.  If testing with python
      is enabled, the play/record menus/dialogs give python as an option.

      It currently can query any QObject property and in python you can compare
      it to a known value.  Just throw an exception if the test fails.
      It can also take snapshots of arbitrary widgets and compare them to
      baselines.

      Also added a test that loads a histogram and takes a snapshot of the
      histogram widget and compares it to a baseline.
parent fe6b1ede
PROJECT(QtTesting)
#OPTION(QT_TESTING_WITH_PYTHON "Build Testing with Python" ON)
SET(QT_TESTING_WITH_PYTHON OFF)
OPTION(QT_TESTING_WITH_PYTHON "Build Testing with Python" ON)
SET(QT_TESTING_WITH_XML ON)
IF(QT_TESTING_WITH_PYTHON)
INCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake)
INCLUDE_DIRECTORIES(
${PYTHON_INCLUDE_PATH}
)
......@@ -40,6 +42,7 @@ QT4_WRAP_CPP(MOC_BUILT_SOURCES
pqComboBoxEventTranslator.h
pqDoubleSpinBoxEventTranslator.h
pqEventDispatcher.h
pqEventObserver.h
pqEventPlayer.h
pqEventSource.h
pqEventTranslator.h
......@@ -48,6 +51,7 @@ QT4_WRAP_CPP(MOC_BUILT_SOURCES
pqRecordEventsDialog.h
pqSpinBoxEventTranslator.h
pqStdoutEventObserver.h
pqTestUtility.h
pqThreadedEventSource.h
pqTabBarEventTranslator.h
pqWidgetEventTranslator.h
......@@ -91,6 +95,8 @@ ADD_LIBRARY(QtTesting
pqDoubleSpinBoxEventTranslator.h
pqEventDispatcher.cxx
pqEventDispatcher.h
pqEventObserver.cxx
pqEventObserver.h
pqEventPlayer.cxx
pqEventPlayer.h
pqEventTranslator.cxx
......@@ -112,6 +118,8 @@ ADD_LIBRARY(QtTesting
pqTabBarEventPlayer.h
pqTabBarEventTranslator.cxx
pqTabBarEventTranslator.h
pqTestUtility.cxx
pqTestUtility.h
pqThreadedEventSource.cxx
pqThreadedEventSource.h
pqWidgetEventPlayer.h
......
......@@ -41,7 +41,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtTest>
#include <QtDebug>
pqAbstractActivateEventPlayer::pqAbstractActivateEventPlayer()
pqAbstractActivateEventPlayer::pqAbstractActivateEventPlayer(QObject * p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -44,7 +44,7 @@ class pqAbstractActivateEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractActivateEventPlayer();
pqAbstractActivateEventPlayer(QObject* p = 0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QAbstractButton>
#include <QtDebug>
pqAbstractBooleanEventPlayer::pqAbstractBooleanEventPlayer()
pqAbstractBooleanEventPlayer::pqAbstractBooleanEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -44,7 +44,7 @@ class pqAbstractBooleanEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractBooleanEventPlayer();
pqAbstractBooleanEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -40,7 +40,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
pqAbstractButtonEventTranslator::pqAbstractButtonEventTranslator()
pqAbstractButtonEventTranslator::pqAbstractButtonEventTranslator(QObject* p)
: pqWidgetEventTranslator(p)
{
}
......
......@@ -49,7 +49,7 @@ class pqAbstractButtonEventTranslator :
Q_OBJECT
public:
pqAbstractButtonEventTranslator();
pqAbstractButtonEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QDoubleSpinBox>
#include <QtDebug>
pqAbstractDoubleEventPlayer::pqAbstractDoubleEventPlayer()
pqAbstractDoubleEventPlayer::pqAbstractDoubleEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -45,7 +45,7 @@ class pqAbstractDoubleEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractDoubleEventPlayer();
pqAbstractDoubleEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -36,7 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QSpinBox>
#include <QtDebug>
pqAbstractIntEventPlayer::pqAbstractIntEventPlayer()
pqAbstractIntEventPlayer::pqAbstractIntEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -45,7 +45,7 @@ class pqAbstractIntEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractIntEventPlayer();
pqAbstractIntEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -62,7 +62,8 @@ static QModelIndex GetIndex(QAbstractItemView& View, const QString& Name)
///////////////////////////////////////////////////////////////////////////////
// pqAbstractItemViewEventPlayer
pqAbstractItemViewEventPlayer::pqAbstractItemViewEventPlayer()
pqAbstractItemViewEventPlayer::pqAbstractItemViewEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -45,7 +45,7 @@ class pqAbstractItemViewEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractItemViewEventPlayer();
pqAbstractItemViewEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -51,7 +51,8 @@ static const QString str(const QModelIndex& index)
return result;
}
pqAbstractItemViewEventTranslator::pqAbstractItemViewEventTranslator() :
pqAbstractItemViewEventTranslator::pqAbstractItemViewEventTranslator(QObject* p)
: pqWidgetEventTranslator(p),
CurrentObject(0)
{
}
......
......@@ -51,7 +51,7 @@ class pqAbstractItemViewEventTranslator :
Q_OBJECT
public:
pqAbstractItemViewEventTranslator();
pqAbstractItemViewEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QAbstractSlider>
#include <QEvent>
pqAbstractSliderEventTranslator::pqAbstractSliderEventTranslator() :
pqAbstractSliderEventTranslator::pqAbstractSliderEventTranslator(QObject* p)
: pqWidgetEventTranslator(p),
CurrentObject(0)
{
}
......
......@@ -47,7 +47,7 @@ class pqAbstractSliderEventTranslator :
Q_OBJECT
public:
pqAbstractSliderEventTranslator();
pqAbstractSliderEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -36,7 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QLineEdit>
#include <QtDebug>
pqAbstractStringEventPlayer::pqAbstractStringEventPlayer()
pqAbstractStringEventPlayer::pqAbstractStringEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -45,7 +45,7 @@ class pqAbstractStringEventPlayer :
public pqWidgetEventPlayer
{
public:
pqAbstractStringEventPlayer();
pqAbstractStringEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -37,7 +37,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QWidget>
#include <QtDebug>
pqBasicWidgetEventPlayer::pqBasicWidgetEventPlayer()
pqBasicWidgetEventPlayer::pqBasicWidgetEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
{
}
......
......@@ -44,7 +44,7 @@ class pqBasicWidgetEventPlayer :
public pqWidgetEventPlayer
{
public:
pqBasicWidgetEventPlayer();
pqBasicWidgetEventPlayer(QObject* p=0);
bool playEvent(QObject* Object, const QString& Command, const QString& Arguments, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QEvent>
#include <QWidget>
pqBasicWidgetEventTranslator::pqBasicWidgetEventTranslator()
pqBasicWidgetEventTranslator::pqBasicWidgetEventTranslator(QObject* p)
: pqWidgetEventTranslator(p)
{
}
......
......@@ -47,7 +47,7 @@ class pqBasicWidgetEventTranslator :
Q_OBJECT
public:
pqBasicWidgetEventTranslator();
pqBasicWidgetEventTranslator(QObject* p=0);
~pqBasicWidgetEventTranslator();
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QComboBox>
#include <QEvent>
pqComboBoxEventTranslator::pqComboBoxEventTranslator() :
pqComboBoxEventTranslator::pqComboBoxEventTranslator(QObject* p)
: pqWidgetEventTranslator(p),
CurrentObject(0)
{
}
......
......@@ -47,7 +47,7 @@ class pqComboBoxEventTranslator :
Q_OBJECT
public:
pqComboBoxEventTranslator();
pqComboBoxEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -35,7 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QDoubleSpinBox>
#include <QEvent>
pqDoubleSpinBoxEventTranslator::pqDoubleSpinBoxEventTranslator() :
pqDoubleSpinBoxEventTranslator::pqDoubleSpinBoxEventTranslator(QObject* p)
: pqWidgetEventTranslator(p),
CurrentObject(0)
{
}
......
......@@ -47,7 +47,7 @@ class pqDoubleSpinBoxEventTranslator :
Q_OBJECT
public:
pqDoubleSpinBoxEventTranslator();
pqDoubleSpinBoxEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -127,19 +127,29 @@ void pqEventDispatcher::playNextEvent()
// block signals as some event sources may interact with the event loop
this->blockSignals(true);
bool result = this->Implementation->Source->getNextEvent(
int result = this->Implementation->Source->getNextEvent(
object, command, arguments);
this->blockSignals(false);
if(!result)
if(result == pqEventSource::DONE)
{
this->stopPlayback();
emit this->succeeded();
return;
}
else if(result == pqEventSource::FAILURE)
{
this->stopPlayback();
emit this->failed();
return;
}
bool error = false;
// block signals as some event sources may interact with the event loop, as
// well as some players interact with the event loop
this->blockSignals(true);
this->Implementation->Player->playEvent(object, command, arguments, error);
this->blockSignals(false);
if(error)
{
this->stopPlayback();
......
......@@ -45,7 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QApplication>
#include <QWidget>
#include <QtDebug>
#include <QAbstractEventDispatcher>
pqEventPlayer::pqEventPlayer()
{
......@@ -53,12 +52,11 @@ pqEventPlayer::pqEventPlayer()
pqEventPlayer::~pqEventPlayer()
{
for(int i = 0; i != this->Players.size(); ++i)
delete this->Players[i];
}
void pqEventPlayer::addDefaultWidgetEventPlayers()
{
addWidgetEventPlayer(new pqBasicWidgetEventPlayer());
addWidgetEventPlayer(new pqAbstractActivateEventPlayer());
addWidgetEventPlayer(new pqAbstractBooleanEventPlayer());
addWidgetEventPlayer(new pqAbstractDoubleEventPlayer());
......@@ -66,14 +64,14 @@ void pqEventPlayer::addDefaultWidgetEventPlayers()
addWidgetEventPlayer(new pqAbstractItemViewEventPlayer());
addWidgetEventPlayer(new pqAbstractStringEventPlayer());
addWidgetEventPlayer(new pqTabBarEventPlayer());
addWidgetEventPlayer(new pqBasicWidgetEventPlayer());
}
void pqEventPlayer::addWidgetEventPlayer(pqWidgetEventPlayer* Player)
{
if(Player)
{
this->Players.push_back(Player);
this->Players.push_front(Player);
Player->setParent(this);
}
}
......@@ -123,3 +121,4 @@ void pqEventPlayer::playEvent(
// The event was handled successfully ...
Error = false;
}
......@@ -42,15 +42,25 @@ class QTTESTING_EXPORT pqEventSource : public QObject
{
Q_OBJECT
public:
pqEventSource(QObject* p) : QObject(p) {}
virtual ~pqEventSource() {}
/** Retrieves the next available event. Returns true if an event was
returned, false if there are no more events. */
virtual bool getNextEvent(
enum { SUCCESS, FAILURE, DONE };
/** Retrieves the next available event.
Returns SUCCESS if an event was returned and can be processed,
FAILURE if there was a problem,
DONE, if there are no more events. */
virtual int getNextEvent(
QString& object,
QString& command,
QString& arguments) = 0;
/** Set the filename for contents.
Returns true for valid file, false for invalid file */
virtual void setContent(const QString& filename) = 0;
};
#endif // !_pqEventSource_h
......@@ -55,8 +55,6 @@ struct pqEventTranslator::pqImplementation
{
~pqImplementation()
{
for(int i = 0; i != this->Translators.size(); ++i)
delete this->Translators[i];
}
/// Stores the working set of widget translators
......@@ -68,21 +66,31 @@ struct pqEventTranslator::pqImplementation
////////////////////////////////////////////////////////////////////////////////
// pqEventTranslator
pqEventTranslator::pqEventTranslator() :
pqEventTranslator::pqEventTranslator(QObject* p)
: QObject(p),
Implementation(new pqImplementation())
{
QCoreApplication::instance()->installEventFilter(this);
}
pqEventTranslator::~pqEventTranslator()
{
QCoreApplication::instance()->removeEventFilter(this);
this->stop();
delete Implementation;
}
void pqEventTranslator::start()
{
QCoreApplication::instance()->installEventFilter(this);
}
void pqEventTranslator::stop()
{
QCoreApplication::instance()->removeEventFilter(this);
}
void pqEventTranslator::addDefaultWidgetEventTranslators()
{
addWidgetEventTranslator(new pqBasicWidgetEventTranslator());
addWidgetEventTranslator(new pqAbstractButtonEventTranslator());
addWidgetEventTranslator(new pqAbstractItemViewEventTranslator());
addWidgetEventTranslator(new pqAbstractSliderEventTranslator());
......@@ -92,14 +100,14 @@ void pqEventTranslator::addDefaultWidgetEventTranslators()
addWidgetEventTranslator(new pqMenuEventTranslator());
addWidgetEventTranslator(new pqSpinBoxEventTranslator());
addWidgetEventTranslator(new pqTabBarEventTranslator());
addWidgetEventTranslator(new pqBasicWidgetEventTranslator());
}
void pqEventTranslator::addWidgetEventTranslator(pqWidgetEventTranslator* Translator)
{
if(Translator)
{
this->Implementation->Translators.push_back(Translator);
this->Implementation->Translators.push_front(Translator);
Translator->setParent(this);
QObject::connect(
Translator,
......
......@@ -55,7 +55,7 @@ class QTTESTING_EXPORT pqEventTranslator :
Q_OBJECT
public:
pqEventTranslator();
pqEventTranslator(QObject* p=0);
~pqEventTranslator();
/**
......@@ -69,6 +69,12 @@ public:
/// Adds a Qt object to a list of objects that should be ignored when translating events (useful to prevent recording UI events from being captured as part of the recording)
void ignoreObject(QObject* Object);
/// start listening to the GUI and translating events
void start();
/// stop listening to the GUI and translating events
void stop();
signals:
/// This signal will be emitted every time a translator generates a high-level ParaView event. Observers should connect to this signal to serialize high-level events.
void recordEvent(const QString& Object, const QString& Command, const QString& Arguments);
......
......@@ -36,7 +36,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QLineEdit>
#include <QSpinBox>
pqLineEditEventTranslator::pqLineEditEventTranslator()
pqLineEditEventTranslator::pqLineEditEventTranslator(QObject* p)
: pqWidgetEventTranslator(p)
{
}
......
......@@ -47,7 +47,7 @@ class pqLineEditEventTranslator :
Q_OBJECT
public:
pqLineEditEventTranslator();
pqLineEditEventTranslator(QObject* p=0);
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -37,7 +37,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QKeyEvent>
#include <QMenu>
pqMenuEventTranslator::pqMenuEventTranslator()
pqMenuEventTranslator::pqMenuEventTranslator(QObject* p)
: pqWidgetEventTranslator(p)
{
}
......
......@@ -49,7 +49,7 @@ class pqMenuEventTranslator :
Q_OBJECT
public:
pqMenuEventTranslator();
pqMenuEventTranslator(QObject* p=0);
~pqMenuEventTranslator();
virtual bool translateEvent(QObject* Object, QEvent* Event, bool& Error);
......
......@@ -37,16 +37,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////////
// pqPythonEventObserver
pqPythonEventObserver::pqPythonEventObserver(QTextStream& stream) :
Stream(stream)
pqPythonEventObserver::pqPythonEventObserver(QObject* p)
: pqEventObserver(p)
{
this->Stream << "#/usr/bin/env python\n\n";
this->Stream << "import QtTesting\n\n";
}
pqPythonEventObserver::~pqPythonEventObserver()
{
this->Stream.flush();
}
void pqPythonEventObserver::setStream(QTextStream* stream)
{
pqEventObserver::setStream(stream);
if(this->Stream)
{
*this->Stream << "#/usr/bin/env python\n\n";
*this->Stream << "import QtTesting\n\n";
}
}
void pqPythonEventObserver::onRecordEvent(
......@@ -54,23 +61,25 @@ void pqPythonEventObserver::onRecordEvent(
const QString& Command,
const QString& Arguments)
{
QString varname = this->Names[Widget];
if(varname == QString::null)
if(this->Stream)
{
varname = QString("object%1").arg(this->Names.count());
this->Names.insert(Widget, varname);
QString objname("%1 = '%2'");
objname = objname.arg(varname);
objname = objname.arg(Widget);
this->Stream << objname << "\n";
QString varname = this->Names[Widget];
if(varname == QString::null)
{
varname = QString("object%1").arg(this->Names.count());
this->Names.insert(Widget, varname);
QString objname("%1 = '%2'");
objname = objname.arg(varname);
objname = objname.arg(Widget);
*this->Stream << objname << "\n";
}
QString pycommand("QtTesting.playCommand(%1, '%2', '%3')");
pycommand = pycommand.arg(varname);
pycommand = pycommand.arg(Command);
pycommand = pycommand.arg(Arguments);
*this->Stream << pycommand << "\n";
}
QString pycommand("QtTesting.playCommand(%1, '%2', '%3')");
pycommand = pycommand.arg(varname);
pycommand = pycommand.arg(Command);
pycommand = pycommand.arg(Arguments);
this->Stream << pycommand << "\n";
}
......@@ -33,10 +33,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef _pqPythonEventObserver_h
#define _pqPythonEventObserver_h
#include <QObject>
#include "pqEventObserver.h"
#include <QHash>
#include <QString>
class QTextStream;
/**
Observes high-level ParaView events, and serializes them to a stream as Python
......@@ -50,24 +49,23 @@ must ensure that it goes out of scope before trying to playback the stream.
\sa pqEventTranslator, pqStdoutEventObserver, pqPythonEventSource.
*/
class pqPythonEventObserver :
public QObject
class pqPythonEventObserver : public pqEventObserver
{
Q_OBJECT
public:
pqPythonEventObserver(QTextStream& Stream);
pqPythonEventObserver(QObject* p=0);
~pqPythonEventObserver();
public slots:
void onRecordEvent(
const QString& Widget,
const QString& Command,
const QString& Arguments);
void setStream(QTextStream*);
private:
/// Stores a stream that will be used to store the Python output
QTextStream& Stream;
QHash<QString, QString> Names;
};
......
......@@ -163,7 +163,8 @@ public:
PyThreadState* MainThreadState;
};
pqPythonEventSource::pqPythonEventSource()
pqPythonEventSource::pqPythonEventSource(QObject* p)
: pqThreadedEventSource(p)
{
this->Internal = new pqInternal;
......@@ -213,11 +214,12 @@ bool pqPythonEventSource::event(QEvent* e)
void pqPythonEventSource::run()
{
const char* filename = this->Internal->FileName.toAscii().data();
FILE* pythonScript = fopen(filename, "r");
QString filename = this->Internal->FileName;
FILE* pythonScript = fopen(filename.toAscii().data(), "r");
if(!pythonScript)
{
// TODO: report error
printf("Unable to open python script\n");
return;
}
......@@ -230,7 +232,11 @@ void pqPythonEventSource::run()
Instance = this;
// finally run the script
PyRun_SimpleFile(pythonScript, filename);
int result = PyRun_SimpleFile(pythonScript, filename.toAscii().data());
if( result == 2 )
{
printf("invalid python file\n");
}
PyThreadState_Swap(NULL);
......@@ -241,6 +247,6 @@ void pqPythonEventSource::run()
fclose(pythonScript);
this->done();
this->done(result);
}
......@@ -43,7 +43,7 @@ class QTTESTING_EXPORT pqPythonEventSource :
public pqThreadedEventSource
{
public:
pqPythonEventSource();
pqPythonEventSource(QObject* p = 0);
~pqPythonEventSource();
void setContent(const QString& path);
......
......@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqEventTranslator.h"
#include "pqRecordEventsDialog.h"
#include "pqXMLEventObserver.h"
#include "pqEventObserver.h"
#include "ui_pqRecordEventsDialog.h"
......@@ -47,54 +47,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct pqRecordEventsDialog::pqImplementation
{
public:
pqImplementation(pqEventTranslator* translator, const QString& path) :
Translator(translator),
File(path)
pqImplementation(pqEventTranslator& translator,
pqEventObserver& observer)
: Translator(translator),