27 #include "QApplication" 42 for (uint i=0;i<MaxRecentFiles;i++) recentFileActions[i] = NULL;
47 curModelFileName=
"data/ffsmInput.ods";
48 curBaseDirectory = QApplication::applicationDirPath();
49 curBaseDirectory.append(
"/data/");
51 outputDirName=
"output/";
52 setCurrentLogFileName(
"");
55 debugMsgsEnable =
true;
57 for (
int i = 0; i < MaxRecentFiles; ++i) {
58 recentFileActions[i] =
new QAction(
this);
59 recentFileActions[i]->setVisible(
false);
60 connect(recentFileActions[i], SIGNAL(triggered()),
this, SLOT(openRecentFile()));
63 separatorAction = menuFile->addSeparator();
64 for (
int i = 0; i < MaxRecentFiles; ++i)
65 menuFile->addAction(recentFileActions[i]);
66 menuFile->addSeparator();
67 menuFile->addAction(actionExit);
70 modelMainThread.setInputFileName(curModelFileName);
74 statusView->setColumnCount(2);
75 statusView->setHeaderLabels(QStringList()<< tr (
"Label") << tr (
"Value"));
77 statusView->sortByColumn(0);
78 statusView->setFocus();
110 qRegisterMetaType<string>(
"string");
111 qRegisterMetaType<QString>(
"QString");
112 qRegisterMetaType< QVector<QString> >(
"QVector<QString>");
115 connect(actionRun, SIGNAL(triggered()),
this, SLOT(startModelMainThread()));
116 connect(actionPause, SIGNAL(triggered()),
this, SLOT(pauseOrResumeModelMainThread()));
117 connect(actionStop, SIGNAL(triggered()),
this, SLOT(stopModelMainThread()));
118 connect(actionExit, SIGNAL(triggered()),
this, SLOT(close()));
119 connect(actionSaveLog, SIGNAL(triggered()),
this, SLOT(save()));
120 connect(actionSaveLogAs, SIGNAL(triggered()),
this, SLOT(saveAs()));
121 connect(actionLoadConfiguration, SIGNAL(triggered()),
this, SLOT(open()));
122 connect(actionHideDebugMsgs, SIGNAL(triggered(
bool)),
this, SLOT(hideDebugMsgs(
bool)));
123 connect(actionAboutRegMAS, SIGNAL(triggered()),
this, SLOT(about()));
124 connect(actionRegMASDocumentation, SIGNAL(triggered()),
this, SLOT(showDocumentation()));
125 connect(actionFitMap, SIGNAL(triggered()), mapBox, SLOT(fitInWindow()));
126 connect(
this, SIGNAL(resized()),mapBox, SLOT(fitInWindow()));
127 connect(viewResultsButton, SIGNAL(clicked()),
this, SLOT(openResults()));
129 connect(&modelMainThread, SIGNAL(upgradeLogArea(
const QString&)),
this, SLOT(processLogArea(
const QString&)));
130 connect(&modelMainThread, SIGNAL(addLayerToGui(QString, QString)),
this, SLOT( addLayer(QString, QString)));
131 connect(layerSelector, SIGNAL(activated(
int)),
this, SLOT(switchToLayerFromLayerSelector(
int)));
132 connect(&modelMainThread, SIGNAL(updatePixelToGui(QString,
int,
int, QColor)),
this, SLOT (updatePixel(QString,
int,
int, QColor)));
133 connect(&modelMainThread, SIGNAL(updateImageToGui(QString, QImage)),
this, SLOT (updateImage(QString, QImage)));
134 connect(&modelMainThread, SIGNAL(setOutputDirNameToGui(
string)),
this, SLOT(setOutputDirName(
string)));
135 connect(&modelMainThread, SIGNAL(setGUIUnsavedStatus(
bool)),
this, SLOT(setUnsavedStatus(
bool)));
136 connect(&modelMainThread, SIGNAL(sendScenarioOptionsToGUI(
const QVector<QString> &)),
this, SLOT( receiveScenarioOptions(
const QVector<QString> &) ));
140 connect(scenarioWidget->scenarioSelector, SIGNAL( activated(
const QString&)), scenarioWidget, SLOT( close()));
141 connect(scenarioWidget->scenarioSelector, SIGNAL( activated(
const QString&)), &modelMainThread, SLOT( retrieveScenarioNameFromGUI(
const QString &)));
146 connect(&modelMainThread, SIGNAL( treeViewerItemChangeValueToGui(
string,
string) ),
this, SLOT( treeViewerItemChangeValue(
string,
string) ));
147 connect(&modelMainThread, SIGNAL( treeViewerItemRemoveToGui(
string) ),
this, SLOT( treeViewerItemRemove(
string) ));
148 connect(&modelMainThread, SIGNAL( treeViewerAddItemToGui(
string,
string,
string) ),
this, SLOT( treeViewerAddItem(
string,
string,
string) ));
149 connect(&modelMainThread, SIGNAL( fitInWindowToGui()), mapBox, SLOT(fitInWindow()));
151 connect(mapBox, SIGNAL( queryRequestOnPx(
int,
int,
bool) ), &modelMainThread, SLOT ( checkQuery(
int,
int,
bool) ) );
152 connect(&modelMainThread,SIGNAL(publishQueryResults(
const QString&)), pxInfoArea, SLOT (setHtml(
const QString&)));
153 connect(&modelMainThread,SIGNAL(activateTab(
int)), tabWidget, SLOT (setCurrentIndex(
int)));
155 connect(&modelMainThread, SIGNAL( resetGUIForNewSimulation() ),
this, SLOT( resetGUIForNewSimulation() ));
161 yearSBLabel =
new QLabel(
" 2000 ");
162 yearSBLabel->setAlignment(Qt::AlignHCenter);
163 yearSBLabel->setMinimumSize(yearSBLabel->sizeHint());
165 mainSBLabel =
new QLabel;
166 mainSBLabel->setIndent(3);
168 statusBar()->addWidget(yearSBLabel);
169 statusBar()->addWidget(mainSBLabel, 1);
171 yearSBLabel->setText(
"0");
172 mainSBLabel->setText(
"Welcome to FFSM!");
174 connect(&modelMainThread, SIGNAL(upgradeYearSBLabelToGui(
const QString&)), yearSBLabel, SLOT(setText(
const QString&)));
175 connect(&modelMainThread, SIGNAL(upgradeMainSBLabelToGui(
const QString&)), mainSBLabel, SLOT(setText(
const QString&)));
182 if (okToContinue()) {
184 modelMainThread.stop();
185 modelMainThread.wait();
202 curLogFileName = fileName;
207 curModelFileName = fileName;
209 modelMainThread.setInputFileName(curModelFileName);
211 QString shownName =
"Untitled";
212 if (!curModelFileName.isEmpty()) {
213 shownName = strippedName(curModelFileName);
214 recentFiles.removeAll(curModelFileName);
215 recentFiles.prepend(curModelFileName);
216 updateRecentFileActions();
218 setWindowTitle(tr(
"%2 - [%1]").arg(shownName).arg(tr(
"FFSM - Forest Sector Simulator")));
223 return QFileInfo(fullFileName).fileName();
228 QMutableStringListIterator i(recentFiles);
229 while (i.hasNext()) {
230 if (!QFile::exists(i.next()))
234 for (
int j = 0; j < MaxRecentFiles; ++j) {
235 if (j < recentFiles.count()) {
236 QString
text = tr(
"&%1 %2")
238 .arg(strippedName(recentFiles.at(j)));
240 recentFileActions[j]->setText(text);
241 recentFileActions[j]->setData(recentFiles.at(j));
242 recentFileActions[j]->setVisible(
true);
244 recentFileActions[j]->setVisible(
false);
247 separatorAction->setVisible(!recentFiles.isEmpty());
252 if (modelMainThread.isRunning()) {
253 int t = QMessageBox::warning(
256 tr(
"The model is still running.\n" 257 "Do you want to stop it?"),
258 QMessageBox::Yes | QMessageBox::Default,
259 QMessageBox::Cancel | QMessageBox::Escape
261 if (t == QMessageBox::Yes) {
262 modelMainThread.stop();
263 modelMainThread.wait();
264 }
else if (t == QMessageBox::Cancel) {
270 int r = QMessageBox::warning(
273 tr(
"The model log has not been saved.\n" 274 "Do you want to save it?"),
276 QMessageBox::No | QMessageBox::Default,
277 QMessageBox::Cancel | QMessageBox::Escape
279 if (r == QMessageBox::Yes) {
281 }
else if (r == QMessageBox::Cancel) {
290 if (okToContinue()) {
291 QString fileName = QFileDialog::getOpenFileName(
293 tr(
"Load model file.."),
295 tr(
"OpenDocument Spreadsheet (*.ods)\n" "All files (*.*)")
297 if (!fileName.isEmpty()){
298 statusBar()->showMessage(tr(
"Loaded new FFSM model file"), 2000);
299 setCurrentModelFileName(fileName);
301 QFileInfo info(fileName);
303 path = info.absolutePath();
305 curBaseDirectory = path;
313 QSettings settings(
"LEF",
"FFSM");
314 recentFiles = settings.value(
"recentFiles").toStringList();
315 updateRecentFileActions();
320 if (okToContinue()) {
321 QAction *action = qobject_cast<QAction *>(sender());
323 curModelFileName=action->data().toString();
324 setCurrentModelFileName(curModelFileName);
326 QFileInfo info(curModelFileName);
328 path = info.absolutePath();
330 curBaseDirectory = path;
338 if (curLogFileName.isEmpty()) {
341 cerr <<(curLogFileName.toStdString())<<endl;
342 cerr <<(outputDirName.toStdString())<<endl;
343 return saveLogFile(curLogFileName);
345 unsavedStatus =
false;
351 QString logFileName = QFileDialog::getSaveFileName(
353 tr(
"Save output log"),
355 tr(
"Log files (*.log)\n" "All files (*.*)")
357 if (logFileName.isEmpty())
359 return saveLogFile(logFileName);
360 unsavedStatus =
false;
366 QFile file(logFileName);
367 if (!file.open(QIODevice::WriteOnly)) {
368 QMessageBox::warning(
this, tr(
"FFSM"),
369 tr(
"Cannot write log file file %1:\n%2.")
370 .arg(file.fileName())
371 .arg(file.errorString()));
375 QString logAreaContent = logArea->toPlainText();
376 QTextStream stream( &file );
377 stream << logAreaContent;
380 setCurrentLogFileName(logFileName);
381 statusBar()->showMessage(tr(
"Log file saved"), 2000);
382 unsavedStatus =
false;
387 QSettings settings(
"LEF",
"FFSM");
388 settings.setValue(
"recentFiles", recentFiles);
395 if (modelMainThread.isRunning()) {
397 cout <<
"It seems that the model is already running..."<<endl;
400 modelMainThread.start();
407 if (! modelMainThread.isRunning()) {
410 modelMainThread.stop();
411 modelMainThread.wait();
417 modelMainThread.pauseOrResume();
441 static int counter =0;
442 mapBox->addLayer(layerName_h);
443 layerSelector->addItem(layerLabel_h,layerName_h);
458 mapBox->switchToLayer(layerName_h);
459 int index = mapBox->getLayerIndex(layerName_h);
460 layerSelector->setCurrentIndex(index);
466 QString layerName= layerSelector->itemData(layerIndex_h, Qt::UserRole ).toString();
467 mapBox->switchToLayer(layerName);
473 mapBox->updatePixel(layerName_h,x_h,y_h,color_h.rgb());
479 mapBox->updateImage(layerName_h, image_h);
487 map<string, QTreeWidgetItem*>::iterator p;
488 p=svIndex.find(itemID);
489 if(p != svIndex.end())
490 p->second->setText(1,newValue.c_str());
493 QString tempString2 = itemID.c_str();
494 tempString =
"**** ERROR, Coud not change value for item "+tempString2+
" in the Model Status Viewer. Item doesn't found.";
495 logArea->append(tempString);
503 map<string, QTreeWidgetItem*>::iterator p;
504 p=svIndex.find(itemID);
505 if(p != svIndex.end()){
506 QTreeWidgetItem *parent = p->second->parent();
509 index = parent->indexOfChild(p->second);
510 delete parent->takeChild(index);
513 QString tempString =
"**** ERROR, I will not delete a top level item in the Model Satus Viewer";
514 logArea->append(tempString);
520 QString tempString2 = itemID.c_str();
521 tempString =
"**** ERROR, Coud not delete for item "+tempString2+
" in the Model Status Viewer. Item doesn't found.";
530 map<string, QTreeWidgetItem*>::iterator p;
531 QTreeWidgetItem *parentItem;
533 p=svIndex.find(parentID);
534 if(p != svIndex.end()){
535 parentItem = p->second;
536 QTreeWidgetItem *node =
new QTreeWidgetItem(parentItem);
537 svIndex.insert(pair<string, QTreeWidgetItem*>(itemID, node));
538 node->setText(0, text.c_str());
542 QString tempString2 = itemID.c_str();
543 QString tempString3 = parentID.c_str();
544 tempString =
"**** ERROR, Coud not add sub item "+tempString2+
" to the Model Status Viewer. Parent item ("+tempString3+
") doesn't found.";
545 logArea->append(tempString);
554 logArea->append(message_h);
557 if( ! message_h.startsWith(
"*DEBUG")){
558 logArea->append(message_h);
565 if(hide) debugMsgsEnable =
false;
566 else debugMsgsEnable =
true;
571 QMessageBox::about(
this, tr(
"About FFSM"),
573 "<p>Copyright © 2012 Laboratoire d'Economie Forestière - LEF" 575 "<p>FFSM is a flexible, spatially explicit, coupled resource and economic simulator of the Forest Sector, " 576 "designed for long-term simulations of effects of government policies " 577 "over different forest systems." 578 "<br>It is released under the GNU GPL licence." 579 "<p>For documentation and credits please refer to the project site:" 580 "<br><a href=\"http://www.ffsm-project.org\">http://www.ffsm-project.org</a>" 586 QMessageBox::question(
this, tr(
"FFSM Documentation"),
587 tr(
"<h2>FFSM Documentation</h2>" 588 "<p align=\"justify\">FFSM documentation is organised in three main categories: " 589 "<p align=\"left\">(1) <b>official documentation</b> " 590 "(comprising the <i>User Manual</i> and the <i>Reference Manual</i>); <br>(2) <b>contributed " 591 "documentation</b> (<i>wiki</i>);<br>(3) <b>community project</b> (<i>forum</i> and <i>mailing list</i>). " 592 "<p align=\"justify\">The documentation is located at " 593 "<a href=\"http://www.ffsm-project.org/doc\">http://www.ffsm-project.org/doc</a>" 594 "<p align=\"justify\">If you have chosen to instal a local copy of the documentation, " 595 "you can access it also from the <i>Start menu</i>-><i>Programs</i>-><i>FFSM</i> " 596 "(MS Windows) or directly from the following links (Linux):" 597 "<br><a href=\"doc/userManual/regmasUserManual.pdf\">User Manual</a> " 598 " - <a href=\"doc/referenceManual/html/index.html\">Reference Manual</a> " 600 "<br> - right click on a pixel to get its value across the layers;" 601 "<br> - use the mouse and its wheel over the map to zoom/scroll it;" 609 static int simulationCounter = 0;
612 map<string, QTreeWidgetItem*>::iterator p;
618 QTreeWidgetItem* svGeneralNode =
new QTreeWidgetItem(statusView);
619 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general", svGeneralNode));
620 svGeneralNode -> setText(0,
"General");
621 QTreeWidgetItem* svYearItem =
new QTreeWidgetItem(svGeneralNode);
622 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_year", svYearItem));
623 svYearItem->setText(0,
"year");
624 svYearItem->setText(1,
"0");
625 QTreeWidgetItem* svTotalPlotsItem =
new QTreeWidgetItem(svGeneralNode);
626 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_total plots", svTotalPlotsItem));
627 svTotalPlotsItem->setText(0,
"total plots");
628 svTotalPlotsItem->setText(1,
"0");
629 QTreeWidgetItem* svTotalLandItem =
new QTreeWidgetItem(svGeneralNode);
630 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_total land", svTotalLandItem));
631 svTotalLandItem->setText(0,
"total land");
632 QTreeWidgetItem* svTotalAgrLandItem =
new QTreeWidgetItem(svGeneralNode);
633 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_total agr land", svTotalAgrLandItem));
634 svTotalAgrLandItem->setText(0,
"total agr land");
635 QTreeWidgetItem* svOwnedAgrLandItem =
new QTreeWidgetItem(svGeneralNode);
636 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_owned agr land", svOwnedAgrLandItem));
637 svOwnedAgrLandItem->setText(0,
"owned agr land");
638 QTreeWidgetItem* svRentedAgrLandItem =
new QTreeWidgetItem(svGeneralNode);
639 svIndex.insert(pair<string, QTreeWidgetItem*>(
"general_rented agr land", svRentedAgrLandItem));
640 svRentedAgrLandItem->setText(0,
"rented agr land");
642 QTreeWidgetItem* svManagersNode =
new QTreeWidgetItem(statusView);
643 svIndex.insert(pair<string, QTreeWidgetItem*>(
"managers", svManagersNode));
644 svManagersNode->setText(0,
"Managers");
646 QTreeWidgetItem* svAgentsNode =
new QTreeWidgetItem(statusView);
647 svIndex.insert(pair<string, QTreeWidgetItem*>(
"agents", svAgentsNode));
648 svAgentsNode->setText(0,
"Agents");
651 layerSelector->clear();
653 pxInfoArea->setHtml(
"<i>Tip: Right click over a plot to retrieve its values across layers.</i>");
658 if (simulationCounter) logArea->append(
"***WARNING: You are running more simulations from the GUI without closing/reopening it. It should works, but there are no guarantees. The best way is to run only one simulation from the GUI, eventually closing and opening FFSM again for further simulations.");
670 scenarioWidget->receiveScenarioOptions(scenarios_h);
671 scenarioWidget->show();
672 scenarioWidget->scenarioSelector->setFocus();
686 QUrl resultsUrl(curBaseDirectory+outputDirName+
"results/results.ods", QUrl::TolerantMode);
687 QDesktopServices::openUrl(resultsUrl);
void startModelMainThread()
void hideDebugMsgs(bool hide)
void closeEvent(QCloseEvent *event)
Manage the event of closing the application.
void setCurrentLogFileName(const QString &fileName)
void stopModelMainThread()
void pauseOrResumeModelMainThread()
QString strippedName(const QString &fullFileName)
void updatePixel(QString layerName_h, int x_h, int y_h, QColor color_h)
void treeViewerItemRemove(string itemID)
void treeViewerAddItem(string text, string itemID, string parentID)
e.g. manager_farmer_manager agents or agent_12345_ownedHa
void resizeEvent(QResizeEvent *event)
Manage the event of resizing the application.
bool saveLogFile(const QString &logFileName)
void updateRecentFileActions()
void processLogArea(const QString &message_h)
void resetGUIForNewSimulation()
Reset the graphical elements for a new simulation // Send the request of getting the pixel info to th...
void updateImage(QString layerName_h, const QImage &image_h)
void treeViewerItemChangeValue(string itemID, string newValue)
Change value to an existing item in the Status Viewer.
void receiveScenarioOptions(const QVector< QString > &scenarios_h)
void setCurrentModelFileName(const QString &fileName)
void switchToLayer(QString layerName_h)
void switchToLayerFromLayerSelector(int layerIndex_h)
void addLayer(QString layerName_h, QString layerLabel_h)