Commit d341f788 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

ENH: ParaView Customization/Branding Commit.

This commit makes it possible to make custom clients based on ParaView. There
are a host of changes in this commit that restucture the Qt client level
classes.

For more details refer to the following links:

http://www.paraview.org/ParaView3/index.php/ParaView-based_Applications

http://www.paraview.org/Wiki/Writing_Custom_Applications
parent e0afd8c1
......@@ -55,6 +55,30 @@ bool pqAbstractActivateEventPlayer::playEvent(QObject* Object,
if(Command != "activate")
return false;
if (QMenuBar* const menu_bar = qobject_cast<QMenuBar*>(Object))
{
QMenu* sub_menu = menu_bar->findChild<QMenu*>(Arguments);
if (sub_menu)
{
QAction* action = 0;
foreach (QAction* cur_action, menu_bar->actions())
{
if (cur_action->menu() == sub_menu)
{
action = cur_action;
break;
}
}
if (action)
{
menu_bar->setActiveAction(action);
return true;
}
}
Error = true;
return true;
}
if(QMenu* const object = qobject_cast<QMenu*>(Object))
{
......@@ -107,7 +131,8 @@ bool pqAbstractActivateEventPlayer::playEvent(QObject* Object,
if(QMenuBar* menu_bar = qobject_cast<QMenuBar*>(p))
{
menu_bar->setActiveAction(next->menuAction());
while(!next->isVisible())
int max_wait = 0;
while(!next->isVisible() && (++max_wait) <= 10)
{
pqEventDispatcher::processEventsAndWait(100);
}
......@@ -131,7 +156,8 @@ bool pqAbstractActivateEventPlayer::playEvent(QObject* Object,
menu->setActiveAction(next->menuAction());
#endif
while(!next->isVisible())
int max_wait = 0;
while(!next->isVisible() && (++max_wait) <= 10)
{
pqEventDispatcher::processEventsAndWait(100);
}
......@@ -149,12 +175,21 @@ bool pqAbstractActivateEventPlayer::playEvent(QObject* Object,
QApplication::sendEvent(object, &keyDown);
QApplication::sendEvent(object, &keyUp);
QApplication::processEvents();
return true;
}
if(QAbstractButton* const object = qobject_cast<QAbstractButton*>(Object))
{
object->click();
QApplication::processEvents();
return true;
}
if (QAction* const action = qobject_cast<QAction*>(Object))
{
action->activate(QAction::Trigger);
QApplication::processEvents();
return true;
}
......
......@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QAbstractButton>
#include <QtDebug>
#include <QAction>
pqAbstractBooleanEventPlayer::pqAbstractBooleanEventPlayer(QObject* p)
: pqWidgetEventPlayer(p)
......@@ -54,6 +55,15 @@ bool pqAbstractBooleanEventPlayer::playEvent(QObject* Object, const QString& Com
return true;
}
if (QAction* const action = qobject_cast<QAction*>(Object))
{
if (action->isChecked() != value)
{
action->trigger();
}
return true;
}
qCritical() << "calling set_boolean on unhandled type " << Object;
Error = true;
return true;
......
......@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QKeyEvent>
#include <QMouseEvent>
#include <QPushButton>
#include <QToolButton>
#include <iostream>
......@@ -91,11 +92,17 @@ bool pqAbstractButtonEventTranslator::translateEvent(QObject* Object, QEvent* Ev
return true;
}
void pqAbstractButtonEventTranslator::onActivate(QAbstractButton* object)
void pqAbstractButtonEventTranslator::onActivate(QAbstractButton* actualObject)
{
if(object->isCheckable())
QObject* object = actualObject;
QToolButton* tb = qobject_cast<QToolButton*>(object);
if (tb && tb->defaultAction())
{
const bool new_value = !object->isChecked();
object = tb->defaultAction();
}
if(actualObject->isCheckable())
{
const bool new_value = !actualObject->isChecked();
emit recordEvent(object, "set_boolean", new_value ? "true" : "false");
}
else
......
This diff is collapsed.
......@@ -36,46 +36,57 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "QtTestingExport.h"
#include <QObject>
#include <QTimer>
#include <QEvent>
class pqEventPlayer;
class pqEventSource;
class QTTESTING_EXPORT pqEventDispatcher :
public QObject
/// pqEventDispatcher is responsible for taking each "event" from the test and
/// then "playing" it using the player. The dispatcher is the critical component
/// of this playback since it decides when it's time to dispatch the next
/// "event" from the test.
class QTTESTING_EXPORT pqEventDispatcher : public QObject
{
Q_OBJECT
typedef QObject Superclass;
public:
pqEventDispatcher();
pqEventDispatcher(QObject* parent=0);
~pqEventDispatcher();
/** Retrieves events from the given event source, dispatching them to
the given event player for test case playback. Note that playback is
asynchronous - the call to playEvents() returns immediately. Callers
must ensure that the source, dispatcher, and player objects remain
in-scope until either the succeeded() or failed() signal is emitted
to indicate that playback has finished. */
void playEvents(pqEventSource& source, pqEventPlayer& player);
/// Retrieves events from the given event source, dispatching them to
/// the given event player for test case playback. This call blocks until all
/// the events from the source have been played back (or failure). Returns
/// true if playback was successful.
bool playEvents(pqEventSource& source, pqEventPlayer& player);
/** Wait function provided for players that need to wait for the GUI
to perform a certain action */
static void processEventsAndWait(int ms);
signals:
void succeeded();
void failed();
void readyPlayNextEvent();
private slots:
void playNextEvent();
void checkPlayNextEvent();
void queueNextEvent();
protected:
/// filter application level events. This is not really a "filter", but more
/// like an observer of the application level events.
bool eventFilter(QObject *obj, QEvent *ev);
private:
void stopPlayback();
class pqImplementation;
pqImplementation* const Implementation;
signals:
void triggerPlayEventStack(void*);
protected slots:
/// Plays event set, until
/// 2> All events have been processed
/// 3> There's an error.
void playEventStack(void* activeWidget);
void onMenuTimerTimeout();
protected:
bool PlayBackFinished;
bool PlayBackStatus;
pqEventSource* ActiveSource;
pqEventPlayer* ActivePlayer;
QTimer AdhocMenuTimer;
QList<QWidget*> ActiveModalWidgetStack;
};
#endif // !_pqEventDispatcher_h
......@@ -57,8 +57,18 @@ bool pqMenuEventTranslator::translateEvent(QObject* Object, QEvent* Event,
return false;
}
if(menubar)
if (menubar)
{
QMouseEvent* e = static_cast<QMouseEvent*>(Event);
if (e->button() == Qt::LeftButton)
{
QAction* action = menubar->actionAt(e->pos());
if (action && action->menu())
{
QString which = action->menu()->objectName();
emit recordEvent(menubar, "activate", which);
}
}
return true;
}
......@@ -86,7 +96,7 @@ bool pqMenuEventTranslator::translateEvent(QObject* Object, QEvent* Event,
if(e->button() == Qt::LeftButton)
{
QAction* action = menu->actionAt(e->pos());
if(action && !action->menu())
if (action && !action->menu())
{
QString which = action->objectName();
if(which == QString::null)
......
......@@ -45,22 +45,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqPythonEventObserver.h"
#endif
//-----------------------------------------------------------------------------
pqTestUtility::pqTestUtility(QObject* p) :
QObject(p)
{
QObject::connect(
&this->Dispatcher,
SIGNAL(succeeded()),
this,
SLOT(testSucceeded()));
QObject::connect(
&this->Dispatcher,
SIGNAL(failed()),
this,
SLOT(testFailed()));
this->PlayingTest = false;
this->Translator.addDefaultWidgetEventTranslators();
this->Player.addDefaultWidgetEventPlayers();
......@@ -71,25 +60,30 @@ pqTestUtility::pqTestUtility(QObject* p) :
#endif
}
//-----------------------------------------------------------------------------
pqTestUtility::~pqTestUtility()
{
}
//-----------------------------------------------------------------------------
pqEventDispatcher* pqTestUtility::dispatcher()
{
return &this->Dispatcher;
}
//-----------------------------------------------------------------------------
pqEventPlayer* pqTestUtility::eventPlayer()
{
return &this->Player;
}
//-----------------------------------------------------------------------------
pqEventTranslator* pqTestUtility::eventTranslator()
{
return &this->Translator;
}
//-----------------------------------------------------------------------------
void pqTestUtility::addEventSource(const QString& fileExtension, pqEventSource* source)
{
QMap<QString, pqEventSource*>::iterator iter;
......@@ -104,6 +98,7 @@ void pqTestUtility::addEventSource(const QString& fileExtension, pqEventSource*
source->setParent(this);
}
//-----------------------------------------------------------------------------
void pqTestUtility::addEventObserver(const QString& fileExtension,
pqEventObserver* observer)
{
......@@ -125,27 +120,49 @@ void pqTestUtility::addEventObserver(const QString& fileExtension,
}
void pqTestUtility::playTests(const QString& filename)
//-----------------------------------------------------------------------------
bool pqTestUtility::playTests(const QString& filename)
{
QFileInfo info(filename);
QString suffix = info.completeSuffix();
QMap<QString, pqEventSource*>::iterator iter;
iter = this->EventSources.find(suffix);
if(info.isReadable() && iter != this->EventSources.end())
{
iter.value()->setContent(filename);
this->Dispatcher.playEvents(*iter.value(), this->Player);
}
QStringList files;
files << filename;
return this->playTests(files);
}
void pqTestUtility::playTests(const QStringList& filenames)
//-----------------------------------------------------------------------------
bool pqTestUtility::playTests(const QStringList& filenames)
{
foreach(QString filename, filenames)
if (this->PlayingTest)
{
this->playTests(filename);
qCritical("playTests() cannot be called recursively.");
return false;
}
this->PlayingTest = true;
bool success = true;
foreach (QString filename, filenames)
{
QFileInfo info(filename);
QString suffix = info.completeSuffix();
QMap<QString, pqEventSource*>::iterator iter;
iter = this->EventSources.find(suffix);
if(info.isReadable() && iter != this->EventSources.end())
{
iter.value()->setContent(filename);
if (!this->Dispatcher.playEvents(*iter.value(), this->Player))
{
// dispatcher returned failure, don't continue with rest of the tests
// and flag error.
success = false;
break;
}
}
}
this->PlayingTest = false;
return success;
}
//-----------------------------------------------------------------------------
void pqTestUtility::recordTests(const QString& filename)
{
#if defined(Q_WS_MAC)
......@@ -185,11 +202,3 @@ void pqTestUtility::recordTests(const QString& filename)
dialog->show();
}
void pqTestUtility::testSucceeded()
{
}
void pqTestUtility::testFailed()
{
}
......@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QSet>
#include <QTextStream>
#include <QFile>
#include <QStringList>
#include "QtTestingExport.h"
#include "pqEventDispatcher.h"
......@@ -58,11 +59,15 @@ public:
public:
/// get the event dispatcher
/// Get the event dispatcher. Dispatcher is used to play tests back.
pqEventDispatcher* dispatcher();
/// get the event player
/// Get the event player. This the test-file-interpreter (if you will), that
/// parses the test file and creates events from it that can be dispatched by
/// the pqEventDispatcher.
pqEventPlayer* eventPlayer();
/// get the event translator
/// Get the event translator. This is used for recording tests.
pqEventTranslator* eventTranslator();
/// add an event source for playback of files
......@@ -75,25 +80,25 @@ public:
/// A pqPythonEventObserver is automatically added if Python support is enabled.
void addEventObserver(const QString& fileExtension,
pqEventObserver* translator);
public slots:
/// start the playing of tests in a file
virtual void playTests(const QString& filename);
/// start playing the tests in the collection of files.
virtual void playTests(const QStringList& filenames);
/// Returns if the utility is currently playing a test.
bool playingTest() const
{ return this->PlayingTest; }
/// start the recording of tests to a file
virtual void recordTests(const QString& filename);
/// Plays back the test given by the filename(s). This is a blocking call i.e.
/// it does not return until the test has been played or aborted due to
/// failure. Returns true if the test played successfully.
bool playTests(const QString& filename);
virtual bool playTests(const QStringList& filenames);
protected slots:
virtual void testSucceeded();
virtual void testFailed();
/// start the recording of tests to a file
void recordTests(const QString& filename);
protected:
pqEventDispatcher Dispatcher;
pqEventPlayer Player;
pqEventTranslator Translator;
bool PlayingTest;
QMap<QString, pqEventSource*> EventSources;
QMap<QString, pqEventObserver*> EventObservers;
......
......@@ -180,6 +180,11 @@ void pqThreadedEventSource::guiAcknowledge()
this->Internal->Waiting = 0;
}
void pqThreadedEventSource::msleep(int msec)
{
pqInternal::ThreadHelper::msleep(msec);
}
void pqThreadedEventSource::done(int success)
{
if(success == 0)
......
......@@ -80,6 +80,9 @@ public:
/** Give the testing thread an acknowledgement.
For use by the GUI thread */
void guiAcknowledge();
// helper method to sleep.
static void msleep(int msecs);
private slots:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment