#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include "configdialog.h" static QMap geometryGranularitySymbolic; static QMap geometryGranularityNumeric; static QMap geometrySizeModeSymbolic; static QMap geometrySizeModeNumeric; struct InitStatics { InitStatics(void); }; static const InitStatics initStatics; InitStatics::InitStatics(void) { int n = -1; geometryGranularitySymbolic[n++] = "unspecified"; geometryGranularitySymbolic[n++] = "pixel"; geometryGranularitySymbolic[n++] = "block"; for (int i = -1; i < n; i++) geometryGranularityNumeric[geometryGranularitySymbolic[i]] = i; n = -1; geometrySizeModeSymbolic[n++] = "auto"; geometrySizeModeSymbolic[n++] = "auto"; geometrySizeModeSymbolic[n++] = "fixed"; geometrySizeModeSymbolic[n++] = "shrink"; for (int i = -1; i < n; i++) geometrySizeModeNumeric[geometrySizeModeSymbolic[i]] = i; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), configDialog(NULL) { #ifndef Q_OS_WIN if (!migrateSettingsProfiles()) exit(EXIT_FAILURE); #endif QCommandLineParser parser; parser.setApplicationDescription("This program provides a graphical user interface for minetestmapper. \n" "If you are looking for the command line interface of minetesmapper please execute minetestmapper directly."); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption startPortableOption(QStringList() << "p" << "portable", "Starts in portable mode which reads and writes settings and profiles relative to current directory"); parser.addOption(startPortableOption); parser.process(qApp->arguments()); portable = parser.isSet(startPortableOption); if(portable){ //Attention: This paths could be non writable locations! pathAppData = qApp->applicationDirPath(); //use the Applications directory pathProfiles = pathAppData + "/profiles/"; //manipulate settingsfile on portable mode settings = new QSettings(pathAppData+"/MinetestMapperGui.ini",QSettings::IniFormat); } else{ QSettings dummySettings(QSettings::IniFormat, QSettings::UserScope,qApp->organizationName(),"dummy"); pathAppData = QFileInfo(dummySettings.fileName()).path(); pathProfiles = pathAppData + "/profiles/"; dummySettings.deleteLater(); //non portable use OS defaults settings = new QSettings(); } ui->setupUi(this); finishUiInitialisation(); readSettings(); readProfile(currentProfile); progressBar = new QProgressBar(ui->statusBar); progressBar->setAlignment(Qt::AlignRight); progressBar->setMaximumSize(180, 19); ui->statusBar->addPermanentWidget(progressBar); //progressBar->setValue(0); progressBar->setMaximum(100); progressBar->setMinimum(0); progressBar->hide(); connect(ui->actionAbout_QT, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(ui->actionStart_colors_txt_assistant,SIGNAL(triggered()),this,SLOT(startColorsTxtAssistant())); createLanguageMenu(); createProfilesMenu(); QCompleter *completer = new QCompleter(this); QDirModel *model =new QDirModel(completer); model->setFilter(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Drives); completer->setModel(model); ui->path_World->setCompleter(completer); } void MainWindow::finishUiInitialisation(void) { ui->geometrymode_granularity_group->setId(ui->geometrymode_pixel, geometryGranularityNumeric["pixel"]); ui->geometrymode_granularity_group->setId(ui->geometrymode_block, geometryGranularityNumeric["block"]); ui->geometrymode_size_group->setId(ui->geometrymode_auto, geometrySizeModeNumeric["auto"]); ui->geometrymode_size_group->setId(ui->geometrymode_fixed, geometrySizeModeNumeric["fixed"]); ui->geometrymode_size_group->setId(ui->geometrymode_shrink, geometrySizeModeNumeric["shrink"]); } // we create the language menu entries dynamically, dependent on the existing translations. void MainWindow::createLanguageMenu(void) { QActionGroup* langGroup = new QActionGroup(ui->menuLanguage); langGroup->setExclusive(true); connect(langGroup, SIGNAL (triggered(QAction *)), this, SLOT (slotLanguageChanged(QAction *))); // format systems language QString defaultLocale = QLocale::system().name(); // e.g. "de_DE" defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de" m_langPath = QApplication::applicationDirPath(); m_langPath.append("/languages"); qDebug()<<"Lang path "<< m_langPath; QDir dir(m_langPath); QStringList fileNames = dir.entryList(QStringList("gui_*.qm")); for (int i = 0; i < fileNames.size(); ++i) { // get locale extracted by filename QString locale; locale = fileNames[i]; // "gui_de.qm" locale.truncate(locale.lastIndexOf('.')); // "gui_de" locale.remove(0, locale.indexOf('_') + 1); // "de" QString lang = QLocale::languageToString(QLocale(locale).language()); QIcon ico(QString("%1/%2.png").arg(m_langPath).arg(locale)); QAction *action = new QAction(ico, lang, this); action->setCheckable(true); action->setData(locale); ui->menuLanguage->addAction(action); langGroup->addAction(action); // set default translators and language checked if (defaultLocale == locale) { action->setChecked(true); loadLanguage(locale); } } } // Called every time, when a menu entry of the language menu is called void MainWindow::slotLanguageChanged(QAction* action) { if(0 != action) { // load the language dependant on the action content loadLanguage(action->data().toString()); ui->menuLanguage->setIcon(action->icon()); } } void switchTranslator(QTranslator& translator, const QString& filename) { // remove the old translator qApp->removeTranslator(&translator); QString m_langPath = QApplication::applicationDirPath(); m_langPath.append("/languages/"); qDebug()<<"Trying to load language "<< m_langPath+filename; qDebug()<installTranslator(&translator); } void MainWindow::loadLanguage(const QString& rLanguage) { if(m_currLang != rLanguage) { m_currLang = rLanguage; QLocale locale = QLocale(m_currLang); QLocale::setDefault(locale); QString languageName = QLocale::languageToString(locale.language()); switchTranslator(m_translator, QString("gui_%1.qm").arg(rLanguage)); switchTranslator(m_translatorQt, QString("qtbase_%1.qm").arg(rLanguage)); ui->statusBar->showMessage(tr("Current Language changed to %1").arg(languageName),3000); } } void MainWindow::changeEvent(QEvent* event) { if(0 != event) { switch(event->type()) { // this event is send if a translator is loaded case QEvent::LanguageChange: ui->retranslateUi(this); break; // this event is send, if the system, language changes case QEvent::LocaleChange: { QString locale = QLocale::system().name(); locale.truncate(locale.lastIndexOf('_')); loadLanguage(locale); } break; // Ignore other events default: break; } } QMainWindow::changeEvent(event); } MainWindow::~MainWindow() { if (configDialog) { delete configDialog; configDialog = NULL; } delete ui; } void MainWindow::on_button_generate_clicked() { QFile mapperBinary; if (currentSettings.mapperPath == "") mapperBinary.setFileName(ConfigSettings::getDefaultMapperExecutable()); else mapperBinary.setFileName(currentSettings.mapperPath); if (!mapperBinary.exists()) { QMessageBox::StandardButton ret; if (currentSettings.mapperPath == "") { ret = QMessageBox::critical(this, tr("Minetestmapper not found"), tr("ERROR: No minetestmapper executable could not be found.\n" "Please configure one. (Edit->Preferences)\n\n" "Do you want to open Preferences now?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); } else ret = QMessageBox::critical(this, tr("Minetestmapper not found"), tr("ERROR: Configured minetestmapper executable (%1) could not be found\n" "Please configure one. (Edit->Preferences)\n\n" "Do you want to open Preferences now?").arg(currentSettings.mapperPath), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); if(ret == QMessageBox::Yes) on_actionPreferences_triggered(); return; } else if (!(mapperBinary.permissions() & QFileDevice::ExeUser)) { QMessageBox::StandardButton ret = QMessageBox::critical(this, tr("Minetestmapper not executable"), tr("ERROR: The configured minetestmapper (%1) is not executable.\n" "Please configure a valid minetestmapper executable. (Edit->Preferences)\n\n" "Do you want to open Preferences now?") .arg(mapperBinary.fileName()), QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); if(ret == QMessageBox::Yes) on_actionPreferences_triggered(); return; } qDebug() << QString("Minetestmapper version: ") + ConfigSettings::getMapperVersion(mapperBinary.fileName(), this); QDir worldPath = QDir(ui->path_World->text()); if(!worldPath.exists()||worldPath.path()=="."||worldPath.path()=="/"){ QMessageBox::critical(this, tr("no input world selected"), tr("ERROR: No MinetestWorld selected

" "please select a world")); return; } QString imgName = getOutputFileName(); if(imgName.isEmpty()){ QMessageBox::critical(this, tr("no output image selected"), tr("ERROR: No output image selected

" "please select a output image")); return; } if(QFile::exists(imgName)){ int ret = QMessageBox::question(this, tr("the Image File does already exist"), tr("The File %1 does already exist.

" "Do you want to overwrite?") .arg(imgName)); if(ret != QMessageBox::Yes) return; } QDir imgPath = QFileInfo(imgName).absoluteDir(); if(!imgPath.exists()) { int ret = QMessageBox::question(this, tr("the directory does not exist"), tr("The directory %1 does not exist.

" "Should it be created?") .arg(imgPath.absolutePath())); if(ret == QMessageBox::Yes) { imgPath.mkpath(imgPath.absolutePath()); } else return; } QString appDir =QCoreApplication::applicationDirPath(); qDebug()<path_World->text()//"D:\\Programme\\minetest\\worlds\\server_minetest.king-arthur.eu_30000" <<"--output" << imgName //"D:\\Users\\Adrian\\Desktop\\test2.png" <<"--colors" << dir.absoluteFilePath(ui->path_ColorsTxt->text()) //appDir+"\\colors\\colors.txt" <<"--progress" //<< "--verbose-search-colors=2" //<<"--verbose" <<"--drawalpha="+ui->drawAlpha->currentText() <<"--bgcolor" << ui->bgcolor->text() <<"--blockcolor" << ui->blockcolor->text() <<"--scalecolor" << ui->scalecolor->text() <<"--origincolor" << ui->origincolor->text() <<"--playercolor" << ui->playercolor->text() <<"--tilebordercolor" << ui->tilebordercolor->text(); if(ui->backend->currentIndex() !=0){ arguments <<"--backend" << ui->backend->currentText(); } if(ui->geometry->getFormat() != Geometry::FormatNone && ui->geometry->getGeometry() !=""){ arguments <<"--geometry" << ui->geometry->getGeometry().trimmed(); } if(ui->scalefactor->currentIndex() !=0){ arguments <<"--scalefactor" << ui->scalefactor->currentText(); } if(ui->checkBox_maxY->isChecked()){ arguments <<"--max-y" << ui->maxY->cleanText(); } if(ui->checkBox_minY->isChecked()){ arguments <<"--min-y" << ui->minY->cleanText(); } if(ui->geometrymode_pixel->isChecked()||ui->geometrymode_block->isChecked()||ui->geometrymode_shrink->isChecked()||ui->geometrymode_fixed->isChecked()){ arguments <<"--geometrymode"; if(ui->geometrymode_pixel->isChecked()){ arguments <<"pixel"; } if(ui->geometrymode_block->isChecked()){ arguments <<"block"; } if(ui->geometrymode_shrink->isChecked()){ arguments <<"shrink"; } if(ui->geometrymode_fixed->isChecked()){ arguments <<"fixed"; } } if(ui->drawScaleLeft->isChecked() && ui->drawScaleTop->isChecked()){ arguments <<"--drawscale=left,top"; } else if(ui->drawScaleLeft->isChecked()){ arguments <<"--drawscale=left"; } else if(ui->drawScaleTop->isChecked()){ arguments <<"--drawscale=top"; } if(ui->drawOrigin->isChecked()){ arguments <<"--draworigin"; } if(ui->drawPlayers->isChecked()){ arguments <<"--drawplayers"; } if(ui->drawAir->isChecked()){ arguments <<"--drawair"; } if(ui->noShading->isChecked()){ arguments <<"--noshading"; } //Heightmap Tab if(ui->generateHeightmap->isChecked()){ if(ui->heightmapColor->isChecked()){ arguments <<"--heightmap="+ui->colorHeightmap->text(); } else{ arguments <<"--heightmap"; } arguments <<"--heightmap-nodes" << ui->path_HeightmapNodes->text() <<"--heightmap-colors" << ui->path_HeightmapColors->text() <<"--heightmap-yscale" << ui->heightmapYscale->cleanText().replace(',','.') <<"--height-level-0" << ui->heightLevelNull->cleanText(); qDebug() << ui->heightLevelNull->cleanText(); if(ui->drawHeightscale->isChecked()){ arguments <<"--drawheightscale"; } } //Tiles Tab if(ui->tiles->isChecked()){ arguments <<"--tiles"; if(ui->tiles_sizeAndBorder->isChecked()){ arguments <tilesize->cleanText()+"+"+ui->tileborder->cleanText(); } else if(ui->tile_block->isChecked()){ arguments <<"block"; } else if(ui->tile_chunk->isChecked()){ arguments <<"chunk"; } if(ui->tileorigin->isChecked()){ arguments <<"--tileorigin"; } else{ arguments <<"--tilecenter"; } if(ui->tiles_coordinates->isChecked()){ arguments << ui->tiles_coordinateX->cleanText() +","+ ui->tiles_coordinateY->cleanText(); } else if(ui->tiles_world) arguments<<"world"; else { arguments<<"map"; } } ui->button_generate->setDisabled(true); if(ui->actionExpert_Mode->isChecked()){ bool ok; QString parameters = QInputDialog::getMultiLineText(this, tr("Expert Mode"),//title tr("MinetestMapper will be executed using this arguments. \n" "The arguments can be removed, modified, or new arguments can be added."),//label arguments.join("\n"),//text &ok,0); if (ok) arguments = parameters.split("\n"); else { ui->button_generate->setDisabled(false); return; } } myProcess = new QProcess(this); #ifdef Q_OS_WIN myProcess->setWorkingDirectory(appDir); #endif myProcess->setProgram(mapperBinary.fileName()); qDebug()<setArguments(arguments); qDebug()<arguments(); progressBar->show(); progressBar->setMaximum(100); ui->button_cancel->setDisabled(false); connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput())); connect(myProcess, SIGNAL(readyReadStandardError()), this, SLOT(readError()));//error stream contains unknown nodes connect(myProcess, SIGNAL(finished(int)), this, SLOT(mapperFinisched(int))); connect(myProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError))); ui->standardOutput->append("Starting "+myProcess->program()+" "+arguments.join(" ")); myProcess->start(); #ifdef Q_OS_WIN taskbarButton = new QWinTaskbarButton(this); taskbarButton->setWindow(this->windowHandle()); taskbarButton->setOverlayIcon(QIcon(":/save")); taskbarProgress = taskbarButton->progress(); taskbarProgress->show(); #endif } void MainWindow::on_button_cancel_clicked() { myProcess->kill(); #ifdef Q_OS_WIN taskbarProgress->stop(); #endif } void MainWindow::readOutput() { QByteArray outData = myProcess->readAllStandardOutput(); QString out = QString(outData).trimmed(); if(out != "") { QRegExp rx("([0-9]{1,3})(\\%)"); if(rx.indexIn(out)!=-1){ QString percent = rx.cap(1); // percent == number progressBar->setValue(percent.toInt()); #ifdef Q_OS_WIN taskbarProgress->setValue(percent.toInt()); #endif } ui->statusBar->showMessage(out); ui->standardOutput->append(out); } } void MainWindow::readError() { QByteArray outData = myProcess->readAllStandardError(); QString out = QString(outData).trimmed(); if(out != "") { ui->statusBar->showMessage(out); ui->standardOutput->append(""+out.toHtmlEscaped()+""); } } QString MainWindow::getOutputFileName() { QString worldPath = ui->path_World->text(); QString worldName = QDir(worldPath).dirName(); QString imgName = ui->path_OutputImage->text() .replace("", QDate::currentDate().toString(Qt::SystemLocaleShortDate)) .replace("", QDate::currentDate().toString(Qt::SystemLocaleLongDate)) .replace("", QDate::currentDate().toString(Qt::ISODate)) .replace("", worldName) .replace("