00001 #include <qapplication.h>
00002 #include <qspinbox.h>
00003 #include <qlabel.h>
00004 #include <qmultilineedit.h>
00005 #include <qarray.h>
00006 #include <qprogressdialog.h>
00007 #include <qmessagebox.h>
00008 #include <qfiledialog.h>
00009 #include <qlcdnumber.h>
00010
00011 #include <pvm3.h>
00012 #include <unistd.h>
00013
00014 #include "SIGEL_MasterGUI/SIG_AllIndividualsView.h"
00015 #include "SIGEL_MasterGUI/SIG_IndividualListItem.h"
00016 #include "SIGEL_MasterGUI/SIG_IndividualView.h"
00017
00018 #include "SIGEL_Program/SIG_Program.h"
00019 #include "SIGEL_GP/SIG_GPPVMData.h"
00020
00021 #include <SIGEL_Tools/SIG_IO.h>
00022
00023 #include <cstdlib>
00024
00025 namespace SIGEL_MasterGUI
00026 {
00027
00028 SIG_AllIndividualsView::SIG_AllIndividualsView( QWidget * parent, const char * name, SIGEL_GP::SIG_GPExperiment &theExperiment )
00029 : QSplitter( parent, name ), theExperiment( theExperiment )
00030 {
00031
00032 setOrientation( QSplitter::Vertical );
00033 setOpaqueResize( true );
00034
00035
00036 individualList = new SIG_IndividualList( this, "IndividualListAndButtons" );
00037
00038
00039 individualView = new SIG_IndividualView( this, "IndividualView" );
00040
00041
00042 individualMenu = new QPopupMenu( this );
00043 individualMenu->insertItem( "&Visualize", this, SLOT( slotVisualize() ), ALT+Key_V );
00044 individualMenu->insertSeparator();
00045 individualMenu->insertItem( "&Delete", this, SLOT( slotDeleteIndividuals() ), ALT+Key_D );
00046 individualMenu->insertSeparator();
00047 individualMenu->insertItem( "Import program", this, SLOT( slotImportProgram() ), CTRL+SHIFT+Key_K );
00048 individualMenu->insertItem( "Export program", this, SLOT( slotExportProgram() ), CTRL+ALT+Key_K );
00049 individualMenu->insertItem( "Export individual", this, SLOT( slotExportIndividual() ), CTRL+ALT+Key_L );
00050
00051
00052 listviewMenu = new QPopupMenu( this );
00053 listviewMenu->insertItem( "&Add", this, SLOT( slotAddIndividuals() ), ALT+Key_A );
00054 listviewMenu->insertSeparator();
00055 listviewMenu->insertItem( "Import individual", this, SLOT( slotImportIndividual() ), CTRL+SHIFT+Key_L );
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 QObject::connect( individualList->listviewIndividuals,
00074 SIGNAL( rightButtonClicked( QListViewItem *, const QPoint &, int ) ),
00075 this,
00076 SLOT(slotRightButtonClicked( QListViewItem *, const QPoint &, int ) ) );
00077
00078 QObject::connect( individualList->listviewIndividuals,
00079 SIGNAL( doubleClicked( QListViewItem * ) ),
00080 this,
00081 SLOT( slotDoubleClicked( QListViewItem * ) ) );
00082
00083 QObject::connect( individualList->listviewIndividuals,
00084 SIGNAL( selectionChanged() ),
00085 this,
00086 SLOT( slotSelectionChanged() ) );
00087
00088
00089
00090
00091
00092
00093
00094
00095 QValueList<int> valList;
00096 valList += 4;
00097 valList += 7;
00098 setSizes( valList );
00099 };
00100
00101 SIG_AllIndividualsView::~SIG_AllIndividualsView()
00102 {
00103
00104 };
00105
00106 int SIG_AllIndividualsView::numberOfSelectedItems()
00107 {
00108 int numberOfSelectedItems = 0;
00109
00110
00111 QListViewItemIterator it( individualList->listviewIndividuals );
00112 for ( ; it.current(); ++it )
00113 {
00114 if( it.current()->isSelected() )
00115 {
00116 numberOfSelectedItems++;
00117 }
00118 }
00119 return numberOfSelectedItems;
00120 };
00121
00122 void SIG_AllIndividualsView::slotCompleteRefreshList()
00123 {
00124 int poolSize = theExperiment.population.getSize();
00125
00126 QProgressDialog progress( "Updating pool...", QString::null, poolSize, this, "progressDialogAdd", true );
00127 progress.setCaption( "Updating..." );
00128 progress.show();
00129
00130 individualList->listviewIndividuals->clear();
00131 for( int counter = 0; counter < poolSize; counter++ )
00132 {
00133 progress.setProgress( counter );
00134 qApp->processEvents();
00135 SIGEL_GP::SIG_GPIndividual *theGPIndividual = &theExperiment.population.getIndividual( counter );
00136 SIG_IndividualListItem *theItem = new SIG_IndividualListItem( individualList->listviewIndividuals, counter, theGPIndividual );
00137 }
00138 individualList->lcdnumberNumberOfIndividuals->display(theExperiment.population.getSize() );
00139 };
00140
00141 void SIG_AllIndividualsView::slotAddIndividuals()
00142 {
00143 SIG_AddIndividualsDialog addDialog( this, "Add Individual Dialog", true );
00144 addDialog.spinboxNumber;
00145 addDialog.spinboxNumber->setFocus();
00146 switch( addDialog.exec() )
00147 {
00148 case QDialog::Accepted:
00149 emit signalDataRefreshNeeded();
00150 theExperiment.population.addRandomIndividuals( addDialog.spinboxNumber->value(), theExperiment.gpParameter, *theExperiment.robot.getLangParam() );
00151
00152
00153 individualList->listviewIndividuals->clear();
00154 QProgressDialog progress( "Populating pool...", QString::null, theExperiment.population.getSize(), this, "progressDialogAdd", true );
00155 progress.setCaption( "Add individuals..." );
00156 progress.show();
00157 for( int counter = 0; counter < theExperiment.population.getSize(); counter++ )
00158 {
00159 progress.setProgress( counter );
00160 SIGEL_GP::SIG_GPIndividual *theGPIndividual = &theExperiment.population.getIndividual( counter );
00161 SIG_IndividualListItem *theItem = new SIG_IndividualListItem( individualList->listviewIndividuals, counter, theGPIndividual );
00162 qApp->processEvents();
00163 }
00164 break;
00165 }
00166 individualList->lcdnumberNumberOfIndividuals->display( theExperiment.population.getSize() );
00167 };
00168
00169 void SIG_AllIndividualsView::slotDeleteIndividuals()
00170 {
00171
00172
00173
00174
00175
00176
00177 QArray<int> positions;
00178
00179 int numberOfSelectedItems = 0;
00180
00181
00182 QListViewItemIterator it( individualList->listviewIndividuals );
00183 for ( ; it.current(); ++it )
00184 {
00185 if( it.current()->isSelected() )
00186 {
00187 numberOfSelectedItems++;
00188 }
00189 }
00190
00191 if( numberOfSelectedItems != 0 )
00192 {
00193 QString question;
00194 if( numberOfSelectedItems == 1 )
00195 question = "selected individual?";
00196 else
00197 question = QString::number( numberOfSelectedItems ) + " selected individuals?";
00198
00199 switch( QMessageBox::warning( 0, "Continue deletion?" , "Do you really want to delete the " + question , QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape ) )
00200 {
00201 case QMessageBox::Yes:
00202
00203 positions.resize( numberOfSelectedItems );
00204
00205 int counter = 0;
00206
00207 QListViewItemIterator it2( individualList->listviewIndividuals );
00208 for ( ; it2.current(); ++it2 )
00209 {
00210 if( it2.current()->isSelected() )
00211 {
00212 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( it2.current() );
00213 positions[ counter++ ] = individualListItem->poolPosition;
00214 }
00215 }
00216
00217 positions.sort();
00218
00219 for( int counter = 0; counter < positions.size(); counter++ )
00220 {
00221 theExperiment.population.deleteIndividual( positions[ counter ] - counter );
00222 }
00223
00224 slotCompleteRefreshList();
00225 if( individualList->listviewIndividuals->childCount() == 0 )
00226 individualView->clear();
00227 break;
00228 }
00229 }
00230
00231 };
00232
00233 void SIG_AllIndividualsView::slotResetPool()
00234 {
00235 theExperiment.population.resetPool();
00236 slotCompleteRefreshList();
00237 };
00238
00239 void SIG_AllIndividualsView::slotStatsClicked()
00240 {
00241 SIGEL_Tools::SIG_IO::cerr << "Pool Size:" << theExperiment.population.getSize() << endl;
00242 };
00243
00244 void SIG_AllIndividualsView::slotRightButtonClicked( QListViewItem *theItem, const QPoint &thePoint, int inside )
00245 {
00246 if( inside == -1)
00247 {
00248 listviewMenu->popup( thePoint );
00249 }
00250 else
00251 {
00252 individualMenu->popup( thePoint );
00253 }
00254 };
00255
00256 void SIG_AllIndividualsView::slotDoubleClicked( QListViewItem *theItem )
00257 {
00258 if( theItem )
00259 {
00260 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( theItem );
00261 SIGEL_GP::SIG_GPIndividual *theGPIndividual = &theExperiment.population.getIndividual( individualListItem->poolPosition );
00262 SIG_IndividualView *theView = new SIG_IndividualView( 0, "IndividualViewDoubleClicked", WDestructiveClose, theGPIndividual );
00263 theView->show();
00264 }
00265 };
00266
00267 void SIG_AllIndividualsView::slotVisualize()
00268 {
00269 #ifdef SIG_DEBUG
00270 SIGEL_Tools::SIG_IO::cerr << "Starting visualization!\n";
00271 #endif
00272
00273 QListViewItemIterator it( individualList->listviewIndividuals );
00274 for ( ; it.current(); ++it )
00275 {
00276 if( it.current()->isSelected() )
00277 {
00278
00279 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( it.current() );
00280 SIGEL_GP::SIG_GPIndividual *theGPIndividual = individualListItem->theIndividual;
00281
00282 emit signalDataRefreshNeeded();
00283
00284 SIGEL_Program::SIG_Program &theProgram = theGPIndividual->getProgramVar();
00285
00286 SIGEL_Robot::SIG_Robot modifiedRobot( theExperiment.robot );
00287
00288 switch (theExperiment.simulationParameter.getSimulationLibrary())
00289 {
00290 case SIGEL_Simulation::SIG_SimulationParameters::DynaMo:
00291 try
00292 {
00293 modifiedRobot.prepareDynaMo();
00294 }
00295 catch (SIGEL_Tools::SIG_Exception &e)
00296 {
00297 QMessageBox::warning( this, "Robot Exception!", e.getMessage() );
00298 return;
00299 };
00300 break;
00301 case SIGEL_Simulation::SIG_SimulationParameters::DynaMechs:
00302 try
00303 {
00304 modifiedRobot.prepareDynaMechs();
00305 }
00306 catch (SIGEL_Tools::SIG_Exception &e)
00307 {
00308 QMessageBox::warning( this, "Robot Exception!", e.getMessage() );
00309 return;
00310 };
00311 break;
00312 };
00313
00314 QArray< char > hostNameBuffer( 100 );
00315
00316 gethostname( hostNameBuffer.data(), 100 );
00317
00318 char *sigelRootCString = std::getenv( "SIGEL_ROOT" );
00319
00320 QString sigelRootString( sigelRootCString );
00321
00322 QString executableName = sigelRootString + "/sigel_slave";
00323 QCString executableNameQCString = executableName.utf8();
00324 char const *executableNameCString = executableNameQCString;
00325
00326 int taskId = 0;
00327 int spawnInfo = pvm_spawn( const_cast< char* >(executableNameCString),
00328 0,
00329 PvmTaskHost,
00330 hostNameBuffer.data(),
00331 1,
00332 &taskId );
00333
00334 if (spawnInfo == 1)
00335 {
00336 SIGEL_GP::SIG_GPPVMData pvmData( modifiedRobot,
00337 theExperiment.environment,
00338 theExperiment.simulationParameter,
00339 "",
00340 true );
00341
00342 QString pvmDataString;
00343 QTextStream pvmDataStream( &pvmDataString, IO_ReadWrite );;
00344 pvmData.savePVMDataTransfer( pvmDataStream, theProgram );
00345 pvmData.sendQStringToPVM( pvmDataString, taskId, 23 );
00346 }
00347 else
00348 {
00349 QMessageBox::critical( this, "Error while starting slave!", "The slave could not be started.\n Either there is not executable or a PVM problem occured." );
00350 };
00351 }
00352 }
00353 };
00354
00355 void SIG_AllIndividualsView::slotSelectionChanged()
00356 {
00357
00358
00359
00360 QListViewItem *currentItem = individualList->listviewIndividuals->currentItem();
00361 if( currentItem )
00362 {
00363 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( currentItem );
00364 SIGEL_GP::SIG_GPIndividual *theGPIndividual = &theExperiment.population.getIndividual( individualListItem->poolPosition );
00365 individualView->textlabelShowName->setText( theGPIndividual->getName() );
00366 QString age = QString::number( theGPIndividual->getAge() );
00367 individualView->textlabelShowAge->setText( age );
00368 QString fitness = QString::number( theGPIndividual->getFitness() );
00369 individualView->textlabelShowFitness->setText( fitness );
00370 QString programCode;
00371 theGPIndividual->getProgramPointer()->printToString( programCode );
00372 individualView->multilineeditProgramCode->setText( programCode );
00373 QString history = theGPIndividual->getHistory().join( "\n" );
00374 individualView->multilineeditHistory->setText( history );
00375 }
00376 };
00377
00378 void SIG_AllIndividualsView::slotEvolutionNotRunning( bool isNotRunning )
00379 {
00380 if( !isNotRunning )
00381 {
00382 individualView->clear();
00383 QObject::disconnect( individualList->listviewIndividuals,
00384 0,
00385 0,
00386 0 );
00387 }
00388 else
00389 {
00390 QObject::disconnect( individualList->listviewIndividuals,
00391 0,
00392 0,
00393 0 );
00394
00395 QObject::connect( individualList->listviewIndividuals,
00396 SIGNAL( rightButtonClicked( QListViewItem *, const QPoint &, int ) ),
00397 this,
00398 SLOT(slotRightButtonClicked( QListViewItem *, const QPoint &, int ) ) );
00399
00400 QObject::connect( individualList->listviewIndividuals,
00401 SIGNAL( doubleClicked( QListViewItem * ) ),
00402 this,
00403 SLOT( slotDoubleClicked( QListViewItem * ) ) );
00404
00405 QObject::connect( individualList->listviewIndividuals,
00406 SIGNAL( selectionChanged() ),
00407 this,
00408 SLOT( slotSelectionChanged() ) );
00409 }
00410 };
00411
00412 void SIG_AllIndividualsView::slotImportProgram()
00413 {
00414 QListViewItem *currentItem = individualList->listviewIndividuals->currentItem();
00415 if( currentItem )
00416 {
00417 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( currentItem );
00418 if( numberOfSelectedItems() == 1 )
00419 {
00420 QString fileName = QFileDialog::getOpenFileName( QString::null, "Program files (*.prg);;All Files (*)", 0, 0, "Import program..." );
00421 if( !fileName.isEmpty() )
00422 {
00423 individualListItem->theIndividual->importProgram( fileName );
00424 }
00425 slotSelectionChanged();
00426 }
00427 else
00428 QMessageBox::information( 0, "Select exactly one individual...", "There must be exactly one individual selected!" );
00429 }
00430 else
00431 QMessageBox::information( 0, "No individual selected...", "There is no individual selected!" );
00432 };
00433
00434 void SIG_AllIndividualsView::slotExportProgram()
00435 {
00436 QListViewItem *currentItem = individualList->listviewIndividuals->currentItem();
00437 if( currentItem )
00438 {
00439 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( currentItem );
00440 if( numberOfSelectedItems() == 1 )
00441 {
00442 QString individualName = individualListItem->theIndividual->getName();
00443 QString fileName = QFileDialog::getSaveFileName( QString::null, "Program files (*.prg);;All Files (*)", 0, 0, "Export program..." );
00444 if( !fileName.isEmpty() )
00445 {
00446 if( fileName.right(4) != ".prg" )
00447 fileName.append( ".prg" );
00448 individualListItem->theIndividual->exportProgram( fileName );
00449 }
00450 }
00451 else
00452 QMessageBox::information( 0, "More than one individual selected...", "There is more than one individual selected!" );
00453 }
00454 else
00455 QMessageBox::information( 0, "No individual selected...", "There is no individual selected!" );
00456 };
00457
00458 void SIG_AllIndividualsView::slotImportIndividual()
00459 {
00460 QString fileName = QFileDialog::getOpenFileName( QString::null, "Individual files (*.ind);;All Files (*)", 0, 0, "Import individual..." );
00461 if( !fileName.isEmpty() )
00462 {
00463 theExperiment.population.importNewIndividual( fileName );
00464 }
00465 slotCompleteRefreshList();
00466 };
00467
00468 void SIG_AllIndividualsView::slotExportIndividual()
00469 {
00470 QListViewItem *currentItem = individualList->listviewIndividuals->currentItem();
00471 if( currentItem )
00472 {
00473 SIG_IndividualListItem *individualListItem = static_cast<SIG_IndividualListItem *> ( currentItem );
00474 if( numberOfSelectedItems() == 1 )
00475 {
00476 QString individualName = individualListItem->theIndividual->getName();
00477 QString fileName = QFileDialog::getSaveFileName( QString::null, "Individual files (*.ind);;All Files (*)", 0, 0, "Export individual..." );
00478 if( !fileName.isEmpty() )
00479 {
00480 if( fileName.right(4) != ".ind" )
00481 fileName.append( ".ind" );
00482 individualListItem->theIndividual->exportIndividual( fileName );
00483 }
00484 }
00485 else
00486 QMessageBox::information( 0, "More than one individual selected...", "There is more than one individual selected!" );
00487 }
00488 else
00489 QMessageBox::information( 0, "No individual selected...", "There is no individual selected!" );
00490 };
00491
00492 }