Fri, 08 Jul 2022 13:24:45 +0200
Removed old experiment to calculate flameout and whirlpool ibu's. Changed Tinseth calculation to use a time window so you can select the ibu contribution during a specified time. Added ibu_method Tinset++. Added calculation extensions for Tinseth++, this calculates the flameout and whirlpool effects on all hops. During cooling is to be done.
/** * Setup.cpp is part of bmsapp. * * bmsapp 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. * * bmsapp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "Setup.h" #include "config.h" #include "global.h" #include "MainWindow.h" Setup::Setup(QWidget *parent) : QDialog(parent) { QSqlQuery query; QGridLayout *gridLayout; QWidget *topWidget; QFrame *line; qDebug() << "Setup start"; gridLayout = new QGridLayout(this); gridLayout->setObjectName(QString::fromUtf8("gridLayout")); topWidget = new QWidget(this); topWidget->setObjectName(QString::fromUtf8("topWidget")); breweryLabel = new QLabel(topWidget); breweryLabel->setObjectName(QString::fromUtf8("breweryLabel")); breweryLabel->setGeometry(QRect(60, 20, 131, 20)); breweryLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); breweryLabel->setText(tr("Brewery name:")); breweryEdit = new QLineEdit(topWidget); breweryEdit->setObjectName(QString::fromUtf8("breweryEdit")); breweryEdit->setGeometry(QRect(212, 20, 941, 23)); breweryEdit->setToolTip(tr("The name for this brewery.")); line = new QFrame(topWidget); line->setObjectName(QString::fromUtf8("line")); line->setGeometry(QRect(0, 60, 1251, 20)); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); fwhLabel = new QLabel(topWidget); fwhLabel->setObjectName(QString::fromUtf8("fwhLabel")); fwhLabel->setGeometry(QRect(60, 120, 131, 20)); fwhLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); fwhLabel->setText(tr("First Wort Hop factor:")); mashhopLabel = new QLabel(topWidget); mashhopLabel->setObjectName(QString::fromUtf8("mashhopLabel")); mashhopLabel->setGeometry(QRect(60, 150, 131, 20)); mashhopLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); mashhopLabel->setText(tr("Mash Hop factor:")); pelletLabel = new QLabel(topWidget); pelletLabel->setObjectName(QString::fromUtf8("pelletLabel")); pelletLabel->setGeometry(QRect(60, 180, 131, 20)); pelletLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); pelletLabel->setText(tr("Pellet Hop factor:")); hopplugLabel = new QLabel(topWidget); hopplugLabel->setObjectName(QString::fromUtf8("hopplugLabel")); hopplugLabel->setGeometry(QRect(60, 210, 131, 20)); hopplugLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); hopplugLabel->setText(tr("Hop Plugs factor:")); wethopLabel = new QLabel(topWidget); wethopLabel->setObjectName(QString::fromUtf8("wethopLabel")); wethopLabel->setGeometry(QRect(60, 240, 131, 20)); wethopLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); wethopLabel->setText(tr("Wet Hop factor:")); cryohopLabel = new QLabel(topWidget); cryohopLabel->setObjectName(QString::fromUtf8("cryohopLabel")); cryohopLabel->setGeometry(QRect(60, 270, 131, 20)); cryohopLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); cryohopLabel->setText(tr("Cryo Hop\302\256 factor:")); fwhEdit = new QSpinBox(topWidget); fwhEdit->setObjectName(QString::fromUtf8("fwhEdit")); fwhEdit->setGeometry(QRect(210, 120, 81, 24)); fwhEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); fwhEdit->setAccelerated(true); fwhEdit->setMinimum(-50); fwhEdit->setMaximum(50); fwhEdit->setToolTip(tr("The efficiency for First Wort Hopping.")); fwhEdit->setSuffix(tr("%")); mashhopEdit = new QSpinBox(topWidget); mashhopEdit->setObjectName(QString::fromUtf8("mashhopEdit")); mashhopEdit->setGeometry(QRect(210, 150, 81, 24)); mashhopEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); mashhopEdit->setAccelerated(true); mashhopEdit->setMinimum(-50); mashhopEdit->setMaximum(50); mashhopEdit->setToolTip(tr("The efficiency for Mash hopping.")); mashhopEdit->setSuffix(tr("%")); pelletEdit = new QSpinBox(topWidget); pelletEdit->setObjectName(QString::fromUtf8("pelletEdit")); pelletEdit->setGeometry(QRect(210, 180, 81, 24)); pelletEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); pelletEdit->setAccelerated(true); pelletEdit->setMinimum(0); pelletEdit->setMaximum(20); pelletEdit->setToolTip(tr("The efficiency for hop pellets.")); pelletEdit->setSuffix(tr("%")); hopplugEdit = new QSpinBox(topWidget); hopplugEdit->setObjectName(QString::fromUtf8("hopplugEdit")); hopplugEdit->setGeometry(QRect(210, 210, 81, 24)); hopplugEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); hopplugEdit->setAccelerated(true); hopplugEdit->setMaximum(20); hopplugEdit->setToolTip(tr("The efficiency for hop plugs.")); hopplugEdit->setSuffix(tr("%")); wethopEdit = new QSpinBox(topWidget); wethopEdit->setObjectName(QString::fromUtf8("wethopEdit")); wethopEdit->setGeometry(QRect(210, 240, 81, 24)); wethopEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); wethopEdit->setAccelerated(true); wethopEdit->setMinimum(-98); wethopEdit->setMaximum(-20); wethopEdit->setToolTip(tr("The efficiency for fresh hops.")); wethopEdit->setSuffix(tr("%")); cryohopEdit = new QSpinBox(topWidget); cryohopEdit->setObjectName(QString::fromUtf8("cryohopEdit")); cryohopEdit->setGeometry(QRect(210, 270, 81, 24)); cryohopEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); cryohopEdit->setAccelerated(true); cryohopEdit->setMinimum(-20); cryohopEdit->setMaximum(150); cryohopEdit->setToolTip(tr("The efficiency for using Cryo Hop\302\256.")); cryohopEdit->setSuffix(tr("%")); grainLabel = new QLabel(topWidget); grainLabel->setObjectName(QString::fromUtf8("grainLabel")); grainLabel->setGeometry(QRect(400, 120, 161, 20)); grainLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); grainLabel->setText(tr("Grain Absorbtion:")); brixLabel = new QLabel(topWidget); brixLabel->setObjectName(QString::fromUtf8("brixLabel")); brixLabel->setGeometry(QRect(400, 150, 161, 20)); brixLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); brixLabel->setText(tr("Brix Correction factor:")); heightLabel = new QLabel(topWidget); heightLabel->setObjectName(QString::fromUtf8("heightLabel")); heightLabel->setGeometry(QRect(400, 180, 161, 20)); heightLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); heightLabel->setText(tr("Brewery height meters:")); titleLabel = new QLabel(topWidget); titleLabel->setObjectName(QString::fromUtf8("titleLabel")); titleLabel->setGeometry(QRect(5, 80, 1251, 20)); QFont font; font.setFamily(QString::fromUtf8("DejaVu Sans")); font.setPointSize(12); font.setBold(true); font.setWeight(75); titleLabel->setFont(font); titleLabel->setAlignment(Qt::AlignCenter); titleLabel->setText(tr("Brew settings.")); colorLabel = new QLabel(topWidget); colorLabel->setObjectName(QString::fromUtf8("colorLabel")); colorLabel->setGeometry(QRect(800, 120, 121, 16)); colorLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); colorLabel->setText(tr("Color Calculation:")); ibuLabel = new QLabel(topWidget); ibuLabel->setObjectName(QString::fromUtf8("ibuLabel")); ibuLabel->setGeometry(QRect(800, 150, 121, 16)); ibuLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); ibuLabel->setText(tr("IBU Calculation:")); waterLabel = new QLabel(topWidget); waterLabel->setObjectName(QString::fromUtf8("waterLabel")); waterLabel->setGeometry(QRect(800, 180, 121, 16)); waterLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); waterLabel->setText(tr("Default Water:")); yeastLabel = new QLabel(topWidget); yeastLabel->setObjectName(QString::fromUtf8("yeastLabel")); yeastLabel->setGeometry(QRect(800, 210, 121, 16)); yeastLabel->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); yeastLabel->setText(tr("Private Yeast bank:")); grainEdit = new QDoubleSpinBox(topWidget); grainEdit->setObjectName(QString::fromUtf8("grainEdit")); grainEdit->setGeometry(QRect(580, 120, 101, 24)); grainEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); grainEdit->setAccelerated(true); grainEdit->setMinimum(0.500000000000000); grainEdit->setMaximum(1.100000000000000); grainEdit->setSingleStep(0.010000000000000); grainEdit->setStepType(QAbstractSpinBox::DefaultStepType); grainEdit->setValue(1.000000000000000); grainEdit->setToolTip(tr("Absorbtion with water by the grain (L/Kg)")); grainEdit->setSuffix(tr(" L/Kg")); brixEdit = new QDoubleSpinBox(topWidget); brixEdit->setObjectName(QString::fromUtf8("brixEdit")); brixEdit->setGeometry(QRect(580, 150, 101, 24)); brixEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); brixEdit->setAccelerated(true); brixEdit->setMinimum(1.000000000000000); brixEdit->setMaximum(1.090000000000000); brixEdit->setSingleStep(0.010000000000000); brixEdit->setStepType(QAbstractSpinBox::DefaultStepType); brixEdit->setValue(1.000000000000000); brixEdit->setToolTip(tr("Plato to Brix conversion factor.")); heightEdit = new QSpinBox(topWidget); heightEdit->setObjectName(QString::fromUtf8("heightEdit")); heightEdit->setGeometry(QRect(580, 180, 101, 24)); heightEdit->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); heightEdit->setAccelerated(true); heightEdit->setMinimum(-430); heightEdit->setMaximum(8849); heightEdit->setStepType(QAbstractSpinBox::DefaultStepType); heightEdit->setValue(0); heightEdit->setToolTip(tr("Height in meters above/below sealevel to calculate the exact boiling point and hop isomerizon.")); colorEdit = new QComboBox(topWidget); colorEdit->setObjectName(QString::fromUtf8("colorEdit")); colorEdit->setGeometry(QRect(940, 120, 161, 23)); colorEdit->setMinimumContentsLength(4); colorEdit->setIconSize(QSize(0, 0)); colorEdit->setCurrentText(QString()); colorEdit->setPlaceholderText(tr("Choose color")); ibuEdit = new QComboBox(topWidget); ibuEdit->setObjectName(QString::fromUtf8("ibuEdit")); ibuEdit->setGeometry(QRect(940, 150, 161, 23)); ibuEdit->setMinimumContentsLength(4); ibuEdit->setIconSize(QSize(0, 0)); ibuEdit->setCurrentText(QString()); ibuEdit->setPlaceholderText(tr("Choose color")); waterEdit = new QComboBox(topWidget); waterEdit->setObjectName(QString::fromUtf8("waterEdit")); waterEdit->setGeometry(QRect(940, 180, 211, 23)); waterEdit->setMinimumContentsLength(4); waterEdit->setIconSize(QSize(0, 0)); waterEdit->setCurrentText(QString()); waterEdit->setPlaceholderText(tr("Choose color")); yeastEdit = new QComboBox(topWidget); yeastEdit->setObjectName(QString::fromUtf8("yeastEdit")); yeastEdit->setGeometry(QRect(940, 210, 211, 23)); yeastEdit->setMinimumContentsLength(4); yeastEdit->setIconSize(QSize(0, 0)); yeastEdit->setCurrentText(QString()); yeastEdit->setPlaceholderText(tr("Choose color")); logoLabel = new QLabel(topWidget); logoLabel->setObjectName(QString::fromUtf8("logoLabel")); logoLabel->setGeometry(QRect(940, 260, 211, 211)); logoLabel->setAlignment(Qt::AlignCenter); logoLabel->setText(tr("Logo here")); quitButton = new QPushButton(topWidget); quitButton->setObjectName(QString::fromUtf8("quitButton")); quitButton->setGeometry(QRect(50, 520, 80, 23)); QIcon icon; icon.addFile(QString::fromUtf8(":icons/silk/door_out.png"), QSize(), QIcon::Normal, QIcon::Off); quitButton->setIcon(icon); quitButton->setText(tr("Quit")); saveButton = new QPushButton(topWidget); saveButton->setObjectName(QString::fromUtf8("saveButton")); saveButton->setGeometry(QRect(200, 520, 80, 23)); QIcon icon1; icon1.addFile(QString::fromUtf8(":icons/silk/disk.png"), QSize(), QIcon::Normal, QIcon::Off); saveButton->setIcon(icon1); saveButton->setText(tr("Save")); saveButton->setEnabled(false); openButton = new QPushButton(topWidget); openButton->setObjectName(QString::fromUtf8("openButton")); openButton->setGeometry(QRect(810, 260, 111, 23)); QIcon icon2; icon2.addFile(QString::fromUtf8(":/icons/silk/folder_picture.png"), QSize(), QIcon::Normal, QIcon::Off); openButton->setIcon(icon2); openButton->setText(tr("Load logo")); gridLayout->addWidget(topWidget, 0, 0, 1, 1); connect(quitButton, SIGNAL(clicked()), this, SLOT(on_quitButton_clicked())); connect(saveButton, SIGNAL(clicked()), this, SLOT(on_saveButton_clicked())); connect(openButton, SIGNAL(clicked()), this, SLOT(on_openButton_clicked())); connect(this, SIGNAL(firstWindow()), parent, SLOT(fromSetup())); connect(this, SIGNAL(setTitle(QString)), parent, SLOT(windowTitle(QString))); emit setTitle(QString(tr("Setup"))); query.prepare("SELECT * FROM profile_setup WHERE record='1'"); query.exec(); query.next(); breweryEdit->setText(query.value("brewery_name").toString()); // max 128 connect(breweryEdit, &QLineEdit::textChanged, this, &Setup::is_changed); fwhEdit->setValue(query.value("factor_fwh").toInt()); mashhopEdit->setValue(query.value("factor_mashhop").toInt()); pelletEdit->setValue(query.value("factor_pellet").toInt()); hopplugEdit->setValue(query.value("factor_plug").toInt()); wethopEdit->setValue(query.value("factor_wethop").toInt()); cryohopEdit->setValue(query.value("factor_cryohop").toInt()); connect(fwhEdit, &QSpinBox::textChanged, this, &Setup::is_changed); connect(mashhopEdit, &QSpinBox::textChanged, this, &Setup::is_changed); connect(pelletEdit, &QSpinBox::textChanged, this, &Setup::is_changed); connect(hopplugEdit, &QSpinBox::textChanged, this, &Setup::is_changed); connect(wethopEdit, &QSpinBox::textChanged, this, &Setup::is_changed); connect(cryohopEdit, &QSpinBox::textChanged, this, &Setup::is_changed); grainEdit->setValue(query.value("grain_absorbtion").toDouble()); brixEdit->setValue(query.value("brix_correction").toDouble()); heightEdit->setValue(query.value("brewery_height").toInt()); connect(grainEdit, &QDoubleSpinBox::textChanged, this, &Setup::is_changed); connect(brixEdit, &QDoubleSpinBox::textChanged, this, &Setup::is_changed); connect(heightEdit, &QSpinBox::textChanged, this, &Setup::is_changed); colorEdit->addItem("Morey"); colorEdit->addItem("Mosher"); colorEdit->addItem("Daniels"); colorEdit->addItem("Halberstadt"); colorEdit->addItem("Naudts"); colorEdit->setCurrentIndex(query.value("color_method").toInt()); connect(colorEdit, &QComboBox::currentTextChanged, this, &Setup::is_changed); for (int i = 0; i < 3; i++) ibuEdit->addItem(g_ibu_method[i]); ibuEdit->setCurrentIndex(query.value("ibu_method").toInt()); connect(ibuEdit, &QComboBox::currentTextChanged, this, &Setup::is_changed); QSqlQuery query2("SELECT record,name FROM inventory_waters"); query2.first(); int pos = -1; waterEdit->setEditable(true); waterEdit->setPlaceholderText(tr("Choose default water")); for (int i = 0 ; i < query2.size() ; i++ ) { waterEdit->addItem(query2.value(1).toString()); if (query2.value(0).toInt() == query.value("default_water").toInt()) { pos = i; } query2.next(); } if (pos >= 0) waterEdit->setCurrentIndex(pos); connect(waterEdit, &QComboBox::currentTextChanged, this, &Setup::is_changed); QSqlQuery query3("SELECT DISTINCT laboratory FROM inventory_yeasts ORDER BY laboratory"); query3.first(); pos = -1; yeastEdit->setEditable(true); yeastEdit->setPlaceholderText(tr("Choose laboratory")); for (int i = 0 ; i < query3.size() ; i++ ) { yeastEdit->addItem(query3.value(0).toString()); if (QString::compare(query.value("my_yeastlab").toString(), query3.value(0).toString(), Qt::CaseSensitive) == 0) pos = i; query3.next(); } if (pos >= 0) yeastEdit->setCurrentIndex(pos); connect(yeastEdit, &QComboBox::currentTextChanged, this, &Setup::is_changed); /* logo */ logoByteArray = query.value("brewery_logo").toByteArray(); QPixmap outPixmap = QPixmap(); outPixmap.loadFromData(logoByteArray); logoLabel->setPixmap(outPixmap); logoLabel->adjustSize(); } Setup::~Setup() {} bool Setup::loadFile(const QString &fileName) { QImageReader reader(fileName); reader.setAutoTransform(true); const QImage newImage = reader.read(); if (newImage.isNull()) { QMessageBox::information(this, QGuiApplication::applicationDisplayName(), tr("Cannot load %1: %2") .arg(QDir::toNativeSeparators(fileName), reader.errorString())); return false; } setImage(newImage); setWindowFilePath(fileName); is_changed(); return true; } void Setup::setImage(const QImage &newImage) { image = newImage; qDebug() << "setImage" << image.width() << image.height() << "size" << image.sizeInBytes(); QBuffer buffer(&logoByteArray); buffer.open(QIODevice::WriteOnly); image.save(&buffer, "PNG"); // writes image into logoByteArray in PNG format this->logoLabel->setPixmap(QPixmap::fromImage(image)); scaleFactor = 1.0; // this->logoLabel->resize(scaleFactor * ui->logoLabel->pixmap(Qt::ReturnByValue).size()); this->logoLabel->adjustSize(); } void Setup::on_openButton_clicked() { static bool firstDialog = true; qDebug() << "Setup open"; QFileDialog dialog(this, tr("Open File")); if (firstDialog) { firstDialog = false; const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); dialog.setDirectory(picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last()); } /* Only a few image formats are valid */ QStringList mimeTypeFilters ({ "image/bmp", "image/gif", "image/jpeg", "image/png", "image/svg+xml" }); dialog.setMimeTypeFilters(mimeTypeFilters); dialog.setNameFilter("Images (*.bmp *.BMP *.gif *.GIF *.jpg *.JPG *.png *.PNG *.svg *.SVG)"); dialog.setAcceptMode(QFileDialog::AcceptOpen); while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().constFirst())) {} } /* * Also called from the Quit button if there are changes to save. */ void Setup::on_saveButton_clicked() { QSqlQuery query; /* * Search record number of the current water. */ query.prepare("SELECT record FROM inventory_waters WHERE name=:name"); query.bindValue(":name", this->waterEdit->currentText()); query.exec(); query.first(); int record = query.value(0).toInt(); /* * Update all other data */ query.prepare("UPDATE profile_setup SET brewery_name=:brewery, brewery_logo=:logo, factor_mashhop=:mashhop, factor_fwh=:fwh, " "factor_pellet=:pellet, factor_plug=:plug, factor_wethop=:wet, factor_cryohop=:cryo, color_method=:color, ibu_method=:ibu, " "brix_correction=:brix, grain_absorbtion=:grain, default_water=:water, my_yeastlab=:yeast, " "brewery_height=:height WHERE record='1'"); query.bindValue(":brewery", this->breweryEdit->text()); query.bindValue(":logo", logoByteArray); query.bindValue(":mashhop", this->mashhopEdit->value()); query.bindValue(":fwh", this->fwhEdit->value()); query.bindValue(":pellet", this->pelletEdit->value()); query.bindValue(":plug", this->hopplugEdit->value()); query.bindValue(":wet", this->wethopEdit->value()); query.bindValue(":cryo", this->cryohopEdit->value()); query.bindValue(":color", this->colorEdit->currentIndex()); query.bindValue(":ibu", this->ibuEdit->currentIndex()); query.bindValue(":brix", this->brixEdit->value()); query.bindValue(":grain", this->grainEdit->value()); query.bindValue(":water", record); query.bindValue(":yeast", this->yeastEdit->currentText()); query.bindValue(":height", this->heightEdit->value()); query.exec(); if (query.lastError().isValid()) { qDebug() << "Setup Save error:" << query.lastError(); QMessageBox::warning(this, tr("Database error"), tr("MySQL error: %1\n%2\n%3") .arg(query.lastError().nativeErrorCode()) .arg(query.lastError().driverText()) .arg(query.lastError().databaseText())); } else { qDebug() << "Setup Saved"; } this->fieldIsChanged = false; saveButton->setEnabled(false); emit setTitle(QString(tr("Setup"))); } void Setup::on_quitButton_clicked() { if (this->fieldIsChanged) { int rc = QMessageBox::warning(this, tr("Setup changed"), tr("The global setup has been modified. Save changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save); switch (rc) { case QMessageBox::Save: on_saveButton_clicked(); break; /* Saved and then Quit */ case QMessageBox::Discard: break; /* Quit without Save */ case QMessageBox::Cancel: return; /* Return to the setup page */ } } emit firstWindow(); } void Setup::is_changed() { saveButton->setEnabled(true); this->fieldIsChanged = true; emit setTitle(QString(tr("Setup") + " **")); }