File indexing completed on 2024-10-13 10:08:20
0001 /* AtCore Test Client 0002 * SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0003 * SPDX-FileCopyrightText: 2016-2018 Patrick José Pereira <patrickjp@kde.org> 0004 * SPDX-FileCopyrightText: 2016-2017, 2019 Lays Rodrigues <lays.rodrigues@kde.org> 0005 * SPDX-FileCopyrightText: 2016-2020 Chris Rizzitello <rizzitello@kde.org> 0006 * SPDX-FileCopyrightText: 2016 Tomaz Canabrava <tcanabrava@kde.org> 0007 */ 0008 0009 #include <QFileDialog> 0010 #include <QLoggingCategory> 0011 #include <QMessageBox> 0012 #include <QSerialPortInfo> 0013 #include <QTextStream> 0014 #include <QTimer> 0015 0016 #include "about.h" 0017 #include "gcodecommands.h" 0018 #include "machineinfo.h" 0019 #include "mainwindow.h" 0020 #include "seriallayer.h" 0021 0022 Q_LOGGING_CATEGORY(TESTCLIENT_MAINWINDOW, "org.kde.atelier.core") 0023 0024 int MainWindow::fanCount = 4; 0025 0026 MainWindow::MainWindow(QWidget *parent) 0027 : QMainWindow(parent) 0028 , core(new AtCore(this)) 0029 { 0030 setWindowTitle(tr("AtCore - Test Client")); 0031 setWindowIcon(QIcon(QStringLiteral(":/icon/windowIcon"))); 0032 QCoreApplication::setApplicationVersion(core->version()); 0033 initMenu(); 0034 initStatusBar(); 0035 initWidgets(); 0036 0037 connect(core, &AtCore::atcoreMessage, logWidget, &LogWidget::appendLog); 0038 logWidget->appendLog(tr("Attempting to locate Serial Ports")); 0039 core->setSerialTimerInterval(1000); 0040 0041 connect(core, &AtCore::stateChanged, this, &MainWindow::printerStateChanged); 0042 connect(core, &AtCore::portsChanged, this, &MainWindow::locateSerialPort); 0043 connect(core, &AtCore::sdCardFileListChanged, sdWidget, &SdWidget::updateFilelist); 0044 connect(core, &AtCore::autoTemperatureReportChanged, this, &MainWindow::updateAutoTemperatureReport); 0045 0046 comboPort->setFocus(Qt::OtherFocusReason); 0047 0048 if (comboProfile->count() == 0) { 0049 QMessageBox::information(this, tr("AtCore First Run"), tr("No Profiles Detected, use the Profile Manager to create one.")); 0050 profileDock->setVisible(true); 0051 move(profileDock->geometry().center()); 0052 profileDock->move(geometry().center()); 0053 profileDock->activateWindow(); 0054 } 0055 } 0056 0057 void MainWindow::initMenu() 0058 { 0059 QMenu *menuFile = new QMenu(tr("File")); 0060 QAction *actionQuit = new QAction(style()->standardIcon(QStyle::SP_DialogCloseButton), tr("Quit")); 0061 connect(actionQuit, &QAction::triggered, this, &MainWindow::close); 0062 menuFile->addAction(actionQuit); 0063 0064 menuView = new QMenu(tr("View")); 0065 QAction *actionShowDockTitles = new QAction(tr("Show Dock Titles")); 0066 actionShowDockTitles->setCheckable(true); 0067 actionShowDockTitles->setChecked(true); 0068 connect(actionShowDockTitles, &QAction::toggled, this, &MainWindow::toggleDockTitles); 0069 menuView->addAction(actionShowDockTitles); 0070 0071 QMenu *menuHelp = new QMenu(tr("Help")); 0072 QAction *actionAbout = new QAction(tr("About")); 0073 actionAbout->setShortcut(QKeySequence(Qt::Key_F1)); 0074 connect(actionAbout, &QAction::triggered, this, [] { 0075 auto *dialog = new About; 0076 dialog->exec(); 0077 }); 0078 menuHelp->addAction(actionAbout); 0079 0080 menuBar()->addMenu(menuFile); 0081 menuBar()->addMenu(menuView); 0082 menuBar()->addMenu(menuHelp); 0083 } 0084 0085 void MainWindow::initStatusBar() 0086 { 0087 statusWidget = new StatusWidget; 0088 connect(statusWidget, &StatusWidget::stopPressed, core, &AtCore::stop); 0089 connect(core, &AtCore::printProgressChanged, statusWidget, &StatusWidget::updatePrintProgress); 0090 connect(core, &AtCore::sdMountChanged, statusWidget, &StatusWidget::setSD); 0091 statusBar()->addPermanentWidget(statusWidget, 100); 0092 } 0093 0094 void MainWindow::initWidgets() 0095 { 0096 // Make the Docks 0097 makeCommandDock(); 0098 makePrintDock(); 0099 makeTempTimelineDock(); 0100 makeLogDock(); 0101 makeConnectDock(); 0102 makeMoveDock(); 0103 makeTempControlsDock(); 0104 makeSdDock(); 0105 makeProfileDock(); 0106 0107 setDangeriousDocksDisabled(true); 0108 0109 setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North); 0110 setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North); 0111 tabifyDockWidget(moveDock, tempControlsDock); 0112 tabifyDockWidget(moveDock, sdDock); 0113 moveDock->raise(); 0114 0115 tabifyDockWidget(connectDock, printDock); 0116 tabifyDockWidget(connectDock, commandDock); 0117 connectDock->raise(); 0118 0119 tabifyDockWidget(logDock, profileDock); 0120 logDock->raise(); 0121 setCentralWidget(nullptr); 0122 0123 // More Gui stuff 0124 // hide the printing progress bar. 0125 statusWidget->showPrintArea(false); 0126 } 0127 0128 void MainWindow::makeCommandDock() 0129 { 0130 commandWidget = new CommandWidget; 0131 // Connect the commandPressed signal 0132 connect(commandWidget, &CommandWidget::commandPressed, core, &AtCore::pushCommand); 0133 // Connect the messagePressed signal 0134 connect(commandWidget, &CommandWidget::messagePressed, core, &AtCore::showMessage); 0135 // Create the dock, and set the Widget. 0136 commandDock = new QDockWidget(tr("Commands"), this); 0137 commandDock->setWidget(commandWidget); 0138 0139 // Push the toggle view action into our view menu 0140 menuView->insertAction(nullptr, commandDock->toggleViewAction()); 0141 0142 // Place the Dock into a DockWidget Area. 0143 // Failure todo this will create some odd side effects at runtime 0144 addDockWidget(Qt::LeftDockWidgetArea, commandDock); 0145 } 0146 0147 void MainWindow::makePrintDock() 0148 { 0149 printWidget = new PrintWidget; 0150 connect(printWidget, &PrintWidget::printPressed, this, &MainWindow::printPBClicked); 0151 connect(printWidget, &PrintWidget::emergencyStopPressed, core, &AtCore::emergencyStop); 0152 connect(printWidget, &PrintWidget::fanSpeedChanged, core, &AtCore::setFanSpeed); 0153 connect(printWidget, &PrintWidget::printSpeedChanged, core, &AtCore::setPrinterSpeed); 0154 connect(printWidget, &PrintWidget::flowRateChanged, core, &AtCore::setFlowRate); 0155 0156 printDock = new QDockWidget(tr("Print"), this); 0157 printDock->setWidget(printWidget); 0158 0159 menuView->insertAction(nullptr, printDock->toggleViewAction()); 0160 addDockWidget(Qt::LeftDockWidgetArea, printDock); 0161 } 0162 0163 void MainWindow::makeTempTimelineDock() 0164 { 0165 plotWidget = new PlotWidget; 0166 // make and connect our plots in the widget. 0167 plotWidget->addPlot(tr("Actual Bed")); 0168 connect(core->temperature(), &Temperature::bedTemperatureChanged, this, [this] { 0169 float temp = core->temperature()->bedTemperature(); 0170 checkTemperature(0x00, 0, temp); 0171 plotWidget->appendPoint(tr("Actual Bed"), temp); 0172 }); 0173 0174 plotWidget->addPlot(tr("Target Bed")); 0175 connect(core->temperature(), &Temperature::bedTargetTemperatureChanged, this, [this] { 0176 float temp = core->temperature()->bedTargetTemperature(); 0177 checkTemperature(0x01, 0, temp); 0178 plotWidget->appendPoint(tr("Target Bed"), temp); 0179 }); 0180 0181 plotWidget->addPlot(tr("Actual Ext.1")); 0182 connect(core->temperature(), &Temperature::extruderTemperatureChanged, this, [this] { 0183 float temp = core->temperature()->extruderTemperature(); 0184 checkTemperature(0x02, 0, temp); 0185 plotWidget->appendPoint(tr("Actual Ext.1"), temp); 0186 }); 0187 0188 plotWidget->addPlot(tr("Target Ext.1")); 0189 connect(core->temperature(), &Temperature::extruderTargetTemperatureChanged, this, [this] { 0190 float temp = core->temperature()->extruderTargetTemperature(); 0191 checkTemperature(0x03, 0, temp); 0192 plotWidget->appendPoint(tr("Target Ext.1"), temp); 0193 }); 0194 0195 auto timerLayout = new QHBoxLayout; 0196 auto lblTimer = new QLabel(tr("Seconds Between Temperature Checks"), this); 0197 sbTemperatureTimer = new QSpinBox(this); 0198 sbTemperatureTimer->setRange(0, 90); 0199 connect(sbTemperatureTimer, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int value) { core->setTemperatureTimerInterval(value * 1000); }); 0200 connect(core, &AtCore::temperatureTimerIntervalChanged, this, [this](int value) { 0201 if (value != sbTemperatureTimer->value()) { 0202 sbTemperatureTimer->blockSignals(true); 0203 sbTemperatureTimer->setValue(value / 1000); 0204 sbTemperatureTimer->blockSignals(false); 0205 } 0206 }); 0207 0208 timerLayout->addWidget(lblTimer); 0209 timerLayout->addWidget(sbTemperatureTimer); 0210 0211 auto tempDockLayout = new QVBoxLayout; 0212 tempDockLayout->addWidget(plotWidget); 0213 tempDockLayout->addLayout(timerLayout); 0214 0215 auto tempDockMainWidget = new QWidget(this); 0216 tempDockMainWidget->setLayout(tempDockLayout); 0217 0218 tempTimelineDock = new QDockWidget(tr("Temperature Timeline"), this); 0219 tempTimelineDock->setWidget(tempDockMainWidget); 0220 menuView->insertAction(nullptr, tempTimelineDock->toggleViewAction()); 0221 addDockWidget(Qt::RightDockWidgetArea, tempTimelineDock); 0222 } 0223 0224 void MainWindow::makeLogDock() 0225 { 0226 logWidget = new LogWidget(new QTemporaryFile(QDir::tempPath() + QStringLiteral("/AtCore_"))); 0227 logDock = new QDockWidget(tr("Session Log"), this); 0228 logDock->setWidget(logWidget); 0229 0230 menuView->insertAction(nullptr, logDock->toggleViewAction()); 0231 addDockWidget(Qt::RightDockWidgetArea, logDock); 0232 } 0233 0234 void MainWindow::makeConnectDock() 0235 { 0236 auto *mainLayout = new QVBoxLayout; 0237 auto *newLabel = new QLabel(tr("Port:")); 0238 0239 comboPort = new QComboBox; 0240 comboPort->setEditable(true); 0241 0242 auto *hBoxLayout = new QHBoxLayout; 0243 hBoxLayout->addWidget(newLabel); 0244 hBoxLayout->addWidget(comboPort, 75); 0245 mainLayout->addLayout(hBoxLayout); 0246 0247 comboProfile = new QComboBox(); 0248 comboProfile->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); 0249 comboProfile->addItems(MachineInfo::instance()->profileNames()); 0250 0251 connect(MachineInfo::instance(), &MachineInfo::profilesChanged, this, [this] { 0252 int index = comboProfile->currentIndex(); 0253 comboProfile->clear(); 0254 comboProfile->addItems(MachineInfo::instance()->profileNames()); 0255 comboProfile->setCurrentIndex(std::min<int>(index, comboProfile->count() - 1)); 0256 }); 0257 0258 newLabel = new QLabel(tr("Profile:")); 0259 auto profileLayout = new QHBoxLayout(); 0260 profileLayout->addWidget(newLabel); 0261 profileLayout->addWidget(comboProfile); 0262 mainLayout->addLayout(profileLayout); 0263 0264 cbReset = new QCheckBox(tr("Attempt to stop Reset on connect")); 0265 if (MachineInfo::instance()->profileNames().isEmpty()) { 0266 cbReset->setHidden(true); 0267 } else { 0268 cbReset->setHidden(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); 0269 } 0270 mainLayout->addWidget(cbReset); 0271 0272 connect(comboProfile, &QComboBox::currentTextChanged, this, [this](const QString ¤tText) { 0273 cbReset->setHidden(MachineInfo::instance()->readKey(currentText, MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); 0274 }); 0275 0276 buttonConnect = new QPushButton(tr("Connect")); 0277 connect(buttonConnect, &QPushButton::clicked, this, &MainWindow::connectPBClicked); 0278 0279 connectionTimer = new QTimer(this); 0280 connectionTimer->setInterval(20000); 0281 connectionTimer->setSingleShot(true); 0282 connect(connectionTimer, &QTimer::timeout, this, [this] { 0283 Q_EMIT buttonConnect->clicked(); 0284 QMessageBox::critical(this, tr("Connection Error"), tr("Your machine did not respond after 20 seconds.\n\nBefore connecting again check that your printer is on and your are connecting using the correct BAUD Rate for your device.")); 0285 }); 0286 0287 mainLayout->addWidget(buttonConnect); 0288 0289 auto *dockContents = new QWidget; 0290 dockContents->setLayout(mainLayout); 0291 0292 connectDock = new QDockWidget(tr("Connect"), this); 0293 connectDock->setWidget(dockContents); 0294 0295 menuView->insertAction(nullptr, connectDock->toggleViewAction()); 0296 addDockWidget(Qt::LeftDockWidgetArea, connectDock); 0297 } 0298 0299 void MainWindow::makeMoveDock() 0300 { 0301 movementWidget = new MovementWidget(this); 0302 0303 connect(movementWidget, &MovementWidget::homeAllPressed, this, [this] { 0304 logWidget->appendLog(tr("Home All")); 0305 core->home(); 0306 }); 0307 0308 connect(movementWidget, &MovementWidget::homeXPressed, this, [this] { 0309 logWidget->appendLog(tr("Home X")); 0310 core->home(AtCore::X); 0311 }); 0312 0313 connect(movementWidget, &MovementWidget::homeYPressed, this, [this] { 0314 logWidget->appendLog(tr("Home Y")); 0315 core->home(AtCore::Y); 0316 }); 0317 0318 connect(movementWidget, &MovementWidget::homeZPressed, this, [this] { 0319 logWidget->appendLog(tr("Home Z")); 0320 core->home(AtCore::Z); 0321 }); 0322 0323 connect(movementWidget, &MovementWidget::absoluteMove, this, [this](const QLatin1Char &axis, const double &value) { 0324 logWidget->appendLog(GCode::description(GCode::G1)); 0325 core->move(axis, value); 0326 }); 0327 0328 connect(movementWidget, &MovementWidget::disableMotorsPressed, this, [this] { core->disableMotors(0); }); 0329 0330 connect(movementWidget, &MovementWidget::relativeMove, this, [this](const QLatin1Char &axis, const double &value) { 0331 core->setRelativePosition(); 0332 core->move(axis, value); 0333 core->setAbsolutePosition(); 0334 }); 0335 0336 connect(movementWidget, &MovementWidget::unitsChanged, this, [this](int units) { 0337 auto selection = static_cast<AtCore::UNITS>(units); 0338 core->setUnits(selection); 0339 }); 0340 0341 moveDock = new QDockWidget(tr("Movement"), this); 0342 moveDock->setWidget(movementWidget); 0343 0344 menuView->insertAction(nullptr, moveDock->toggleViewAction()); 0345 addDockWidget(Qt::LeftDockWidgetArea, moveDock); 0346 } 0347 0348 void MainWindow::makeTempControlsDock() 0349 { 0350 temperatureWidget = new TemperatureWidget; 0351 connect(temperatureWidget, &TemperatureWidget::bedTempChanged, core, &AtCore::setBedTemp); 0352 connect(temperatureWidget, &TemperatureWidget::extTempChanged, core, &AtCore::setExtruderTemp); 0353 0354 tempControlsDock = new QDockWidget(tr("Temperatures"), this); 0355 tempControlsDock->setWidget(temperatureWidget); 0356 menuView->insertAction(nullptr, tempControlsDock->toggleViewAction()); 0357 addDockWidget(Qt::LeftDockWidgetArea, tempControlsDock); 0358 } 0359 0360 void MainWindow::makeSdDock() 0361 { 0362 sdWidget = new SdWidget; 0363 connect(sdWidget, &SdWidget::requestSdList, core, &AtCore::sdFileList); 0364 0365 connect(sdWidget, &SdWidget::printSdFile, this, [this](const QString &fileName) { 0366 if (fileName.isEmpty()) { 0367 QMessageBox::information(this, tr("Print Error"), tr("You must Select a file from the list")); 0368 } else { 0369 core->print(fileName, true); 0370 } 0371 }); 0372 0373 connect(sdWidget, &SdWidget::deleteSdFile, this, [this](const QString &fileName) { 0374 if (fileName.isEmpty()) { 0375 QMessageBox::information(this, tr("Delete Error"), tr("You must Select a file from the list")); 0376 } else { 0377 core->sdDelete(fileName); 0378 } 0379 }); 0380 0381 sdDock = new QDockWidget(tr("Sd Card"), this); 0382 sdDock->setWidget(sdWidget); 0383 menuView->insertAction(nullptr, sdDock->toggleViewAction()); 0384 addDockWidget(Qt::LeftDockWidgetArea, sdDock); 0385 } 0386 0387 void MainWindow::makeProfileDock() 0388 { 0389 profileManager = new ProfileManager(); 0390 profileDock = new QDockWidget(tr("Profile Manager"), this); 0391 profileDock->setWidget(profileManager); 0392 menuView->insertAction(nullptr, profileDock->toggleViewAction()); 0393 addDockWidget(Qt::RightDockWidgetArea, profileDock); 0394 profileDock->setFloating(true); 0395 profileDock->setVisible(false); 0396 } 0397 0398 void MainWindow::closeEvent(QCloseEvent *event) 0399 { 0400 core->close(); 0401 event->accept(); 0402 } 0403 0404 void MainWindow::checkTemperature(uint sensorType, uint number, float temp) 0405 { 0406 QString msg; 0407 switch (sensorType) { 0408 case 0x00: // bed 0409 msg = QString::fromLatin1("Bed Temperature"); 0410 break; 0411 0412 case 0x01: // bed target 0413 msg = QString::fromLatin1("Bed Target Temperature"); 0414 break; 0415 0416 case 0x02: // extruder 0417 msg = QString::fromLatin1("Extruder[%1] Temperature").arg(QString::number(number)); 0418 break; 0419 0420 case 0x03: // extruder target 0421 msg = QString::fromLatin1("Extruder[%1] Target Temperature").arg(QString::number(number)); 0422 break; 0423 0424 case 0x04: // enclosure 0425 msg = QString::fromLatin1("Enclosure Temperature"); 0426 break; 0427 0428 case 0x05: // enclosure target 0429 msg = QString::fromLatin1("Enclosure Target Temperature"); 0430 break; 0431 } 0432 0433 msg.append(QString::fromLatin1(": %1").arg(QString::number(double(temp), 'f', 2))); 0434 logWidget->appendLog(msg); 0435 } 0436 /** 0437 * @brief MainWindow::locateSerialPort 0438 * Locate all active serial ports on the computer and add to the list 0439 * of serial ports 0440 */ 0441 void MainWindow::locateSerialPort(const QStringList &ports) 0442 { 0443 comboPort->clear(); 0444 if (!ports.isEmpty()) { 0445 comboPort->addItems(ports); 0446 logWidget->appendLog(tr("Found %1 Ports").arg(QString::number(ports.count()))); 0447 } else { 0448 QString portError(tr("No available ports! Please connect a serial device to continue!")); 0449 if (!logWidget->endsWith(portError)) { 0450 logWidget->appendLog(portError); 0451 } 0452 } 0453 } 0454 0455 void MainWindow::connectPBClicked() 0456 { 0457 if (core->state() == AtCore::DISCONNECTED) { 0458 int baud = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::BAUDRATE).toInt(); 0459 int xMax = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::XMAX).toInt(); 0460 int yMax = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::YMAX).toInt(); 0461 int zMax = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::ZMAX).toInt(); 0462 QString plugin = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::FIRMWARE).toString(); 0463 if (core->newConnection(comboPort->currentText(), baud, plugin, cbReset->isChecked())) { 0464 connect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); 0465 connect(core, &AtCore::pushedCommand, logWidget, &LogWidget::appendSLog); 0466 logWidget->appendLog(tr("Serial connected")); 0467 movementWidget->setAxisMax(xMax, yMax, zMax); 0468 if ((!plugin.contains(QStringLiteral("Auto-Detect"))) && cbReset->isChecked()) { 0469 // Wait a few seconds after connect to avoid the normal errors 0470 QTimer::singleShot(5000, core, &AtCore::sdCardPrintStatus); 0471 } 0472 } 0473 } else { 0474 disconnect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); 0475 disconnect(core, &AtCore::pushedCommand, logWidget, &LogWidget::appendSLog); 0476 core->closeConnection(); 0477 core->setState(AtCore::DISCONNECTED); 0478 logWidget->appendLog(tr("Disconnected")); 0479 } 0480 } 0481 0482 void MainWindow::printPBClicked() 0483 { 0484 QString fileName; 0485 switch (core->state()) { 0486 case AtCore::DISCONNECTED: 0487 QMessageBox::information(this, tr("Error"), tr("Not Connected To a Printer")); 0488 break; 0489 0490 case AtCore::CONNECTING: 0491 QMessageBox::information( 0492 this, 0493 tr("Error"), 0494 tr(" A Firmware Plugin was not loaded!\n Please send the command M115 and let us know what your firmware returns, so we can improve our firmware detection. Edit your profile to use \"marlin\" and try again.")); 0495 break; 0496 0497 case AtCore::IDLE: 0498 fileName = QFileDialog::getOpenFileName(this, tr("Select a file to print"), QDir::homePath(), tr("*.gcode")); 0499 if (fileName.isNull()) { 0500 logWidget->appendLog(tr("No File Selected")); 0501 } else { 0502 logWidget->appendLog(tr("Print: %1").arg(fileName)); 0503 core->print(fileName); 0504 } 0505 break; 0506 0507 case AtCore::BUSY: 0508 core->pause(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::POSTPAUSE).toString()); 0509 break; 0510 0511 case AtCore::PAUSE: 0512 core->resume(); 0513 break; 0514 0515 default: 0516 qCDebug(TESTCLIENT_MAINWINDOW) << "ERROR / STOP unhandled."; 0517 } 0518 } 0519 0520 void MainWindow::printerStateChanged(AtCore::STATES state) 0521 { 0522 QString stateString; 0523 switch (state) { 0524 case AtCore::IDLE: 0525 if (connectionTimer->isActive()) { 0526 core->setAutoTemperatureReport(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::AUTOTEMPREPORT).toBool()); 0527 connectionTimer->stop(); 0528 } 0529 buttonConnect->setText(tr("Disconnect")); 0530 printWidget->setPrintText(tr("Print File")); 0531 stateString = tr("Connected to ") + core->connectedPort(); 0532 sdDock->setVisible(core->firmwarePlugin()->isSdSupported()); 0533 break; 0534 0535 case AtCore::STARTPRINT: 0536 stateString = tr("START PRINT"); 0537 printWidget->setPrintText(tr("Pause Print")); 0538 statusWidget->showPrintArea(true); 0539 break; 0540 0541 case AtCore::FINISHEDPRINT: 0542 stateString = tr("Finished Print"); 0543 printWidget->setPrintText(tr("Print File")); 0544 statusWidget->showPrintArea(false); 0545 break; 0546 0547 case AtCore::PAUSE: 0548 stateString = tr("Paused"); 0549 printWidget->setPrintText(tr("Resume Print")); 0550 break; 0551 0552 case AtCore::BUSY: 0553 stateString = tr("Printing"); 0554 printWidget->setPrintText(tr("Pause Print")); 0555 break; 0556 0557 case AtCore::DISCONNECTED: 0558 if (connectionTimer->isActive()) { 0559 connectionTimer->stop(); 0560 } 0561 sbTemperatureTimer->setValue(0); 0562 stateString = QStringLiteral("Not Connected"); 0563 buttonConnect->setText(tr("Connect")); 0564 setConnectionWidgetsEnabled(true); 0565 setDangeriousDocksDisabled(true); 0566 break; 0567 0568 case AtCore::CONNECTING: 0569 stateString = QStringLiteral("Connecting"); 0570 buttonConnect->setText(tr("Abort")); 0571 connectionTimer->start(); 0572 setConnectionWidgetsEnabled(false); 0573 setDangeriousDocksDisabled(false); 0574 break; 0575 0576 case AtCore::STOP: 0577 stateString = tr("Stopping Print"); 0578 break; 0579 0580 case AtCore::ERRORSTATE: 0581 stateString = tr("Command ERROR"); 0582 break; 0583 } 0584 statusWidget->setState(stateString); 0585 } 0586 0587 void MainWindow::toggleDockTitles(bool checked) 0588 { 0589 if (checked) { 0590 delete connectDock->titleBarWidget(); 0591 connectDock->setTitleBarWidget(nullptr); 0592 delete logDock->titleBarWidget(); 0593 logDock->setTitleBarWidget(nullptr); 0594 delete tempTimelineDock->titleBarWidget(); 0595 tempTimelineDock->setTitleBarWidget(nullptr); 0596 delete commandDock->titleBarWidget(); 0597 commandDock->setTitleBarWidget(nullptr); 0598 delete moveDock->titleBarWidget(); 0599 moveDock->setTitleBarWidget(nullptr); 0600 delete tempControlsDock->titleBarWidget(); 0601 tempControlsDock->setTitleBarWidget(nullptr); 0602 delete printDock->titleBarWidget(); 0603 printDock->setTitleBarWidget(nullptr); 0604 delete sdDock->titleBarWidget(); 0605 sdDock->setTitleBarWidget(nullptr); 0606 delete profileDock->titleBarWidget(); 0607 profileDock->setTitleBarWidget(nullptr); 0608 } else { 0609 if (!connectDock->isFloating()) { 0610 connectDock->setTitleBarWidget(new QWidget()); 0611 } 0612 if (!logDock->isFloating()) { 0613 logDock->setTitleBarWidget(new QWidget()); 0614 } 0615 if (!tempTimelineDock->isFloating()) { 0616 tempTimelineDock->setTitleBarWidget(new QWidget()); 0617 } 0618 if (!commandDock->isFloating()) { 0619 commandDock->setTitleBarWidget(new QWidget()); 0620 } 0621 if (!moveDock->isFloating()) { 0622 moveDock->setTitleBarWidget(new QWidget()); 0623 } 0624 if (!tempControlsDock->isFloating()) { 0625 tempControlsDock->setTitleBarWidget(new QWidget()); 0626 } 0627 if (!printDock->isFloating()) { 0628 printDock->setTitleBarWidget(new QWidget()); 0629 } 0630 if (!sdDock->isFloating()) { 0631 sdDock->setTitleBarWidget(new QWidget()); 0632 } 0633 if (!profileDock->isFloating()) { 0634 profileDock->setTitleBarWidget(new QWidget()); 0635 } 0636 } 0637 } 0638 0639 void MainWindow::setDangeriousDocksDisabled(bool disabled) 0640 { 0641 commandDock->widget()->setDisabled(disabled); 0642 moveDock->widget()->setDisabled(disabled); 0643 tempControlsDock->widget()->setDisabled(disabled); 0644 printDock->widget()->setDisabled(disabled); 0645 sdDock->widget()->setDisabled(disabled); 0646 0647 if (!disabled) { 0648 temperatureWidget->updateExtruderCount(core->extruderCount()); 0649 printWidget->updateFanCount(fanCount); 0650 } else { 0651 printWidget->setPrintText(tr("Print File")); 0652 statusWidget->showPrintArea(false); 0653 } 0654 } 0655 0656 void MainWindow::setConnectionWidgetsEnabled(bool enabled) 0657 { 0658 comboProfile->setEnabled(enabled); 0659 comboPort->setEnabled(enabled); 0660 } 0661 0662 void MainWindow::updateAutoTemperatureReport(bool autoReport) 0663 { 0664 disconnect(sbTemperatureTimer, QOverload<int>::of(&QSpinBox::valueChanged), this, {}); 0665 disconnect(core, &AtCore::temperatureTimerIntervalChanged, this, {}); 0666 disconnect(core, &AtCore::autoCheckTemperatureIntervalChanged, this, {}); 0667 0668 if (autoReport) { 0669 connect(sbTemperatureTimer, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int value) { core->setAutoCheckTemperatureInterval(value); }); 0670 connect(core, &AtCore::autoCheckTemperatureIntervalChanged, this, [this](int value) { 0671 if (value != sbTemperatureTimer->value()) { 0672 sbTemperatureTimer->blockSignals(true); 0673 sbTemperatureTimer->setValue(value); 0674 sbTemperatureTimer->blockSignals(false); 0675 } 0676 }); 0677 } else { 0678 connect(sbTemperatureTimer, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int value) { core->setTemperatureTimerInterval(value * 1000); }); 0679 connect(core, &AtCore::temperatureTimerIntervalChanged, this, [this](int value) { 0680 if (value != sbTemperatureTimer->value()) { 0681 sbTemperatureTimer->blockSignals(true); 0682 sbTemperatureTimer->setValue(value / 1000); 0683 sbTemperatureTimer->blockSignals(false); 0684 } 0685 }); 0686 } 0687 }