Salome HOME
c9d71efd190e10448cb1bc0e380295814f587503
[modules/med.git] / src / MEDCalc / gui / TestController.cxx
1 // Copyright (C) 2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "TestController.hxx"
21 #include "MEDModule.hxx"
22
23 #include <Basics_Utils.hxx>  // STDLOG() macro
24
25 #include <SUIT_Session.h>
26 #include <SUIT_Desktop.h>
27
28 #include <SALOMEconfig.h>
29 #include CORBA_CLIENT_HEADER(MEDEventListener)
30
31 #include <pqTestUtility.h>
32 #include <pqXMLEventObserver.h>
33 #include <pqXMLEventSource.h>
34
35 #include <pqQVTKWidgetEventPlayer.h>
36 #include <pqQVTKWidgetEventTranslator.h>
37
38 #include <pqTabbedMultiViewWidget.h>
39 #include <pqApplicationCore.h>
40 #include <pqTestingReaction.h>
41 #include <pqSaveScreenshotReaction.h>
42
43 #include <QFileDialog>
44 #include <QString>
45 #include <QDir>
46 #include <QIcon>
47 #include <QTimer>
48 #include <QEvent>
49
50 class PlayTestEvent: public QEvent {
51 public:
52   PlayTestEvent(QEvent::Type type, const std::string & filename): QEvent(type), _filename(filename) {}
53   virtual ~PlayTestEvent() {}
54   const std::string _filename;
55 };
56
57 TestController::TestController(MEDModule* mod):
58   _salomeModule(mod),
59   _desk(SUIT_Session::session()->activeApplication()->desktop()),
60   _tester(0), _lock_action(0),
61   _quitEventType(QEvent::registerEventType()),
62   _playEventType(QEvent::registerEventType()),
63   _aboutToPlayTest(false),
64   _myEventLoopStarted(false)
65 {
66   STDLOG("Creating a TestController");
67   _tester = new pqTestUtility(_desk);
68   _tester->addEventObserver("xml", new pqXMLEventObserver(_desk));
69   _tester->addEventSource("xml", new pqXMLEventSource(_desk));
70
71   QTimer::singleShot(0, this, SLOT(onMainEventLoopStarting()));
72 }
73
74 TestController::~TestController()
75 {
76   if (_tester)
77     delete _tester;
78   _tester = 0;
79 }
80
81 void
82 TestController::createActions() {
83   //
84   // Main actions
85   //
86   QString label   = tr("LAB_RECORD_TEST");
87   QString tooltip = tr("TIP_RECORD_TEST");
88   int actionId;
89   actionId = _salomeModule->createStandardAction(label,this, SLOT(onRecordTest()),QString(),tooltip);
90
91   // This action has to be placed in the general file menu
92   int menuId = _salomeModule->createMenu( tr( "MEN_FILE" ), -1,  1 );
93   _salomeModule->action(actionId)->setIconVisibleInMenu(false);
94   _salomeModule->createMenu(actionId, menuId, 60);
95
96   label   = tr("LAB_PLAY_TEST");
97   tooltip = tr("TIP_PLAY_TEST");
98   actionId = _salomeModule->createStandardAction(label,this, SLOT(onPlayTest()),QString(),tooltip);
99   _salomeModule->action(actionId)->setIconVisibleInMenu(false);
100   _salomeModule->createMenu(actionId, menuId, 70);
101
102   label   = tr("LAB_LOCK_TEST");
103   tooltip = tr("TIP_LOCK_TEST");
104   actionId = _salomeModule->createStandardAction(label,this, SLOT(onLockViewSize()),QString(),tooltip);
105   _salomeModule->action(actionId)->setIconVisibleInMenu(false);
106   _salomeModule->action(actionId)->setCheckable(true);
107   _lock_action = _salomeModule->action(actionId);
108   _salomeModule->createMenu(actionId, menuId, 70);
109
110   label   = tr("LAB_SNAP_TEST");
111   tooltip = tr("TIP_SNAP_TEST");
112   actionId = _salomeModule->createStandardAction(label,this, SLOT(onTakeSnapshot()),QString(),tooltip);
113   _salomeModule->action(actionId)->setIconVisibleInMenu(false);
114   _salomeModule->createMenu(actionId, menuId, 70);
115 }
116
117 void TestController::onRecordTest()
118 {
119   QString fileName =
120       QFileDialog::getSaveFileName(_desk, "Save test", QString(), QString("XML file (*.xml)"));
121   if (!fileName.isEmpty())
122     {
123       QApplication::setActiveWindow(_desk); //mandatory otherwise record pop up doesn't show up
124       _tester->recordTests(fileName);
125     }
126 }
127
128
129 void TestController::onPlayTest()
130 {
131   QString fileName =
132       QFileDialog::getOpenFileName(_desk, "Open test", QString(), QString("XML file (*.xml)"));
133   if (!fileName.isEmpty())
134     _tester->playTests(fileName);
135 }
136
137 void TestController::onLockViewSize() const
138 {
139   pqTestingReaction::lockViewSize(_lock_action->isChecked());
140 }
141
142 void TestController::onTakeSnapshot() const
143 {
144   pqSaveScreenshotReaction::saveScreenshot();
145 }
146
147 void TestController::onRequestTermination()
148 {
149   // Check if test playing
150   if (_tester->playingTest() || _aboutToPlayTest)
151     {
152       QEvent * e = new QEvent((QEvent::Type)_quitEventType);
153       QApplication::postEvent(this, e);
154     }
155   else
156     {
157       _salomeModule->requestSALOMETermination();
158     }
159 }
160
161 void
162 TestController::customEvent(QEvent * event)
163 {
164   if (event->type() == _quitEventType)
165     {
166       if(!isMainEventLoopStarted())
167           // Repost (=delay)
168           QApplication::postEvent(this, new QEvent((QEvent::Type)_quitEventType));
169       else
170           onRequestTermination();
171     }
172   else if (event->type() == _playEventType)
173     {
174       PlayTestEvent * e = dynamic_cast<PlayTestEvent *>(event);
175       if (e)
176         {
177 //          // Wait for main event loop to start:
178           if(!isMainEventLoopStarted())
179               // Repost (=delay)
180               QApplication::postEvent(this, new PlayTestEvent((QEvent::Type)_playEventType, e->_filename));
181           else
182             {
183               STDLOG("About to play test " << e->_filename);
184               _tester->playTests(e->_filename.c_str());
185               _aboutToPlayTest = false;
186               STDLOG("Done playing test " << e->_filename);
187             }
188         }
189     }
190   else
191     { QObject::customEvent(event);  }
192 }
193
194 void
195 TestController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
196 {
197   if ( event->type == MEDCALC::EVENT_PLAY_TEST ) {
198       /* [ABN] Post an event. Indeed, calling the function directly would prevent the proper refresh of the
199        * GUI which also needs to go through the MED event loop (WorkspaceController::processWorkspaceEvent)
200        */
201       _aboutToPlayTest = true; // to prevent an early quit!
202       PlayTestEvent * e  = new PlayTestEvent((QEvent::Type)_playEventType, std::string(event->filename));
203       QApplication::postEvent(this, e);
204   }
205   else if ( event->type == MEDCALC::EVENT_QUIT_SALOME ) {
206       // [ABN] again: post as an event to give a chance to other events (piled up by test
207       // scenarios for example) to execute:
208       QEvent * e = new QEvent((QEvent::Type)_quitEventType);
209       QApplication::postEvent(this, e);
210   }
211 }
212
213 void TestController::onMainEventLoopStarting()
214 {
215   _myEventLoopStarted = true;
216 }