evorobotviewer.cpp
1 /********************************************************************************
2  * FARSA Experiments Library *
3  * Copyright (C) 2007-2012 *
4  * Stefano Nolfi <stefano.nolfi@istc.cnr.it> *
5  * Onofrio Gigliotta <onofrio.gigliotta@istc.cnr.it> *
6  * Gianluca Massera <emmegian@yahoo.it> *
7  * Tomassino Ferrauto <tomassino.ferrauto@istc.cnr.it> *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the Free Software *
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
22  ********************************************************************************/
23 
24 #include "evorobotviewer.h"
25 #include "abstracttest.h"
26 #include "tests.h"
27 #include "total99resources.h"
28 #include <QGridLayout>
29 #include <QPushButton>
30 #include <QCheckBox>
31 #include <QFileDialog>
32 #include <QVBoxLayout>
33 #include <QDir>
34 #include <QFileInfo>
35 #include <QFile>
36 #include <QEvent>
37 #include <QCoreApplication>
38 
39 using namespace qglviewer;
40 
41 // All the suff below is to avoid warnings on Windows about the use of unsafe
42 // functions. This should be only a temporary workaround, the solution is stop
43 // using C string and file functions...
44 #if defined(_MSC_VER)
45  #pragma warning(push)
46  #pragma warning(disable:4996)
47 #endif
48 
49 namespace farsa {
50 
51 EvoRobotViewer::EvoRobotViewer( EvoRobotComponent* component )
53  evorobot = component;
54  ga = evorobot->getGA();
56 
57  // Declaring which resources we will need to use
58  usableResources(QStringList() << "world" << "experiment");
59 
60  // Global connections
61  ResourcesLocker locker(this);
62  connect( evorobot, SIGNAL(actionFinished()), this, SLOT(onActionFinished()) );
63 }
64 
66 {
67  // Nothing to do
68  // --- All objects are destroyed in others parts because none of them are owend by this object
69 }
70 
71 void EvoRobotViewer::fillActionsMenu( QMenu* actionsMenu ) {
72  actionsMenu->addAction( "Evolve", evorobot, SLOT(evolve()) );
73  actionsMenu->addAction( "Stop", evorobot, SLOT(stop()) );
74 }
75 
76 QList<ParameterSettableUIViewer> EvoRobotViewer::getViewers( QWidget* parent, Qt::WindowFlags flags ) {
77  QList<ParameterSettableUIViewer> viewsList;
78  viewsList.append( evogaControls( parent, flags ) );
79 // viewsList.append( icubview( parent, flags ) );
80  viewsList.append( fitview( parent, flags ) );
81  viewsList.append( statview( parent, flags ) );
82  viewsList.append( renderWorld( parent, flags ) );
83  //--- check if there are some special view for the testing actions
84  QStringList testsList = AvailableTestList::getList();
85  for (int i = 0; i < testsList.size(); i++) {
86  TestIndividual* testIndividual = dynamic_cast<TestIndividual*>(AvailableTestList::getTest(testsList[i]));
87  if ( testIndividual ) {
88  viewsList.append( testIndividualUI( testIndividual, parent, flags ) );
89  }
90  }
91  return viewsList;
92 }
93 
94 void EvoRobotViewer::addAdditionalMenus( QMenuBar* menuBar ) {
95  QMenu* testMenu = menuBar->addMenu( "Tests" );
96  QStringList testsList = AvailableTestList::getList();
97  for (int i = 0; i < testsList.size(); i++) {
98  AbstractTest* test = AvailableTestList::getTest(testsList[i]);
99  QAction* action = testMenu->addAction( test->menuText(), evorobot, SLOT(runTestFromQAction()) );
100  action->setData( QVariant(testsList[i]) );
101  action->setToolTip( test->tooltip() );
102  action->setIcon( QIcon( test->iconFilename() ) );
103  }
104 }
105 
106 void EvoRobotViewer::resourceChanged(QString resourceName, ResourceChangeType changeType)
107 {
108  // Here we have to update the connection with the advanced slot of world
109  if ((resourceName == "world") && (changeType != Deleted)) {
110  World* world = getResource<World>();
111 
112  connect( world, SIGNAL(advanced()), this, SLOT(onWorldAdvance()), Qt::QueuedConnection );
113  }
114 }
115 
116 ParameterSettableUIViewer EvoRobotViewer::renderWorld( QWidget* parent, Qt::WindowFlags flags )
117 {
118  // Creating the wrapper class for RenderWorld and sharing resources
119  renderworldwrapper = new RenderWorldWrapperWidget(parent, flags);
120  renderworldwrapper->shareResourcesWith(this);
121 
122  return ParameterSettableUIViewer(renderworldwrapper, "RenderWorld");
123 }
124 
125 ParameterSettableUIViewer EvoRobotViewer::evogaControls( QWidget* parent, Qt::WindowFlags flags ) {
126  QWidget* widget = new QWidget( parent, flags );
127  QGridLayout* lay = new QGridLayout( widget );
128  //lay->setContentsMargins(0,0,0,0);
129 
130  // --- visualizzaione del trial corrente, e step corrente
131  infoEvoga = new QLabel( "Information", widget );
132  infoEvoga->setStyleSheet( "QLabel { font: bold normal large \"Courier\" }" );
133  lay->addWidget( infoEvoga, 0, 0, 1, 2 );
134 
135  QPushButton* bt = new QPushButton( "Do Step", widget );
136  bt->setAutoRepeat(true);
137  bt->setEnabled( false );
138  connect( bt, SIGNAL(clicked(bool)), ga, SLOT(doNextStep()) );
139 
140  QCheckBox* cb = new QCheckBox( "Step by Step Mode", widget );
141  connect( cb, SIGNAL(clicked(bool)), ga, SLOT(enableStepByStep(bool)) );
142  connect( cb, SIGNAL(clicked(bool)), bt, SLOT(setEnabled(bool)) );
143 
144  lay->addWidget( cb, 1, 0 );
145  lay->addWidget( bt, 1, 1 );
146 
147  bt = new QPushButton( "Next Trial", widget );
148  connect( bt, SIGNAL(clicked()), this, SLOT(evogaNextTrial()) );
149  lay->addWidget( bt, 2, 0, 1, 2 );
150 
151  //----- Skip Trial... Go to Trial number N
152 
153  return ParameterSettableUIViewer( widget, "Evoga Controls" );
154 }
155 
156 void EvoRobotViewer::evogaNextTrial() {
158 }
159 
160 ParameterSettableUIViewer EvoRobotViewer::fitview( QWidget* parent, Qt::WindowFlags flags )
161 {
162  // Here we also create the fitness viewer
163  ftv = new FitViewer(3,4000,parent,flags);
164  ftv->setChunkProperties(0, "MaxFit", Qt::red, true);
165  ftv->setChunkProperties(1, "AverageFit", Qt::green, true);
166  ftv->setChunkProperties(2, "MinFit", Qt::blue, true);
167  ftv->setLabels(QString("EvoICub Fitness Monitor"), QString("Generations"), QString("Fitness"));
168  ftv->setGeometry(50, 50, 500, 500);
169  ftv->setWindowTitle( "Fitness Curves" );
170  connect( ga, SIGNAL(startingReplication(int)),
171  this, SLOT(onEvogaStartingReplication(int)), Qt::QueuedConnection );
172  connect( ga, SIGNAL(recoveredInterruptedEvolution(QString)),
173  this, SLOT(onEvogaRecoveredInterruptedEvolution(QString)), Qt::QueuedConnection );
174  connect( ga, SIGNAL(endGeneration(int,int,int,int)),
175  this, SLOT(onEvogaEndGeneration(int,int,int,int)), Qt::QueuedConnection );
176  return ParameterSettableUIViewer( ftv, "Fitness monitor" );
177 }
178 
179 // ParameterSettableUIViewer EvoRobotViewer::icubview( QWidget* parent, Qt::WindowFlags flags )
180 // {
181 // m_icubview = new VisionMapSensorGui(parent,flags);
182 // m_icubview->setWindowTitle( "iCub Camera" );
183 // m_icubview->resize( 200, 200 );
184 // m_icubview->hide();
185 // return ParameterSettableUIViewer( m_icubview, "iCub camera" );
186 // }
187 
188 ParameterSettableUIViewer EvoRobotViewer::statview( QWidget* parent, Qt::WindowFlags flags )
189 {
190  statViewer = new QWidget( parent, flags );
191  statViewer->setWindowTitle( "Statictis Viewer" );
192  QGridLayout* lay = new QGridLayout( statViewer );
193  QPushButton* but = new QPushButton( "Load a Stat File", statViewer );
194  connect( but, SIGNAL(clicked()), this, SLOT(loadStat()) );
195  lay->addWidget( but, 0, 0 );
196  but = new QPushButton( "Load All Stat", statViewer );
197  connect( but, SIGNAL(clicked()), this, SLOT(loadAllStat()) );
198  lay->addWidget( but, 0, 1 );
199  return ParameterSettableUIViewer( statViewer, "Statistic Viewer" );
200 }
201 
202 void EvoRobotViewer::loadStat() {
203  QString filename = QFileDialog::getOpenFileName(statViewer, tr("Open Stat File"), ".", tr("Files with statistics (*.fit *.ini)"));
204  if (filename.isEmpty()) {
205  return;
206  }
207  FitViewer* fitViewer = statViewer->findChild<FitViewer*>( "statFitViewer" );
208  if ( fitViewer ) {
209  delete fitViewer;
210  }
211  fitViewer = new FitViewer(3, 4000, statViewer);
212  fitViewer->setObjectName( "statFitViewer" );
213  fitViewer->setLabels(QString("Stat monitor. File: ").append(filename), QString("Generation"), QString("Fitnes"));
214  fitViewer->setChunkProperties(0, "MaxFit", Qt::red,true);
215  fitViewer->setChunkProperties(1, "Average", Qt::green,true);
216  fitViewer->setChunkProperties(2, "Minimum", Qt::blue,true);
217  fitViewer->loadRawData(0, filename, 0);
218  fitViewer->loadRawData(1, filename, 1);
219  fitViewer->loadRawData(2, filename, 2);
220  QGridLayout* lay = qobject_cast<QGridLayout*>( statViewer->layout() );
221  lay->addWidget( fitViewer, 1, 0, 1, 2 );
222  lay->setRowStretch( 1, 2 );
223  fitViewer->show();
224 }
225 
226 void EvoRobotViewer::loadAllStat()
227 {
228  FitViewer* fitViewer = statViewer->findChild<FitViewer*>( "statFitViewer" );
229  if ( fitViewer ) {
230  delete fitViewer;
231  }
232 
233  QDir currentDir;
234  QFileInfoList statFiles = currentDir.entryInfoList( QStringList() << "*.fit", QDir::Files, QDir::Name );
235 
236  fitViewer = new FitViewer(statFiles.size(), ga->getNumOfGenerations(), statViewer);
237  fitViewer->setObjectName( "statFitViewer" );
238  QString title = QString("Stat monitor");
239  fitViewer->setLabels(title, QString("Generation"), QString("Fitness"));
240 
241  QColor colors[10] = { QColor(Qt::red), QColor(Qt::green), QColor(Qt::blue), QColor(Qt::cyan),
242  QColor(Qt::magenta), QColor(Qt::darkYellow), QColor(Qt::gray), QColor(255, 140, 0, 255),
243  QColor(153, 50, 204, 255), QColor(Qt::black) };
244  for(int i=0; i<statFiles.size(); i++ ) {
245  QFileInfo statFile = statFiles[i];
246  QColor col = colors[i%10];
247  fitViewer->setChunkProperties( i, QString("Seed:").append(statFile.baseName().split("S").last()), col, true );
248  fitViewer->loadRawData( i, statFile.fileName(), 0 );
249  }
250  fitViewer->sortchunks();
251  QGridLayout* lay = qobject_cast<QGridLayout*>( statViewer->layout() );
252  lay->addWidget( fitViewer, 1, 0, 1, 2 );
253  lay->setRowStretch( 1, 2 );
254  fitViewer->show();
255 }
256 
257 ParameterSettableUIViewer EvoRobotViewer::testIndividualUI( TestIndividual* test, QWidget* parent, Qt::WindowFlags flags ) {
258  TestIndividualGUI* testIndUI = new TestIndividualGUI( test, parent, flags );
259  testIndUI->setWindowTitle( "Select the Individual to Test" );
260  return ParameterSettableUIViewer( testIndUI, "Individual to Test", QString(), "From this view you can select an individual to test using the \"TestIndividual\" from the \"Tests\" menu" );
261 }
262 
263 void EvoRobotViewer::onWorldAdvance() {
264  ResourcesLocker locker(this);
265 
266  EvoRobotExperiment* exp = getResource<EvoRobotExperiment>("experiment");
267 
268  if ( exp->getActivityPhase() == EvoRobotExperiment::INTEST ) {
269  renderworldwrapper->updateRenderWorld();
270 // if (m_icubview != NULL) {
271 // m_icubview->setImage( exp->getResource<PhyiCub>( "robot" ) ); // update the iCub camera widget
272 // }
273  }
274  // visualizza su EvoGa Controls informazioni su step e trial
275  infoEvoga->setText( QString( "Step %1 of %2 --- Trial %3 of %4" )
276  .arg( exp->getCurStep(), 5 ).arg( exp->getNSteps() )
277  .arg( exp->getCurTrial(), 5 ).arg( exp->getNTrials() ) );
278 }
279 
280 void EvoRobotViewer::onEvogaStartingReplication( int /*replication*/ ) {
281  ftv->reset();
282 }
283 
284 void EvoRobotViewer::onEvogaRecoveredInterruptedEvolution( QString statfile ) {
285  ftv->loadRawData(0,statfile,0);
286  ftv->loadRawData(1,statfile,1);
287  ftv->loadRawData(2,statfile,2);
288 }
289 
290 void EvoRobotViewer::onEvogaEndGeneration( int generation, int fmax, int faverage, int fmin ) {
291  ftv->setChunkValue(0,generation,fmax);
292  ftv->setChunkValue(1,generation,faverage);
293  ftv->setChunkValue(2,generation,fmin);
294  ftv->diplayUntilStep(generation);
295  ftv->update();
296 }
297 
298 void EvoRobotViewer::onActionFinished() {
299  infoEvoga->setText( evorobot->status() );
300 }
301 
302 namespace {
303  // A custom QEvent to force update of RenderWorldWrapperWidget
304  class ForceRenderWorldUpdateEvent : public QEvent
305  {
306  public:
307  ForceRenderWorldUpdateEvent() :
308  QEvent(QEvent::User)
309  {
310  }
311 
312  virtual ~ForceRenderWorldUpdateEvent()
313  {
314  }
315  };
316 }
317 
318 RenderWorldWrapperWidget::RenderWorldWrapperWidget(QWidget* parent, Qt::WindowFlags flags) :
319  QWidget(parent, flags),
321  m_renderWorld(new RenderWorld(this, "world")),
322  m_layout(new QVBoxLayout(this)),
323  m_renderWorldStateRestored(false),
324  m_setCameraToLookAtRobot(false),
325  m_robotTm(wMatrix::identity())
326 {
327  // Setting some window property and creating the layout that will contain renderworld
328  setWindowTitle("3D World");
329  m_layout->setContentsMargins(0, 0, 0, 0);
330  m_layout->addWidget(m_renderWorld);
331  const QString stateFileName = ".evolver.xml";
332  m_renderWorld->setStateFileName(stateFileName);
333  if (QFile::exists(stateFileName)) {
334  m_renderWorldStateRestored = true;
335  m_renderWorld->restoreStateFromFile();
336  }
337 
338  // Declaring which resources we will need to use
339  usableResources(QStringList() << "robot");
340 }
341 
343 {
344  // Nothing to do here
345 }
346 
348 {
349  if (m_setCameraToLookAtRobot) {
350  lookAtRobot();
351 
352  m_setCameraToLookAtRobot = false;
353  // Setting this to true so that the next time the robot changes we don't move camera
354  m_renderWorldStateRestored = true;
355  }
356 
357  m_renderWorld->update();
358 }
359 
361 {
362  // First of all calling parent function
364 
365  // Now sharing with RenderWorld
366  m_renderWorld->shareResourcesWith(buddy);
367 }
368 
369 void RenderWorldWrapperWidget::resourceChanged(QString resourceName, ResourceChangeType changeType)
370 {
371  if (resourceName == "robot") {
372  if ((changeType != Deleted) && (!m_renderWorldStateRestored)) {
373  try {
374  m_robotTm = getResource<WObject>()->matrix();
375  } catch (const ResourceTypeMismatchException&) {
376  }
377 
378  m_setCameraToLookAtRobot = true;
379  }
380  } else {
381  Logger::info("Unknown resource " + resourceName + " for RenderWorldWrapperWidget widget");
382  }
383 
384  // Forcing renderworld update
385  QCoreApplication::postEvent(this, new ForceRenderWorldUpdateEvent());
386 }
387 
388 void RenderWorldWrapperWidget::customEvent(QEvent* event)
389 {
390  if (event->type() == QEvent::User) {
391  // Forcing RenderWorld update
393  }
394 }
395 
396 void RenderWorldWrapperWidget::lookAtRobot()
397 {
398  wVector cameraDefaultPosition = m_robotTm.transformVector(wVector(-0.8f, 0.0f, +0.6f));
399  m_renderWorld->camera()->setPosition(Vec(cameraDefaultPosition[0], cameraDefaultPosition[1], cameraDefaultPosition[2]));
400  m_renderWorld->camera()->setUpVector(Vec(0.0f, 0.0f, 1.0f));
401  m_renderWorld->camera()->lookAt(Vec(m_robotTm.w_pos[0], m_robotTm.w_pos[1], m_robotTm.w_pos[2]));
402 }
403 
404 // #include <QPainter>
405 // #include <QPen>
406 // #include <QBrush>
407 // #include <QTransform>
408 // #include <QVBoxLayout>
409 //
410 // namespace VisionMapSensorGuiInternal {
411 // /**
412 // * \brief An helper class to display an image
413 // *
414 // * This takes a pointer to the image to show and also resizes itself to
415 // * match the image dimension
416 // */
417 // class ImageDisplayer : public QWidget
418 // {
419 // public:
420 // ImageDisplayer(QWidget* parent = NULL) :
421 // QWidget(parent),
422 // m_image(NULL)
423 // {
424 // }
425 //
426 // ~ImageDisplayer()
427 // {
428 // }
429 //
430 // void setImage(QImage* image)
431 // {
432 // // Saving image
433 // m_image = image;
434 //
435 // // Also resetting widget dimensions
436 // setMinimumSize(m_image->width(), m_image->height());
437 // setMaximumSize(m_image->width(), m_image->height());
438 //
439 // // Updating the widget
440 // update();
441 // }
442 //
443 // private:
444 // void paintEvent(QPaintEvent *)
445 // {
446 // if (m_image == NULL) {
447 // return;
448 // }
449 //
450 // QPainter painter(this);
451 //
452 // // Drawing image. Also flipping image (perhaps yarp doesn't consider top left to be 0, 0)
453 // painter.drawImage(0, 0, m_image->mirrored(false, true));
454 // }
455 //
456 // QImage* m_image;
457 // };
458 // }
459 //
460 // VisionMapSensorGui::VisionMapSensorGui(QWidget* parent, Qt::WindowFlags flags) :
461 // QWidget(parent,flags),
462 // m_image(),
463 // m_imageDisplayer(new VisionMapSensorGuiInternal::ImageDisplayer(this))
464 // {
465 // // Creating a layout and adding the image displayer widget and the table with map activations
466 // QVBoxLayout* layout = new QVBoxLayout(this);
467 // layout->addWidget(m_imageDisplayer);
468 //
469 //
470 // }
471 //
472 // VisionMapSensorGui::~VisionMapSensorGui()
473 // {
474 // // Nothing to do here
475 // }
476 //
477 // void VisionMapSensorGui::setImage(PhyiCub *icub, bool useRightCamera)
478 // {
479 //
480 // // Taking the image in yarp format
481 // yarp::sig::ImageOf<yarp::sig::PixelRgb> yarpImage;
482 // // yarp::dev::IFrameGrabberImage* frameGrabber = useRightCamera ? icub->rightEyeFrameGrabber() : icub->leftEyeFrameGrabber();
483 // yarp::dev::IFrameGrabberImage* frameGrabber = NULL; // The line above crashes with multithread
484 // if (frameGrabber == NULL) {
485 // return;
486 // }
487 // // frameGrabber->getImage(yarpImage); // Crashes with multithread
488 //
489 // // Converting to QImage
490 // m_image = QImage(yarpImage.width(), yarpImage.height(), QImage::Format_RGB32);
491 // for (int i = 0; i < yarpImage.width(); i++) {
492 // for (int j = 0; j < yarpImage.height(); j++) {
493 // // Converting pixel and writing it into the QImage
494 // yarp::sig::PixelRgb& yarpPixel = yarpImage.pixel(i, j);
495 // m_image.setPixel(i, j, qRgb(yarpPixel.r, yarpPixel.g, yarpPixel.b));
496 // }
497 // }
498 //
499 //
500 // // Drawing an X at the image center
501 // QPainter painter(&m_image);
502 // const int cX = m_image.width() / 2;
503 // const int cY = m_image.height() / 2;
504 //
505 // // Drawing the X
506 // painter.setPen(QPen(Qt::white, 3));
507 // painter.drawLine(cX - 5, cY - 5, cX + 5, cY + 5);
508 // painter.drawLine(cX + 5, cY - 5, cX - 5, cY + 5);
509 // painter.setPen(QPen(Qt::black, 1));
510 // painter.drawLine(cX - 5, cY - 5, cX + 5, cY + 5);
511 // painter.drawLine(cX + 5, cY - 5, cX - 5, cY + 5);
512 //
513 // // Setting the image for the image displayer
514 // m_imageDisplayer->setImage(&m_image);
515 // m_imageDisplayer->update();
516 // }
517 //
518 // void VisionMapSensorGui::addMark(double x, double y, QColor markCenter, QColor markSurrounding)
519 // {
520 // // Drawing a mark directly on the image
521 // QPainter painter(&m_image);
522 //
523 // // Computing the mark position in image coordinates
524 // const int imageX = int(x * double(m_image.width()));
525 // const int imageY = int(y * double(m_image.height()));
526 //
527 // // Drawing the mark
528 // painter.setPen(QPen(markSurrounding, 5));
529 // painter.drawPoint(imageX, imageY);
530 // painter.setPen(QPen(markCenter, 3));
531 // painter.drawPoint(imageX, imageY);
532 //
533 // // Updating the image displayer widget
534 // m_imageDisplayer->update();
535 // }
536 
537 TestIndividualGUI::TestIndividualGUI(TestIndividual* tb, QWidget *parent, Qt::WindowFlags flags) :
538  QWidget(parent, flags)
539 {
540  test = tb;
541 
542  //set layout
543  QGridLayout* mainLay = new QGridLayout( this );
544 
545  // buttons
546  QPushButton* bt = new QPushButton( "Refresh", this );
547  connect( bt, SIGNAL(clicked()), this, SLOT(populateCombo()) );
548  mainLay->addWidget(bt, 0, 0, 1, 2);
549  //creating comboBox and list
550  combo = new QComboBox();
551  list = new QListWidget();
552  mainLay->addWidget(new QLabel("Select File to load:"), 1, 0);
553  mainLay->addWidget(combo, 1, 1);
554  mainLay->addWidget(list, 2, 0, 1, 2);
555 
556  //checking available best and gen files
557  populateCombo();
558 
559  // Connecting signals and slots
560  connect(combo, SIGNAL(activated(QString)), this, SLOT(seedWasChosen()));
561  connect(list, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(agentClicked()));
562 }
563 
564 void TestIndividualGUI::populateCombo()
565 {
566  combo->clear();
567  list->clear();
568  //ask abstractGA the template name for the files (i.e. "*P*S*G*.gen")
569  QString bestF = test->component()->getGA()->bestsFilename();
570  QString genF = test->component()->getGA()->generationFilename();
571 
572  //search current folder for files
573  QDir* dir = new QDir();
574  QStringList expression = (QStringList() << bestF << genF);
575  fileList = dir->entryList(expression);
576 
577  //insert their name into the combo boxes
578  combo->addItems(fileList);
579 }
580 
581 void TestIndividualGUI::seedWasChosen()
582 {
583  //load the chosen file
584  test->setPopulationToTest( combo->currentText(), false );
585  //refresh individuals list on the GUI
586  list->clear();
587  int loadindi = test->component()->getGA()->numLoadedGenotypes();
588  for(int i=1; i<=loadindi; i++)
589  {
590  list->addItem(QString::number(i));
591  }
592 }
593 
594 void TestIndividualGUI::agentClicked()
595 {
596  //take index of the chosen individual
597  test->setIndividualToTest( list->currentRow() );
598 }
599 
600 } //end namespace farsa
601 
602 // All the suff below is to restore the warning state on Windows
603 #if defined(_MSC_VER)
604  #pragma warning(pop)
605 #endif