Salome HOME
Copyright update 2022
[modules/med.git] / src / MEDCalc / gui / TestController.cxx
index 8023c6816a8e77fcfc8251082586cd29916c3626..f1abfa55f098fb5632e2c0e55bdb2adcd9f9d0b1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2016  CEA/DEN, EDF R&D
+// Copyright (C) 2016-2022  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 #include <QDir>
 #include <QIcon>
 #include <QTimer>
+#include <QEvent>
+
+class PlayTestEvent: public QEvent {
+public:
+  PlayTestEvent(QEvent::Type type, const std::string & filename): QEvent(type), _filename(filename) {}
+  virtual ~PlayTestEvent() {}
+  const std::string _filename;
+};
 
 TestController::TestController(MEDModule* mod):
   _salomeModule(mod),
   _desk(SUIT_Session::session()->activeApplication()->desktop()),
-  _tester(0), _lock_action(0)
+  _tester(0), _lock_action(0),
+  _quitEventType(QEvent::registerEventType()),
+  _playEventType(QEvent::registerEventType()),
+  _aboutToPlayTest(false),
+  _myEventLoopStarted(false)
 {
   STDLOG("Creating a TestController");
   _tester = new pqTestUtility(_desk);
   _tester->addEventObserver("xml", new pqXMLEventObserver(_desk));
   _tester->addEventSource("xml", new pqXMLEventSource(_desk));
+
+  QApplication::instance()->installEventFilter(this);
+  //QTimer::singleShot(0, this, SLOT(onMainEventLoopStarting()));
 }
 
 TestController::~TestController()
@@ -120,21 +135,61 @@ void TestController::onPlayTest()
     _tester->playTests(fileName);
 }
 
-void TestController::onPlayTestScenario()
+void TestController::onLockViewSize() const
 {
-  STDLOG("@@@@ About to play test " << _test_scenario.toStdString());
-  _tester->playTests(_test_scenario);
-  STDLOG("@@@@ Done playing test " << _test_scenario.toStdString());
+  pqTestingReaction::lockViewSize(_lock_action->isChecked());
 }
 
-void TestController::onLockViewSize()
+void TestController::onTakeSnapshot() const
 {
-  pqTestingReaction::lockViewSize(_lock_action->isChecked());
+  pqSaveScreenshotReaction::saveScreenshot();
 }
 
-void TestController::onTakeSnapshot()
+void TestController::onRequestTermination()
 {
-  pqSaveScreenshotReaction::saveScreenshot();
+  // Check if test playing
+  if (_tester->playingTest() || _aboutToPlayTest)
+    {
+      QEvent * e = new QEvent((QEvent::Type)_quitEventType);
+      QApplication::postEvent(this, e);
+    }
+  else
+    {
+      _salomeModule->requestSALOMETermination();
+    }
+}
+
+void
+TestController::customEvent(QEvent * event)
+{
+  if (event->type() == _quitEventType)
+    {
+      if(!isMainEventLoopStarted())
+          // Repost (=delay)
+          QApplication::postEvent(this, new QEvent((QEvent::Type)_quitEventType));
+      else
+          onRequestTermination();
+    }
+  else if (event->type() == _playEventType)
+    {
+      PlayTestEvent * e = dynamic_cast<PlayTestEvent *>(event);
+      if (e)
+        {
+//          // Wait for main event loop to start:
+          if(!isMainEventLoopStarted())
+              // Repost (=delay)
+              QApplication::postEvent(this, new PlayTestEvent((QEvent::Type)_playEventType, e->_filename));
+          else
+            {
+              STDLOG("About to play test " << e->_filename);
+              _tester->playTests(e->_filename.c_str());
+              _aboutToPlayTest = false;
+              STDLOG("Done playing test " << e->_filename);
+            }
+        }
+    }
+  else
+    { QObject::customEvent(event);  }
 }
 
 void
@@ -144,8 +199,27 @@ TestController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
       /* [ABN] Post an event. Indeed, calling the function directly would prevent the proper refresh of the
        * GUI which also needs to go through the MED event loop (WorkspaceController::processWorkspaceEvent)
        */
-      _test_scenario = QString(event->filename);
-      QTimer::singleShot(100, this, SLOT(onPlayTestScenario()));
+      _aboutToPlayTest = true; // to prevent an early quit!
+      PlayTestEvent * e  = new PlayTestEvent((QEvent::Type)_playEventType, std::string(event->filename));
+      QApplication::postEvent(this, e);
   }
+  else if ( event->type == MEDCALC::EVENT_QUIT_SALOME ) {
+      // [ABN] again: post as an event to give a chance to other events (piled up by test
+      // scenarios for example) to execute:
+      QEvent * e = new QEvent((QEvent::Type)_quitEventType);
+      QApplication::postEvent(this, e);
+  }
+}
+
+void TestController::onMainEventLoopStarting()
+{
+  _myEventLoopStarted = true;
+  QApplication::instance()->removeEventFilter(this);
 }
 
+bool TestController::eventFilter(QObject *obj, QEvent *event)
+{
+  if ( obj == QApplication::instance() && event->type() == 9999 )
+    onMainEventLoopStarting();
+  return QObject::eventFilter(obj, event);
+}