::iterator f = xml_files.find( currentFile_nopath );
if (f == xml_files.end()) {
return;
}
++f;
if (f==xml_files.end()) {
QMessageBox mb( "Read next leaf",
"No more files",
QMessageBox::Information,
QMessageBox::Ok | QMessageBox::Default,
QMessageBox::NoButton,
QMessageBox::NoButton);
mb.exec();
return;
}
next_file = *f;
next_file = currentFile_path+"/"+next_file;
readStateXML((const char*)next_file);
}
}
void Main::readLastStateXML()
{
// if we have already read a file, read the next file
if (!currentFile.isEmpty() && working_dir) {
QString next_file;
QStringList xml_files = working_dir->entryList("*.xml");
QString currentFile_nopath = currentFile.section( '/', -1 );
QString currentFile_path = currentFile.section( '/', 0, -2 );
next_file = xml_files.back();
next_file = currentFile_path+"/"+next_file;
readStateXML((const char*)next_file);
}
}
void Main::readFirstStateXML()
{
// if we have already read a file, read the next file
if (!currentFile.isEmpty() && working_dir) {
QString next_file;
QStringList xml_files = working_dir->entryList("*.xml");
QString currentFile_nopath = currentFile.section( '/', -1 );
QString currentFile_path = currentFile.section( '/', 0, -2 );
next_file = xml_files.front();
next_file = currentFile_path+"/"+next_file;
readStateXML((const char*)next_file);
}
}
QDir Main::GetLeafDir(void) {
QDir LeafDir(QApplication::applicationDirPath());
QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
#if defined(Q_OS_WIN)
if (LeafDir.dirName().toLower() =="debug"
||LeafDir.dirName().toLower() =="release")
LeafDir.cdUp();
//plugin_filters << "*.dll";
#elif defined(Q_OS_MAC)
if (LeafDir.dirName() =="MacOS"){
LeafDir.cdUp();
LeafDir.cdUp();
LeafDir.cdUp();
}
#endif
// for all OS-es. Move from "bin" directory to root application folder.
if (LeafDir.dirName() == "bin") {
LeafDir.cdUp();
}
LeafDir.cd("data/leaves");
/* if (!LeafDir.cd("data/leaves")) {
QString status_message = QString("No directory data/leaves");
statusBar()->showMessage(status_message);
return LeafDir;
}
*/
return LeafDir;
}
void Main::readStateXML()
{
// extern Mesh mesh;
stopSimulation();
#ifdef QDEBUG
qDebug() << "Trying to open an OptionFileDialog" << endl;
#endif
OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE );
fd->setMode( OptionFileDialog::ExistingFile );
fd->setFilter( "LeafML files (*.xml)");
if (working_dir) {
fd->setDir(*working_dir);
} else {
fd->setDir(par.datadir);
}
QString fileName;
if ( fd->exec() == QDialog::Accepted ) {
fileName = fd->selectedFile();
if (working_dir) {
delete working_dir;
}
working_dir = fd->dir();
if (readStateXML((const char *)fileName,fd->readGeometryP(), fd->readParametersP()) )
return readStateXML(); // user can try again
}
}
void Main::clear()
{
editor->clear();
}
void Main::about()
{
static QMessageBox* about = new QMessageBox
( "VirtualLeaf V1.0",
"VirtualLeaf V1.0
\
\
An Open Source framework for cell-based modeling of plant\
tissue growth and development.\
\
(c) 2005-2008, Roeland Merks et al.\
VIB Department Plant Systems Biology,\
Ghent, Belgium.\
\
(c) 2008-2010,\
Roeland Merks et al.\
Centrum Wiskunde & Informatica (CWI) and\
Netherlands Consortium for Systems Biology (NCSB),\
Amsterdam, the Netherlands.\
\
\
VirtualLeaf is free software: you can redistribute it and/or\
modify it under the terms of the GNU General Public License as\
published by the Free Software Foundation, either version 3 of the\
License, or (at your option) any later version.\
\
\
If you use this code for your projects, please cite our paper in\
Plant Physiology, ‘\
Roeland M. H. Merks, Michael Guravage, Dirk Inze, and Gerrit T.S. Beemster,\
\
VirtualLeaf: an Open Source framework for cell-based modeling of plant tissue growth and development,
\
Plant Physiology 2011: pp.110.167619v1-pp.110.167619.\
\
\
Please share your model plugins and extensions at\
http://virtualleaf.googlecode.com.\
",
QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
about->setButtonText( 1, "Dismiss" );
about->setIconPixmap(QPixmap( leaficon_small ));
about->show();
}
void Main::gpl()
{
static QMessageBox* gpl = new QMessageBox ( "GPL License", "",
QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
QDir docDir(QApplication::applicationDirPath());
docDir.cd("../doc"); // Where Linux expects gpl3.txt
QString path = docDir.filePath("gpl3.txt");
if (!docDir.exists("gpl3.txt")){
docDir = QApplication::applicationDirPath();
docDir.cd("doc"); // Where Windows expects gpl3.txt
path = docDir.filePath("gpl3.txt");
}
// At this point path points either to the linux variant, which
// exists, or the windows variant, which may exist. Testing the
// ifstream object will determine whether we've found gpl3.txt.
std::ifstream file(path.toStdString().c_str());
std::string str;
if (file) {
file.seekg(0, std::ios::end);
str.reserve(file.tellg());
file.seekg(0, std::ios::beg);
str.assign((std::istreambuf_iterator(file)),
std::istreambuf_iterator());
gpl->setDetailedText(QString(str.c_str()));
}
gpl->setText(QString( "GNU GENERAL PUBLIC LICENSE
"
"Version 3, 29 June 2007
"
"Copyright © 2007 Free Software Foundation, Inc. "
"<http://fsf.org/>
"
"Everyone is permitted to copy and distribute verbatim copies "
"of this license document, but changing it is not allowed.
"
"GNU GENERAL PUBLIC LICENSE
"));
gpl->setButtonText( 1, "Dismiss" );
gpl->show();
}
void Main::aboutQt(){
QMessageBox::aboutQt( this, "Virtual Leaf" );
}
void Main::toggleShowCellCenters()
{
Plot();
}
void Main::toggleShowWalls()
{
Plot();
}
void Main::toggleShowApoplasts()
{
Plot();
}
void Main::toggleShowNodes()
{
Plot();
}
void Main::toggleNodeNumbers(void)
{
Plot();
}
void Main::toggleCellNumbers(void)
{
Plot();
}
void Main::toggleCellAxes(void)
{
Plot();
}
void Main::toggleCellStrain(void)
{
Plot();
}
void Main::toggleShowFluxes(void)
{
Plot();
}
void Main::toggleShowBorderCells()
{
Plot();
}
void Main::toggleHideCells(void)
{
Plot();
editor->FullRedraw();
}
void Main::toggleMovieFrames(){}
void Main::toggleLeafBoundary(){}
void Main::toggleDynCells() {}
void Main::startSimulation(void)
{
timer->start( 0 );
statusBar()->message("Simulation started");
running = true;
}
void Main::stopSimulation(void)
{
timer->stop();
cerr << "Stopping simulation" << endl;
statusBar()->message("Simulation paused");
running = false;
}
void Main::togglePaused()
{
bool s = run->isItemChecked(paused_id);
if (s) {
cerr << "Calling start simulation" << endl;
startSimulation();
} else {
cerr << "Calling stop simulation" << endl;
stopSimulation();
}
}
void Main::setFluxArrowSize(int size)
{
flux_arrow_size = size/100.;
}
void Main::enlarge()
{
canvas.setSceneRect( QRectF( 0,0, canvas.width()*4./3., canvas.height()*4./3.) );
}
void Main::shrink()
{
canvas.setSceneRect( QRectF( 0,0, canvas.width()*3/4, canvas.height()*3/4) );
}
void Main::scale(double factor)
{
QMatrix m = editor->matrix();
m.scale(factor, factor);
editor->setMatrix( m );
}
void Main::zoomIn()
{
QMatrix m = editor->matrix();
m.scale( 1.1, 1.1 );
editor->setMatrix( m );
}
void Main::zoomOut()
{
QMatrix m = editor->matrix();
m.scale( 0.9, 0.9 );
editor->setMatrix( m );
}
void Main::print()
{
if ( !printer ) printer = new QPrinter;
if ( printer->setup(this) ) {
// extern Mesh mesh;
Vector bbll,bbur;
mesh.BoundingBox(bbll,bbur);
#ifdef QDEBUG
qDebug() << "bbll = " << bbll << endl;
qDebug() << "bbur = " << bbur << endl;
#endif
double cw = (bbur.x - bbll.x);
double ch = (bbur.y - bbll.y);
QPainter pp(printer);
QRect vp=pp.viewport();
#ifdef QDEBUG
qDebug() << "Paper width = " << vp.width() << " x " << vp.height() << endl;
#endif
// Note that Cell is also translated...
/* pp.translate(-bbur.x,-bbur.y);
if (cw>ch) {
pp.scale(vp.width()/(2*cw*Cell::Magnification()), vp.width()/(2*cw*Cell::Magnification()));
} else {
pp.scale(vp.height()/(2*ch*Cell::Magnification()), vp.height()/(2*ch*Cell::Magnification()));
}*/
canvas.render(&pp);//, QRectF(), QRectF(0.,0.,canvas.width(),canvas.height()));
}
}
void Main::TimeStepWrap(void)
{
static int t;
stringstream fname;
TimeStep();
t = (int)mesh.getTime();
if ((par.export_interval > 0) && !(t%par.export_interval)){
fname << par.datadir << "/" << par.export_fn_prefix;
fname.fill('0');
fname.width(6);
fname << t << ".csv";
this->exportCellData(QString(fname.str().c_str()));
}
// check number of timesteps
if (t == par.nit) {
emit SimulationDone();
}
}
void Main::RestartSim(void)
{
stopSimulation();
if ( QMessageBox::question(
this,
tr("Restart simulation?"),
tr("Restart simulation.\n"
"Are you sure?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton ) == QMessageBox::Yes ) {
cerr << "Restarting simulation" << endl;
// extern Mesh mesh;
mesh.Clear();
Init();
Plot();
editor->FullRedraw();
}
//startSimulation();
}
void Main::FitCanvasToWindow(void)
{
double scale_factor_x = (double)editor->width()/(double)canvas.width();
double scale_factor_y = (double)editor->height()/(double)canvas.height();
double scale_factor = scale_factor_x > scale_factor_y ? scale_factor_x : scale_factor_y;
QMatrix m = editor->matrix();
#ifdef QDEBUG
qDebug() << "editor->width() = " << editor->width() << endl;
qDebug() << "editor->height() = " << editor->height() << endl;
qDebug() << "scale_factor = " << scale_factor << endl;
qDebug() << "scale_factor_x = " << scale_factor_x << endl;
qDebug() << "scale_factor_y = " << scale_factor_y << endl;
#endif
m.scale( scale_factor, scale_factor );
editor->setMatrix( m );
editor->show();
}
void Main::PauseIfRunning(void)
{
if (running) {
timer->stop();
}
}
void Main::ContIfRunning(void)
{
if (running) {
timer->start( 0 );
}
}
void Main::FitLeafToCanvas(void)
{
Vector ll,ur;
mesh.BoundingBox(ll, ur);
ll*=Cell::Magnification(); ur*=Cell::Magnification();
// give the leaf some space
Vector border = ((ur-ll)/5.);
QRectF bb( ll.x - border.x, ll.y - border.y, ur.x-ll.x + 2*border.x, ur.y-ll.y + 2*border.y );
// cerr << ur << ", " << ll << endl;
// editor->fitInView(bb, Qt::KeepAspectRatio);
editor->ensureVisible(bb);
canvas.setSceneRect(bb);
//editor->setTransform(viewport);
}
void Main::CleanMesh(void)
{
vector clean_chem(Cell::NChem());
vector clean_transporters(Cell::NChem());
for (int i=0;iFullRedraw();
}
void Main::CleanMeshChemicals(void)
{
vector clean_chem(Cell::NChem());
for (int i=0;iFullRedraw();
}
void Main::CleanMeshTransporters(void)
{
vector clean_transporters(Cell::NChem());
for (int i=0;iFullRedraw();
}
void Main::RandomizeMesh(void)
{
vector max_chem(Cell::NChem());
vector max_transporters(Cell::NChem());
for (int i=0;isetItemChecked(com_id, showcentersp);
view->setItemChecked(mesh_id, showmeshp);
view->setItemChecked(border_id, showbordercellp);
view->setItemChecked(node_number_id, shownodenumbersp);
view->setItemChecked(cell_number_id, showcellnumbersp);
view->setItemChecked(cell_axes_id, showcellsaxesp);
view->setItemChecked(cell_strain_id, showcellstrainp);
view->setItemChecked(movie_frames_id, movieframesp);
view->setItemChecked(only_boundary_id, showboundaryonlyp);
view->setItemChecked(fluxes_id, showfluxesp);
view->setItemChecked(hide_cells_id, hidecellsp);
options->setItemChecked(dyn_cells_id, dynamicscellsp);
view->setItemChecked( cell_walls_id, showwallsp);
// view->setItemChecked( apoplasts_id, showapoplastsp);
editor->setTransform(viewport);
}
xmlNode *Main::XMLSettingsTree(void)
{
showcentersp = view->isItemChecked(com_id);
showmeshp = view->isItemChecked(mesh_id);
showbordercellp = view->isItemChecked(border_id);
shownodenumbersp = view->isItemChecked(node_number_id);
showcellnumbersp = view->isItemChecked(cell_number_id);
showcellsaxesp = view->isItemChecked( cell_axes_id );
showcellstrainp = view->isItemChecked( cell_strain_id );
movieframesp = view->isItemChecked(movie_frames_id);;
showboundaryonlyp = view->isItemChecked(only_boundary_id);
showfluxesp = view->isItemChecked(fluxes_id);
dynamicscellsp = options->isItemChecked(dyn_cells_id);
showwallsp = view->isItemChecked( cell_walls_id);
//showapoplastsp = view->isItemChecked( apoplasts_id);
hidecellsp = view->isItemChecked( hide_cells_id);
xmlNode *settings = MainBase::XMLSettingsTree();
QTransform viewport(editor->transform());
xmlAddChild(settings, XMLViewportTree(viewport));
return settings;
}
void Main::exportCellData(QString fileName) {
#ifdef QDEBUG
qDebug() << "exportCellData fileName: " << fileName << endl;
#endif
QFile file(fileName);
if ( file.open( IO_WriteOnly ) ) {
QTextStream stream( &file );
mesh.CSVExportCellData(stream);
mesh.CSVExportWallData(stream);
mesh.CSVExportMeshData(stream);
file.close();
}
}
void Main::exportCellData() {
QString fileName;
Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
fd->setDir(par.datadir);
stopSimulation();
fd->setMode( Q3FileDialog::AnyFile );
if ( fd->exec() == QDialog::Accepted ) {
fileName = fd->selectedFile();
// extract extension from filename
QFileInfo fi(fileName);
QString extension = fi.suffix();
if (extension.isEmpty()) {
extension = "csv";
fileName += ".";
fileName += extension;
}
if (extension!="csv" && extension!="CSV") {
if (
QMessageBox::question(
this,
tr("Change extension? -- Cell data export"),
tr("VirtualLeaf can only export data to CSV format (Excel-compatible)."
"Do you want to change the file extension to \".csv\"?"),
QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No
) {
return exportCellData();
} else {
fileName.replace(extension,"csv");
extension="csv";
}
}
if ( QFile::exists( fileName ) &&
QMessageBox::question(
this,
tr("Overwrite file? -- Cell data export"),
tr("A file called %1 already exists."
" Do you want to overwrite it?").arg( fileName ),
QMessageBox::Yes, QMessageBox::No
) == QMessageBox::No
) {
return exportCellData();
} else {
exportCellData(fileName);
QString status_message = QString("Wrote data file to %1").arg(fileName);
statusBar()->showMessage(status_message);
}
}
}
/* finis */