diff --git a/Messages.sh b/Messages.sh index 461bcd8..630e77c 100644 --- a/Messages.sh +++ b/Messages.sh @@ -1,4 +1,4 @@ #! /usr/bin/env bash $EXTRACTRC `find . -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp -$XGETTEXT `find . -name \*.cc -o -name \*.cpp -o -name \*.h -name \*.qml` -o $podir/aelier.pot +$XGETTEXT `find . -name \*.cc -o -name \*.cpp -o -name \*.h -name \*.qml` -o $podir/atelier.pot diff --git a/src/dialogs/profilesdialog.cpp b/src/dialogs/profilesdialog.cpp index 3798005..d3c11b1 100644 --- a/src/dialogs/profilesdialog.cpp +++ b/src/dialogs/profilesdialog.cpp @@ -1,281 +1,281 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2016> Author: Lays Rodrigues - lays.rodrigues@kde.org Chris Rizzitello - rizzitello@kde.org This program 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. This program 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 . */ #include #include #include #include #include "profilesdialog.h" #include "ui_profilesdialog.h" ProfilesDialog::ProfilesDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::ProfilesDialog) , m_modified(false) { ui->setupUi(this); ui->firmwareCB->addItem(QStringLiteral("Auto-Detect")); ui->firmwareCB->addItems(detectFWPlugins()); ui->baudCB->addItems(SERIAL::BAUDS); ui->baudCB->setCurrentText(QLatin1String("115200")); ui->profileCB->setAutoCompletion(true); connect(ui->profileCB, static_cast(&QComboBox::currentIndexChanged), this, [this] { askToSave(); loadSettings(); }); updateCBProfiles(); connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &ProfilesDialog::buttonBoxClicked); connect(ui->heatedBedCK, &QCheckBox::clicked, this, [this](const bool & status) { ui->bedTempSB->setEnabled(status); }); connect(ui->cartesianRB, &QRadioButton::clicked, this, [this] { ui->printerTypeStack->setCurrentIndex(1); }); connect(ui->deltaRB, &QRadioButton::clicked, this, [this] { ui->printerTypeStack->setCurrentIndex(0); }); connect(ui->removeProfilePB, &QPushButton::clicked, this, &ProfilesDialog::removeProfile); ui->removeProfilePB->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"), style()->standardIcon(QStyle::SP_TrashIcon))); -//if any control is modifed and no load / save has happend contents are not saved. +//if any control is modified and no load / save has happened contents are not saved. auto modify = [this] {setModified(true);}; connect(ui->baudCB, &QComboBox::currentTextChanged, modify); connect(ui->radiusSB, &QSpinBox::editingFinished, modify); connect(ui->z_delta_dimensionSB, &QSpinBox::editingFinished, modify); connect(ui->x_dimensionSB, &QSpinBox::editingFinished, modify); connect(ui->y_dimensionSB, &QSpinBox::editingFinished, modify); connect(ui->z_dimensionSB, &QSpinBox::editingFinished, modify); connect(ui->heatedBedCK, &QCheckBox::stateChanged, modify); connect(ui->bedTempSB, &QSpinBox::editingFinished, modify); connect(ui->extruderTempSB, &QSpinBox::editingFinished, modify); connect(ui->postPauseLE, &QLineEdit::editingFinished, modify); connect(ui->firmwareCB, &QComboBox::currentTextChanged, modify); } ProfilesDialog::~ProfilesDialog() { delete ui; } void ProfilesDialog::buttonBoxClicked(QAbstractButton *btn) { switch (ui->buttonBox->buttonRole(btn)) { case QDialogButtonBox::ResetRole: askToSave(); loadSettings(); break; case QDialogButtonBox::RejectRole: askToSave(); close(); break; case QDialogButtonBox::AcceptRole: saveSettings(); break; default: break; } } void ProfilesDialog::saveSettings() { m_settings.beginGroup(QStringLiteral("Profiles")); QStringList groups = m_settings.childGroups(); m_settings.endGroup(); if (groups.contains(ui->profileCB->currentText())) { int ret = QMessageBox::warning( this , i18n("Overwrite Profile?") , i18n("A profile with this name already exists. \n Are you sure you want to overwrite it?") , QMessageBox::Save , QMessageBox::Cancel ); if (ret == QMessageBox::Cancel) { return; } } save(); } void ProfilesDialog::save() { QString currentProfile = ui->profileCB->currentText(); //Add indent to better view of the data m_settings.beginGroup(QStringLiteral("Profiles")); m_settings.beginGroup(currentProfile); //BED if (ui->cartesianRB->isChecked()) { m_settings.setValue(QStringLiteral("isCartesian"), true); m_settings.setValue(QStringLiteral("dimensionX"), ui->x_dimensionSB->value()); m_settings.setValue(QStringLiteral("dimensionY"), ui->y_dimensionSB->value()); m_settings.setValue(QStringLiteral("dimensionZ"), ui->z_dimensionSB->value()); } else { m_settings.setValue(QStringLiteral("isCartesian"), false); m_settings.setValue(QStringLiteral("radius"), ui->radiusSB->value()); m_settings.setValue(QStringLiteral("z_delta_dimension"), ui->z_dimensionSB->value()); } m_settings.setValue(QStringLiteral("heatedBed"), ui->heatedBedCK->isChecked()); m_settings.setValue(QStringLiteral("maximumTemperatureBed"), ui->bedTempSB->value()); //HOTEND m_settings.setValue(QStringLiteral("maximumTemperatureExtruder"), ui->extruderTempSB->value()); //Baud m_settings.setValue(QStringLiteral("bps"), ui->baudCB->currentText()); m_settings.setValue(QStringLiteral("firmware"), ui->firmwareCB->currentText()); m_settings.setValue(QStringLiteral("postPause"), ui->postPauseLE->text()); m_settings.endGroup(); m_settings.endGroup(); //Load new profile setModified(false); updateCBProfiles(); loadSettings(currentProfile); emit updateProfiles(); } void ProfilesDialog::loadSettings(const QString ¤tProfile) { m_settings.beginGroup(QStringLiteral("Profiles")); const QString profileName = currentProfile.isEmpty() ? ui->profileCB ->currentText() : currentProfile; ui->profileCB->setCurrentText(profileName); m_settings.beginGroup(profileName); //BED if (m_settings.value(QStringLiteral("isCartesian")).toBool()) { ui->printerTypeStack->setCurrentIndex(1); ui->cartesianRB->setChecked(true); ui->deltaRB->setChecked(false); ui->x_dimensionSB->setValue(m_settings.value(QStringLiteral("dimensionX"), QStringLiteral("0")).toInt()); ui->y_dimensionSB->setValue(m_settings.value(QStringLiteral("dimensionY"), QStringLiteral("0")).toInt()); ui->z_dimensionSB->setValue(m_settings.value(QStringLiteral("dimensionZ"), QStringLiteral("0")).toInt()); } else { ui->printerTypeStack->setCurrentIndex(0); ui->deltaRB->setChecked(true); ui->cartesianRB->setChecked(false); ui->radiusSB->setValue(m_settings.value(QStringLiteral("radius"), QStringLiteral("0")).toInt()); ui->z_delta_dimensionSB->setValue(m_settings.value(QStringLiteral("z_delta_dimension"), QStringLiteral("0")).toInt()); } ui->heatedBedCK->setChecked(m_settings.value(QStringLiteral("heatedBed"), QStringLiteral("true")).toBool()); ui->bedTempSB->setEnabled(ui->heatedBedCK->isChecked()); ui->bedTempSB->setValue(m_settings.value(QStringLiteral("maximumTemperatureBed"), QStringLiteral("0")).toInt()); //HOTEND ui->extruderTempSB->setValue(m_settings.value(QStringLiteral("maximumTemperatureExtruder"), QStringLiteral("0")).toInt()); //Baud ui->baudCB->setCurrentText(m_settings.value(QStringLiteral("bps"), QStringLiteral("115200")).toString()); ui->firmwareCB->setCurrentText(m_settings.value(QStringLiteral("firmware"), QStringLiteral("Auto-Detect")).toString()); ui->postPauseLE->setText(m_settings.value(QStringLiteral("postPause"), QStringLiteral("")).toString()); m_settings.endGroup(); m_settings.endGroup(); setModified(false); } void ProfilesDialog::updateCBProfiles() { m_settings.beginGroup(QStringLiteral("Profiles")); QStringList groups = m_settings.childGroups(); m_settings.endGroup(); if (groups.isEmpty()) { ui->printerTypeStack->setCurrentIndex(1); } ui->profileCB->clear(); ui->profileCB->addItems(groups); } void ProfilesDialog::removeProfile() { QString currentProfile = ui->profileCB->currentText(); m_settings.beginGroup(QStringLiteral("Profiles")); m_settings.beginGroup(currentProfile); m_settings.remove(""); m_settings.endGroup(); m_settings.remove(currentProfile); m_settings.endGroup(); updateCBProfiles(); } QStringList ProfilesDialog::detectFWPlugins() { QStringList firmwares; QStringList paths = AtCoreDirectories::pluginDir; //Add our runtime paths paths.prepend(qApp->applicationDirPath() + QStringLiteral("/../Plugins/AtCore")); paths.prepend(qApp->applicationDirPath() + QStringLiteral("/AtCore")); paths.prepend(qApp->applicationDirPath() + QStringLiteral("/plugins")); for (const QString &path : paths) { firmwares = firmwaresInPath(path); if (!firmwares.isEmpty()) { //use path where plugins were detected. break; } } return firmwares; } QStringList ProfilesDialog::firmwaresInPath(const QString &path) { QStringList firmwares; QStringList files = QDir(path).entryList(QDir::Files); for (const QString &f : files) { QString file = f; #if defined(Q_OS_WIN) if (file.endsWith(QStringLiteral(".dll"))) #elif defined(Q_OS_MAC) if (file.endsWith(QStringLiteral(".dylib"))) #else if (file.endsWith(QStringLiteral(".so"))) #endif file = file.split(QChar::fromLatin1('.')).at(0); else { continue; } if (file.startsWith(QStringLiteral("lib"))) { file = file.remove(QStringLiteral("lib")); } file = file.toLower().simplified(); firmwares.append(file); } return firmwares; } void ProfilesDialog::setModified(bool modified) { m_modified = modified; } void ProfilesDialog::askToSave() { if (m_modified) { int ret = QMessageBox::question( this , i18n("Save?") , i18n("This Profile has been modified, Would you like to Save it?") , QMessageBox::Save , QMessageBox::No ); if (ret == QMessageBox::Save) { save(); } } } diff --git a/src/widgets/gcodeeditorwidget.cpp b/src/widgets/gcodeeditorwidget.cpp index 7a89d88..7262914 100644 --- a/src/widgets/gcodeeditorwidget.cpp +++ b/src/widgets/gcodeeditorwidget.cpp @@ -1,142 +1,142 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2016> Author: Lays Rodrigues - lays.rodrigues@kde.org Chris Rizzitello - rizzitello@kde.org This program 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. This program 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 . */ #include #include #include #include #include #include "gcodeeditorwidget.h" GCodeEditorWidget::GCodeEditorWidget(QWidget *parent) : QWidget(parent) , m_tabwidget(new QTabWidget()) { setAcceptDrops(true); m_editor = KTextEditor::Editor::instance(); setupTabWidget(); QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(m_tabwidget); setLayout(layout); } void GCodeEditorWidget::setupTabWidget() { connect(m_tabwidget, &QTabWidget::tabCloseRequested, this, &GCodeEditorWidget::closeTab); connect(m_tabwidget, &QTabWidget::currentChanged, this, &GCodeEditorWidget::currentIndexChanged); m_tabwidget->setTabsClosable(true); } void GCodeEditorWidget::loadFile(const QUrl &file) { //if the file is loaded then reload the document. if (urlDoc.contains(file)) { urlDoc[file]->documentReload(); m_tabwidget->setCurrentIndex(m_tabwidget->indexOf(urlTab[file])); return; } auto doc = newDoc(file); int t = m_tabwidget->addTab(newView(doc), file.fileName()); urlDoc[doc->url()] = doc; urlTab[doc->url()] = m_tabwidget->widget(t); //connect our new document's modified state changed signal. connect(doc, &KTextEditor::Document::modifiedChanged, this, [this, t](const KTextEditor::Document * document) { QString filename = document->url().fileName(QUrl::FullyDecoded); if (document->isModified()) { filename.append(" *"); } m_tabwidget->setTabText(t, filename); }); m_tabwidget->setCurrentIndex(t); } void GCodeEditorWidget::setupInterface(const KTextEditor::View *view) { m_interface = qobject_cast(view); m_interface->setConfigValue("line-numbers", true); m_interface->setConfigValue("dynamic-word-wrap", false); m_interface->setConfigValue("modification-markers", true); m_interface->setConfigValue("scrollbar-minimap", false); } KTextEditor::Document *GCodeEditorWidget::newDoc(const QUrl &file) { KTextEditor::Document *doc = m_editor->createDocument(this); doc->setMode("G-Code"); doc->openUrl(file); doc->setHighlightingMode(QString("G-Code")); return doc; } KTextEditor::View *GCodeEditorWidget::newView(KTextEditor::Document *doc) { auto view = doc->createView(this); // Connection is a hack using undocumented parts of KTextEditor::View. - // One day this may break, KTextEditor::View needs this added correcty as a real slot to the API. + // One day this may break, KTextEditor::View needs this added correctly as a real slot to the API. // Hopefully we can get that added and use it in the future. // This must be the older style connect string or it will not work. connect(view, SIGNAL(dropEventPass(QDropEvent *)), this, SLOT(dropCatch(QDropEvent *))); setupInterface(view); return view; } void GCodeEditorWidget::closeTab(int index) { QUrl url = urlTab.key(m_tabwidget->widget(index)); auto doc = urlDoc[url]; if (doc->closeUrl()) { m_tabwidget->removeTab(index); urlTab.remove(url); urlDoc.remove(url); emit fileClosed(url); } } void GCodeEditorWidget::currentIndexChanged(int index) { emit currentFileChanged(urlTab.key(m_tabwidget->widget(index))); emit updateClientFactory(qobject_cast(m_tabwidget->widget(index))); } void GCodeEditorWidget::dropCatch(QDropEvent *event) { if (event->mimeData()->hasUrls()) { emit droppedUrls(event->mimeData()->urls()); } } QVector GCodeEditorWidget::modifiedFiles() { QVector modList; for (auto const &doc : m_editor->documents()) { if (doc->isModified()) { modList.append(doc->url()); } } return modList; } bool GCodeEditorWidget::saveFile(const QUrl &url) { if (!urlDoc.contains(url)) { return false; } KTextEditor::Document *doc = urlDoc[url]; return doc->save(); } diff --git a/src/widgets/thermowidget.cpp b/src/widgets/thermowidget.cpp index 2f4ba0e..2b14c4b 100644 --- a/src/widgets/thermowidget.cpp +++ b/src/widgets/thermowidget.cpp @@ -1,306 +1,306 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2018> Author: Tomaz Canabrava - tcanabrava@kde.org Chris Rizzitello - rizzitello@kde.org Lays Rodrigues - lays.rodrigues@kde.org This program 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. This program 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 . */ #include #include #include #include #include #include #include #include #include "thermowidget.h" ThermoWidget::ThermoWidget(QWidget *parent, QString name) : QwtDial(parent) , m_targetTemperatureNeedle(new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, false, Qt::red, Qt::darkRed)) , m_name(name) , m_tempChangedTimer(new QTimer()) , m_currentTemperature(0) , m_targetTemperature(0) { setScaleArc(40, 320); //make our current temperature needle here so we can set it to match text color. m_currentTemperatureNeedle = new QwtDialSimpleNeedle(QwtDialSimpleNeedle::Arrow, true, palette().text().color()); setNeedle(m_currentTemperatureNeedle); setReadOnly(false); setFocusPolicy(Qt::StrongFocus); m_cursorTimer = new QTimer(); connect(m_cursorTimer, &QTimer::timeout, this, [this] { m_paintCursor = !m_paintCursor; update(); }); m_tempChangedTimer->setSingleShot(true); connect(m_tempChangedTimer, &QTimer::timeout, this, [this] { emit targetTemperatureChanged(m_targetTemperature); }); } void ThermoWidget::keyPressEvent(QKeyEvent *event) { //set our target text length. int slen = m_currentTemperatureTextFromEditor.length() - 1; - // be sure our cursor posistion is valid. + // be sure our cursor position is valid. if (slen < 0) { m_currentTemperatureTextFromEditor = '-'; m_cursorPos = 0; } else if (slen > 2) { m_cursorPos = 2; } //parse the key events. if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9) { auto tmp = m_currentTemperatureTextFromEditor; if (m_cursorPos == slen) { tmp.append(event->key()); } else { tmp.insert(m_cursorPos, event->key()); } if (tmp.startsWith('0')) { tmp.remove(0, 1); } if (tmp.contains('-')) { tmp.remove('-'); //push the cursor back to negate advancement; m_cursorPos--; } if (tmp.toInt() <= upperBound() && tmp.toInt() >= lowerBound()) { m_currentTemperatureTextFromEditor = tmp; if (m_cursorPos <= slen) { m_cursorPos++; } } } else if (event->key() == Qt::Key_Delete && m_currentTemperatureTextFromEditor.count()) { m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); if (m_cursorPos < slen) { m_cursorPos = slen; } m_cursorPos--; } else if (event->key() == Qt::Key_Backspace && m_currentTemperatureTextFromEditor.count()) { if (m_cursorPos <= slen) { m_cursorPos--; m_currentTemperatureTextFromEditor.remove(m_cursorPos, 1); } } else if (event->key() == Qt::Key_Enter) { m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); } else if (event->key() == Qt::Key_Escape) { m_currentTemperatureTextFromEditor = '0'; } else if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Plus) { if (!isEqual(m_targetTemperature, upperBound())) { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 1); } } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Minus) { if (!isEqual(m_targetTemperature, lowerBound())) { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 1); } } else if (event->key() == Qt::Key_PageUp) { if (m_targetTemperature + 10 > upperBound()) { m_currentTemperatureTextFromEditor = QString::number(upperBound()); } else { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); } } else if (event->key() == Qt::Key_PageDown) { if (m_targetTemperature - 10 < lowerBound()) { m_currentTemperatureTextFromEditor = QString::number(lowerBound()); } else { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); } } else if (event->key() == Qt::Key_Right) { if (m_cursorPos < slen) { m_cursorPos++; } } else if (event->key() == Qt::Key_Left) { if (m_cursorPos > 0) { m_cursorPos--; } } else { QwtDial::keyPressEvent(event); return; } if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); resetTimer(); update(); event->accept(); } } void ThermoWidget::wheelEvent(QWheelEvent *event) { if (event->angleDelta().y() > 0) { if (m_targetTemperature + 10 > upperBound()) { m_currentTemperatureTextFromEditor = QString::number(upperBound()); } else { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature + 10); } } else if (event->angleDelta().y() < 0) { if (m_targetTemperature - 10 < lowerBound()) { m_currentTemperatureTextFromEditor = QString::number(lowerBound()); } else { m_currentTemperatureTextFromEditor = QString::number(m_targetTemperature - 10); } } if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); resetTimer(); update(); } event->accept(); } void ThermoWidget::focusOutEvent(QFocusEvent *event) { if (m_targetTemperature != m_currentTemperatureTextFromEditor.toInt()) { m_targetTemperature = m_currentTemperatureTextFromEditor.toInt(); resetTimer(); event->accept(); } m_cursorTimer->stop(); m_paintCursor = false; update(); } void ThermoWidget::focusInEvent(QFocusEvent *event) { m_cursorTimer->start(1000); event->accept(); } void ThermoWidget::paintEvent(QPaintEvent *event) { QwtDial::paintEvent(event); const QString currentText = QString::number(m_currentTemperature); QFontMetrics fm(font()); const int targetWidth = fm.width(m_currentTemperatureTextFromEditor); const int currentWidth = fm.width(currentText); const int nameWidth = fm.width(m_name); const int wWidth = fm.width('W'); const int cursorWidth = fm.width('0'); const int height = fm.height(); const int halfWidth = geometry().width() / 2; const int xposTarget = int(halfWidth - (targetWidth / 2)); const int xposCurrent = int(halfWidth - (currentWidth / 2)); const int xposName = halfWidth - (nameWidth / 2); const int xposCursor = xposTarget + (cursorWidth * m_cursorPos); int ypos = geometry().height() / 2 + height * 2; QPainter p(this); QColor color = palette().color(QPalette::Text); //draw a box to put our target into as a user hint. p.fillRect(QRect(int(halfWidth - wWidth), int(ypos - (height * 0.66)), int(wWidth * 2), int(height * 0.9)), palette().color(QPalette::AlternateBase)); if (m_paintCursor) { p.setPen(palette().color(QPalette::Text)); p.drawText(xposCursor, ypos, QChar('_')); } p.setPen(Qt::red); p.drawText(xposTarget, ypos, m_currentTemperatureTextFromEditor); ypos += height + 2; p.setPen(color); p.drawText(xposCurrent, ypos, QString::number(m_currentTemperature)); p.setPen(color); if (size().height() <= height * 6.5 && innerRect().width() <= nameWidth * 4) { p.drawText(xposName, 0 + height, m_name); } else if (size().height() >= height * 8) { p.drawText(xposName, ypos + height + 2, m_name); } else { p.drawText(xposName, geometry().height() / 2 - 12, m_name); } } void ThermoWidget::drawNeedle(QPainter *painter, const QPointF ¢er, double radius, double dir, QPalette::ColorGroup colorGroup) const { Q_UNUSED(dir); //save a copy of radius as int to avoid casting it several times. int radiusAsInt = int(radius); const double relativePercent = upperBound() - lowerBound(); const double currentTemperaturePercent = (m_currentTemperature - lowerBound()) / relativePercent; const double targetTemperaturePercent = (m_targetTemperature - lowerBound()) / relativePercent; const double currentTemperatureAngle = (maxScaleArc() - minScaleArc()) * currentTemperaturePercent + minScaleArc(); const double targetTemperatureAngle = (maxScaleArc() - minScaleArc()) * targetTemperaturePercent + minScaleArc(); // Qt coordinates and Qwt coordinates differ. // the "begin" of our coordinates in Qt: -130 // the "span" of our coordinates in Qt: -180 // Negative values means clockwise in Qt dialect. const int qtBeginAngle = -130; const int coolZone = int (- (targetTemperatureAngle - minScaleArc())); int yPos = geometry().height() / 2 - radiusAsInt; int xPos = geometry().width() / 2 - radiusAsInt; QRadialGradient grad(center, radius); grad.setColorAt(0.75, QColor(0, 0, 0, 0)); grad.setColorAt(0.85, QColor(255, 0, 0, 196)); grad.setColorAt(0.95, QColor(255, 110, 60, 196)); painter->setBrush(grad); painter->drawPie(xPos, yPos, radiusAsInt * 2, radiusAsInt * 2, qtBeginAngle * 16, coolZone * 16); m_targetTemperatureNeedle->draw(painter, center, radius * 1.3, 360 - targetTemperatureAngle - origin(), colorGroup); m_currentTemperatureNeedle->draw(painter, center, radius, 360 - currentTemperatureAngle - origin(), colorGroup); } void ThermoWidget::setCurrentTemperature(double temperature) { if (!isEqual(m_currentTemperature, temperature)) { m_currentTemperature = temperature; update(); } } void ThermoWidget::setTargetTemperature(int temperature) { if (m_targetTemperature != temperature) { m_currentTemperatureTextFromEditor = QString::number(temperature); m_targetTemperature = temperature; resetTimer(); update(); } } void ThermoWidget::resetTimer() { m_tempChangedTimer->start(500); } bool ThermoWidget::isEqual(double a, double b) { //qFuzzyCompare always returns false if a || b ==0 if (qFuzzyIsNull(a) || qFuzzyIsNull(b)) { if (a < 0.0 || b < 0.0) { //One number is 0 and the other negative //to prevent a issue if a or b == -1 and the other 0 //we will subtract one from each value a -= 1; b -= 1; } else { a += 1; b += 1; } } return qFuzzyCompare(a, b); }