diff --git a/src/core/atcore.cpp b/src/core/atcore.cpp index 7f246f9..379a7ae 100644 --- a/src/core/atcore.cpp +++ b/src/core/atcore.cpp @@ -1,782 +1,782 @@ /* AtCore Copyright (C) <2016> Authors: Tomaz Canabrava Chris Rizzitello Patrick José Pereira Lays Rodrigues This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include #include #include #include "atcore.h" #include "atcore_version.h" #include "seriallayer.h" #include "gcodecommands.h" #include "printthread.h" #include "atcore_default_folders.h" Q_LOGGING_CATEGORY(ATCORE_PLUGIN, "org.kde.atelier.core.plugin") Q_LOGGING_CATEGORY(ATCORE_CORE, "org.kde.atelier.core") /** * @brief The AtCorePrivate struct * Provides a private data set for atcore. */ struct AtCorePrivate { IFirmware *firmwarePlugin = nullptr;//!< @param firmwarePlugin: pointer to firmware plugin SerialLayer *serial = nullptr; //!< @param serial: pointer to the serial layer QPluginLoader pluginLoader; //!< @param pluginLoader: QPluginLoader QMap plugins; //!< @param plugins: Map of plugins name / path QByteArray lastMessage; //!< @param lastMessage: lastMessage from the printer int extruderCount = 1; //!< @param extruderCount: extruder count Temperature temperature; //!< @param temperature: Temperature object QStringList commandQueue; //!< @param commandQueue: the list of commands to send to the printer bool ready = false; //!< @param ready: True if printer is ready for a command QTimer *tempTimer = nullptr; //!< @param tempTimer: timer connected to the checkTemperature function float percentage; //!< @param percentage: print job percent QByteArray posString; //!< @param posString: stored string from last M114 return AtCore::STATES printerState; //!< @param printerState: State of the Printer QStringList serialPorts; //!< @param seralPorts: Detected serial Ports QTimer *serialTimer = nullptr; //!< @param serialTimer: Timer connected to locateSerialPorts bool sdCardMounted = false; //!< @param sdCardMounted: True if Sd Card is mounted. bool sdCardReadingFileList = false; //!< @param sdCardReadingFileList: True while getting file names from sd card bool sdCardPrinting = false; //!< @param sdCardPrinting: True if currently printing from sd card. QString sdCardFileName; //!< @param sdCardFileName: name of file being used from sd card. QStringList sdCardFileList; //!< @param sdCardFileList: List of files on sd card. }; AtCore::AtCore(QObject *parent) : QObject(parent), d(new AtCorePrivate) { //Register MetaTypes qRegisterMetaType("AtCore::STATES"); setState(AtCore::DISCONNECTED); //Create and start the timer that checks for temperature. d->tempTimer = new QTimer(this); d->tempTimer->setInterval(5000); d->tempTimer->setSingleShot(false); //Attempt to find our plugins qCDebug(ATCORE_PLUGIN) << "Detecting Plugin path"; for (const auto &path : AtCoreDirectories::pluginDir) { qCDebug(ATCORE_PLUGIN) << "Checking: " << path; QMap tempMap = findFirmwarePlugins(path); if (!tempMap.isEmpty()) { d->plugins = tempMap; return; } } setState(AtCore::DISCONNECTED); } QString AtCore::version() const { QString versionString = QString::fromLatin1(ATCORE_VERSION_STRING); #if defined GIT_REVISION if (!QStringLiteral(GIT_REVISION).isEmpty()) { versionString.append(QString::fromLatin1("-%1").arg(QStringLiteral(GIT_REVISION))); } #endif return versionString; } SerialLayer *AtCore::serial() const { return d->serial; } IFirmware *AtCore::firmwarePlugin() const { return d->firmwarePlugin; } void AtCore::close() { exit(0); } Temperature &AtCore::temperature() const { return d->temperature; } void AtCore::findFirmware(const QByteArray &message) { if (state() == AtCore::DISCONNECTED) { qCWarning(ATCORE_CORE) << tr("Cant find firwmware, serial not connected!"); return; } if (state() == AtCore::CONNECTING) { //Most Firmwares will return "start" on connect, some return their firmware name. if (message.contains("start")) { qCDebug(ATCORE_CORE) << "Waiting requestFirmware."; QTimer::singleShot(500, this, &AtCore::requestFirmware); return; } else if (message.contains("Grbl")) { loadFirmwarePlugin(QString::fromLatin1("grbl")); return; } else if (message.contains("Smoothie")) { loadFirmwarePlugin(QString::fromLatin1("smoothie")); return; } qCDebug(ATCORE_CORE) << "Waiting for firmware detect."; emit atcoreMessage(tr("Waiting for firmware detect.")); } qCDebug(ATCORE_CORE) << "Find Firmware: " << message; if (!message.contains("FIRMWARE_NAME:")) { qCDebug(ATCORE_CORE) << "No firmware yet."; return; } qCDebug(ATCORE_CORE) << "Found firmware string, Looking for Firmware Name."; QString fwName = QString::fromLocal8Bit(message); fwName = fwName.split(QChar::fromLatin1(':')).at(1); if (fwName.indexOf(QChar::fromLatin1(' ')) == 0) { //remove leading space fwName.remove(0, 1); } if (fwName.contains(QChar::fromLatin1(' '))) { //check there is a space or dont' resize fwName.resize(fwName.indexOf(QChar::fromLatin1(' '))); } fwName = fwName.toLower().simplified(); if (fwName.contains(QChar::fromLatin1('_'))) { fwName.resize(fwName.indexOf(QChar::fromLatin1('_'))); } qCDebug(ATCORE_CORE) << "Firmware Name:" << fwName; if (message.contains("EXTRUDER_COUNT:")) { //this code is broken if more then 9 extruders are detected. since only one char is returned setExtruderCount(message.at(message.indexOf("EXTRUDER_COUNT:") + 15) - '0'); } loadFirmwarePlugin(fwName); } void AtCore::loadFirmwarePlugin(const QString &fwName) { qCDebug(ATCORE_CORE) << "Loading plugin: " << d->plugins[fwName]; if (d->plugins.contains(fwName)) { d->pluginLoader.setFileName(d->plugins[fwName]); if (!d->pluginLoader.load()) { //Plugin was not loaded, Provide some debug info. qCDebug(ATCORE_CORE) << "Plugin Loading: Failed."; qCDebug(ATCORE_CORE) << d->pluginLoader.errorString(); setState(AtCore::CONNECTING); } else { //Plugin was loaded successfully. d->firmwarePlugin = qobject_cast(d->pluginLoader.instance()); firmwarePlugin()->init(this); disconnect(serial(), &SerialLayer::receivedCommand, this, &AtCore::findFirmware); connect(serial(), &SerialLayer::receivedCommand, this, &AtCore::newMessage); connect(firmwarePlugin(), &IFirmware::readyForCommand, this, &AtCore::processQueue); d->ready = true; // ready on new firmware load if (firmwarePlugin()->name() != QStringLiteral("Grbl")) { connect(d->tempTimer, &QTimer::timeout, this, &AtCore::checkTemperature); d->tempTimer->start(); } setState(IDLE); } } else { qCDebug(ATCORE_CORE) << "Plugin:" << fwName << ": Not found."; emit atcoreMessage(tr("No plugin found for %1.").arg(fwName)); } } bool AtCore::initSerial(const QString &port, int baud) { d->serial = new SerialLayer(port, baud); if (serialInitialized() && d->serial->isWritable()) { setState(AtCore::CONNECTING); connect(serial(), &SerialLayer::receivedCommand, this, &AtCore::findFirmware); d->serialTimer->stop(); return true; } else { qCDebug(ATCORE_CORE) << "Failed to open device for Read / Write."; emit atcoreMessage(tr("Failed to open device in read/write mode.")); return false; } } bool AtCore::serialInitialized() const { if (!d->serial) { return false; } return d->serial->isOpen(); } QString AtCore::connectedPort() const { return serial()->portName(); } QStringList AtCore::serialPorts() const { QStringList ports; QList serialPortInfoList = QSerialPortInfo::availablePorts(); if (!serialPortInfoList.isEmpty()) { for (const QSerialPortInfo &serialPortInfo : serialPortInfoList) { #ifdef Q_OS_MAC //Mac OS has callout serial ports starting with cu these devices are read only. //It is necessary to filter them out to help prevent user error. if (!serialPortInfo.portName().startsWith(QStringLiteral("cu."), Qt::CaseInsensitive)) { ports.append(serialPortInfo.portName()); } #else ports.append(serialPortInfo.portName()); #endif } } return ports; } void AtCore::locateSerialPort() { QStringList ports = serialPorts(); if (d->serialPorts != ports) { d->serialPorts = ports; emit portsChanged(d->serialPorts); } } quint16 AtCore::serialTimerInterval() const { if (d->serialTimer != nullptr) { return d->serialTimer->interval(); } return 0; } void AtCore::setSerialTimerInterval(const quint16 &newTime) { if (!d->serialTimer) { //There is no timer. We need to create one. d->serialTimer = new QTimer(); connect(d->serialTimer, &QTimer::timeout, this, &AtCore::locateSerialPort); } //emit the newtime if it has changed. if (newTime != d->serialTimer->interval()) { emit serialTimerIntervalChanged(newTime); } //Start the timer. d->serialTimer->start(newTime); } void AtCore::newMessage(const QByteArray &message) { //Evaluate the messages coming from the printer. d->lastMessage = message; //Check if the message has current coordinates. if (message.startsWith(QString::fromLatin1("X:").toLocal8Bit())) { d->posString = message; d->posString.resize(d->posString.indexOf('E')); d->posString.replace(':', ""); } //Check if have temperature info and decode it if (d->lastMessage.contains("T:") || d->lastMessage.contains("B:")) { temperature().decodeTemp(message); } - emit(receivedMessage(d->lastMessage)); + emit receivedMessage(d->lastMessage); } void AtCore::setRelativePosition() { pushCommand(GCode::toCommand(GCode::G91)); } void AtCore::setAbsolutePosition() { pushCommand(GCode::toCommand(GCode::G90)); } float AtCore::percentagePrinted() const { return d->percentage; } void AtCore::print(const QString &fileName, bool sdPrint) { if (state() == AtCore::CONNECTING) { qCDebug(ATCORE_CORE) << "Load a firmware plugin to print."; return; } //Start a print job. setState(AtCore::STARTPRINT); //Only try to print from Sd if the firmware has support for sd cards if (firmwarePlugin()->isSdSupported()) { if (sdPrint) { //Printing from the sd card requires us to send some M commands. pushCommand(GCode::toCommand(GCode::M23, fileName)); d->sdCardFileName = fileName; pushCommand(GCode::toCommand(GCode::M24)); setState(AtCore::BUSY); d->sdCardPrinting = true; connect(d->tempTimer, &QTimer::timeout, this, &AtCore::sdCardPrintStatus); return; } } //Process the gcode with a printThread. //The Thread processes the gcode without freezing the libary. //Only sends a command back when the printer is ready, avoiding buffer overflow in the printer. QThread *thread = new QThread(); PrintThread *printThread = new PrintThread(this, fileName); printThread->moveToThread(thread); connect(printThread, &PrintThread::printProgressChanged, this, &AtCore::printProgressChanged, Qt::QueuedConnection); connect(thread, &QThread::started, printThread, &PrintThread::start); connect(printThread, &PrintThread::finished, thread, &QThread::quit); connect(thread, &QThread::finished, printThread, &PrintThread::deleteLater); if (!thread->isRunning()) { thread->start(); } } void AtCore::pushCommand(const QString &comm) { //Append command to the commandQueue d->commandQueue.append(comm); if (d->ready) { //The printer is ready for a command now so push one. processQueue(); } } void AtCore::closeConnection() { if (serialInitialized()) { if (AtCore::state() == AtCore::BUSY && !d->sdCardPrinting) { //We have to clean up the print job if printing from the host. //However disconnecting while printing from sd card should not affect the print job. setState(AtCore::STOP); } if (firmwarePluginLoaded()) { disconnect(firmwarePlugin(), &IFirmware::readyForCommand, this, &AtCore::processQueue); disconnect(serial(), &SerialLayer::receivedCommand, this, &AtCore::newMessage); if (firmwarePlugin()->name() != QStringLiteral("Grbl")) { disconnect(d->tempTimer, &QTimer::timeout, this, &AtCore::checkTemperature); d->tempTimer->stop(); } //Attempt to unload the firmware plugin. QString name = firmwarePlugin()->name(); QString msg = d->pluginLoader.unload() ? QStringLiteral("closed.") : QStringLiteral("Failed to close."); qCDebug(ATCORE_CORE) << QStringLiteral("Firmware plugin %1 %2").arg(name, msg); } serial()->close(); //Clear our copy of the sdcard filelist clearSdCardFileList(); setState(AtCore::DISCONNECTED); d->serialTimer->start(); } } AtCore::STATES AtCore::state(void) { return d->printerState; } void AtCore::setState(AtCore::STATES state) { if (state != d->printerState) { qCDebug(ATCORE_CORE) << QStringLiteral("Atcore state changed from [%1] to [%2]") .arg(QVariant::fromValue(d->printerState).value(), QVariant::fromValue(state).value()); d->printerState = state; if (state == AtCore::FINISHEDPRINT && d->sdCardPrinting) { //Clean up the sd card print d->sdCardPrinting = false; disconnect(d->tempTimer, &QTimer::timeout, this, &AtCore::sdCardPrintStatus); } - emit(stateChanged(d->printerState)); + emit stateChanged(d->printerState); } } void AtCore::stop() { //Stop a print job setState(AtCore::STOP); d->commandQueue.clear(); if (d->sdCardPrinting) { stopSdPrint(); } setExtruderTemp(0, 0); setBedTemp(0); home(AtCore::X); } void AtCore::emergencyStop() { //Emergency Stop. Stops the machine //Clear the queue, and any print job //Before sending the command to ensure //Less chance of movement after the restart. d->commandQueue.clear(); if (AtCore::state() == AtCore::BUSY) { if (!d->sdCardPrinting) { //Stop our running print thread setState(AtCore::STOP); } } //push command through serial to bypass atcore's queue. serial()->pushCommand(GCode::toCommand(GCode::M112).toLocal8Bit()); } void AtCore::stopSdPrint() { //Stop an SdCard Print. pushCommand(GCode::toCommand(GCode::M25)); d->sdCardFileName = QString(); pushCommand(GCode::toCommand(GCode::M23, d->sdCardFileName)); AtCore::setState(AtCore::FINISHEDPRINT); AtCore::setState(AtCore::IDLE); } void AtCore::requestFirmware() { if (serialInitialized()) { qCDebug(ATCORE_CORE) << "Sending " << GCode::description(GCode::M115); serial()->pushCommand(GCode::toCommand(GCode::M115).toLocal8Bit()); } else { qCDebug(ATCORE_CORE) << "There is no open device to send commands"; } } bool AtCore::firmwarePluginLoaded() const { if (firmwarePlugin()) { return true; } else { return false; } } QMap AtCore::findFirmwarePlugins(const QString &path) { QMap detectedPlugins; 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(); QString pluginString = path; pluginString.append(QChar::fromLatin1('/')); pluginString.append(f); detectedPlugins[file] = pluginString; qCDebug(ATCORE_PLUGIN) << QStringLiteral("Plugin:[%1]=%2").arg(file, pluginString); } return detectedPlugins; } QStringList AtCore::availableFirmwarePlugins() const { return d->plugins.keys(); } void AtCore::pause(const QString &pauseActions) { if (d->sdCardPrinting) { pushCommand(GCode::toCommand(GCode::M25)); } //Push the command to request current coordinates. //This will be read by AtCore::newMessage and stored for use on resume. pushCommand(GCode::toCommand(GCode::M114)); if (!pauseActions.isEmpty()) { QStringList temp = pauseActions.split(QChar::fromLatin1(',')); for (int i = 0; i < temp.length(); i++) { pushCommand(temp.at(i)); } } setState(AtCore::PAUSE); } void AtCore::resume() { if (d->sdCardPrinting) { pushCommand(GCode::toCommand(GCode::M24)); } else { //Move back to previous coordinates. pushCommand(GCode::toCommand(GCode::G0, QString::fromLatin1(d->posString))); } setState(AtCore::BUSY); } /*~~~~~Control Slots ~~~~~~~~*/ void AtCore::home() { pushCommand(GCode::toCommand(GCode::G28)); } void AtCore::home(uchar axis) { QString args; if (axis & AtCore::X) { args.append(QStringLiteral("X0 ")); } if (axis & AtCore::Y) { args.append(QStringLiteral("Y0 ")); } if (axis & AtCore::Z) { args.append(QStringLiteral("Z0")); } pushCommand(GCode::toCommand(GCode::G28, args)); } void AtCore::setExtruderTemp(uint temp, uint extruder, bool andWait) { if (andWait) { pushCommand(GCode::toCommand(GCode::M109, QString::number(temp), QString::number(extruder))); } else { pushCommand(GCode::toCommand(GCode::M104, QString::number(extruder), QString::number(temp))); } } void AtCore::setBedTemp(uint temp, bool andWait) { if (andWait) { pushCommand(GCode::toCommand(GCode::M190, QString::number(temp))); } else { pushCommand(GCode::toCommand(GCode::M140, QString::number(temp))); } } void AtCore::setFanSpeed(uint speed, uint fanNumber) { pushCommand(GCode::toCommand(GCode::M106, QString::number(fanNumber), QString::number(speed))); } void AtCore::setPrinterSpeed(uint speed) { pushCommand(GCode::toCommand(GCode::M220, QString::number(speed))); } void AtCore::setFlowRate(uint speed) { pushCommand(GCode::toCommand(GCode::M221, QString::number(speed))); } void AtCore::move(AtCore::AXES axis, int arg) { static QLatin1Char a('?'); switch (axis) { case AtCore::X: a = QLatin1Char('X'); break; case AtCore::Y: a = QLatin1Char('Y'); break; case AtCore::Z: a = QLatin1Char('Z'); break; case AtCore::E: a = QLatin1Char('E'); break; default: break; }; move(a, arg); } void AtCore::move(QLatin1Char axis, int arg) { pushCommand(GCode::toCommand(GCode::G1, QStringLiteral("%1 %2").arg(axis).arg(QString::number(arg)))); } int AtCore::extruderCount() const { return d->extruderCount; } void AtCore::setExtruderCount(int newCount) { if (d->extruderCount != newCount && newCount >= 1) { d->extruderCount = newCount; emit extruderCountChanged(newCount); qCDebug(ATCORE_CORE) << "Extruder Count:" << QString::number(extruderCount()); } } void AtCore::processQueue() { d->ready = true; if (d->commandQueue.isEmpty()) { return; } if (!serialInitialized()) { qCDebug(ATCORE_PLUGIN) << "Can't process queue ! Serial not initialized."; return; } QString text = d->commandQueue.takeAt(0); if (firmwarePluginLoaded()) { serial()->pushCommand(firmwarePlugin()->translate(text)); } else { serial()->pushCommand(text.toLocal8Bit()); } d->ready = false; } void AtCore::checkTemperature() { //One request for the temperature in the queue at a time. if (d->commandQueue.contains(GCode::toCommand(GCode::M105))) { return; } pushCommand(GCode::toCommand(GCode::M105)); } void AtCore::showMessage(const QString &message) { if (!message.isEmpty()) { pushCommand(GCode::toCommand((GCode::M117), message)); } } void AtCore::setUnits(AtCore::UNITS units) { switch (units) { case AtCore::METRIC: pushCommand(GCode::toCommand(GCode::G21)); break; case AtCore::IMPERIAL: pushCommand(GCode::toCommand(GCode::G20)); break; } } QStringList AtCore::portSpeeds() const { return serial()->validBaudRates(); } void AtCore::disableMotors(uint delay) { //Disables motors if (delay) { pushCommand(GCode::toCommand(GCode::M84, QString::number(delay))); } else { pushCommand(GCode::toCommand(GCode::M84)); } } //Most firmwares will not report if an sdcard is mounted on boot. bool AtCore::isSdMounted() const { return d->sdCardMounted; } void AtCore::setSdMounted(bool mounted) { if (mounted != isSdMounted()) { d->sdCardMounted = mounted; - emit(sdMountChanged(d->sdCardMounted)); + emit sdMountChanged(d->sdCardMounted); } } void AtCore::getSDFileList() { pushCommand(GCode::toCommand(GCode::M20)); } QStringList AtCore::sdFileList() { if (!d->sdCardReadingFileList) { getSDFileList(); } return d->sdCardFileList; } void AtCore::appendSdCardFileList(const QString &fileName) { d->sdCardFileList.append(fileName); - emit(sdCardFileListChanged(d->sdCardFileList)); + emit sdCardFileListChanged(d->sdCardFileList); } void AtCore::clearSdCardFileList() { d->sdCardFileList.clear(); - emit(sdCardFileListChanged(d->sdCardFileList)); + emit sdCardFileListChanged(d->sdCardFileList); } void AtCore::sdDelete(const QString &fileName) { if (d->sdCardFileList.contains(fileName)) { pushCommand(GCode::toCommand(GCode::M30, fileName)); getSDFileList(); } else { qCDebug(ATCORE_CORE) << "Delete failed file not found:" << fileName; } } void AtCore::mountSd(uint slot) { pushCommand(GCode::toCommand(GCode::M21, QString::number(slot))); } void AtCore::umountSd(uint slot) { pushCommand(GCode::toCommand(GCode::M22, QString::number(slot))); } bool AtCore::isReadingSdCardList() const { return d->sdCardReadingFileList; } void AtCore::setReadingSdCardList(bool readingList) { d->sdCardReadingFileList = readingList; } void AtCore::sdCardPrintStatus() { //One request for the Sd Job status in the queue at a time. if (d->commandQueue.contains(GCode::toCommand(GCode::M27))) { return; } pushCommand(GCode::toCommand(GCode::M27)); } diff --git a/src/core/printthread.cpp b/src/core/printthread.cpp index 1cb7cec..f04c402 100644 --- a/src/core/printthread.cpp +++ b/src/core/printthread.cpp @@ -1,229 +1,229 @@ /* AtCore Copyright (C) <2017> Authors: Chris Rizzitello This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include #include #include #include "printthread.h" Q_LOGGING_CATEGORY(PRINT_THREAD, "org.kde.atelier.core.printThread") /** * @brief The PrintThreadPrivate class */ class PrintThreadPrivate { public: AtCore *core = nullptr; //!<@param core: Pointer to AtCore QTextStream *gcodestream = nullptr; //!<@param gcodestream: Steam the job is read from float printProgress = 0; //!<@param printProgress: Progress of the print job qint64 totalSize = 0; //!<@param totalSize: total file size qint64 stillSize = 0; //!<@param stillSize: remaining file QString cline; //!<@param cline: current line AtCore::STATES state = AtCore::IDLE;//!<@param state: printer state QFile *file = nullptr; //!<@param file: gcode File to stream from QList options = { {QCommandLineOption(QStringLiteral("pause"))}, {QCommandLineOption(QStringLiteral("extruder temperature"))}, {QCommandLineOption(QStringLiteral("bed temperature"))}, {QCommandLineOption(QStringLiteral("print speed"))}, {QCommandLineOption(QStringLiteral("fan speed"))}, {QCommandLineOption(QStringLiteral("flow rate"))}, {QCommandLineOption(QStringLiteral("message"))}, {QCommandLineOption(QStringLiteral("command"))} }; //!<@param options: injectable commands. }; PrintThread::PrintThread(AtCore *parent, QString fileName) : d(new PrintThreadPrivate) { d->core = parent; d->state = d->core->state(); d->file = new QFile(fileName); d->file->open(QFile::ReadOnly); d->totalSize = d->file->bytesAvailable(); d->stillSize = d->totalSize; d->gcodestream = new QTextStream(d->file); } void PrintThread::start() { // we only want to do this when printing connect(d->core->firmwarePlugin(), &IFirmware::readyForCommand, this, &PrintThread::processJob, Qt::QueuedConnection); connect(this, &PrintThread::nextCommand, d->core, &AtCore::pushCommand, Qt::QueuedConnection); connect(this, &PrintThread::stateChanged, d->core, &AtCore::setState, Qt::QueuedConnection); connect(d->core, &AtCore::stateChanged, this, &PrintThread::setState, Qt::QueuedConnection); connect(this, &PrintThread::finished, this, &PrintThread::deleteLater); // force a command if the printer doesn't send "wait" when idle processJob(); } void PrintThread::processJob() { if (d->gcodestream->atEnd()) { endPrint(); } switch (d->state) { case AtCore::STARTPRINT: case AtCore::IDLE: case AtCore::BUSY: setState(AtCore::BUSY); nextLine(); while (d->cline.isEmpty() && !d->gcodestream->atEnd()) { nextLine(); } if (!d->cline.isEmpty() && d->core->state() != AtCore::PAUSE) { qCDebug(PRINT_THREAD) << "cline:" << d->cline; emit nextCommand(d->cline); } break; case AtCore::ERRORSTATE: qCDebug(PRINT_THREAD) << "Error State"; break; case AtCore::STOP: { endPrint(); break; } case AtCore::PAUSE: if (d->cline.startsWith(QStringLiteral(";-"))) { nextLine(); } break; default: qCDebug(PRINT_THREAD) << "Unknown State"; break; } } void PrintThread::endPrint() { - emit(printProgressChanged(100)); + emit printProgressChanged(100); qCDebug(PRINT_THREAD) << "atEnd"; disconnect(d->core->firmwarePlugin(), &IFirmware::readyForCommand, this, &PrintThread::processJob); disconnect(this, &PrintThread::nextCommand, d->core, &AtCore::pushCommand); disconnect(d->core, &AtCore::stateChanged, this, &PrintThread::setState); - emit(stateChanged(AtCore::FINISHEDPRINT)); - emit(stateChanged(AtCore::IDLE)); + emit stateChanged(AtCore::FINISHEDPRINT); + emit stateChanged(AtCore::IDLE); disconnect(this, &PrintThread::stateChanged, d->core, &AtCore::setState); emit finished(); } void PrintThread::nextLine() { d->cline = d->gcodestream->readLine(); qCDebug(PRINT_THREAD) << "Nextline:" << d->cline; d->stillSize -= d->cline.size() + 1; //remove read chars d->printProgress = float(d->totalSize - d->stillSize) * 100.0 / float(d->totalSize); qCDebug(PRINT_THREAD) << "progress:" << QString::number(d->printProgress); - emit(printProgressChanged(d->printProgress)); + emit printProgressChanged(d->printProgress); if (d->cline.startsWith(QStringLiteral(";-"))) { injectCommand(d->cline); d->cline = QStringLiteral(""); return; } //Remove Comments from the gcode. //Type 1: Anything after ; is comment. //Example G28 Z; Home Axis Z if (d->cline.contains(QChar::fromLatin1(';'))) { d->cline.resize(d->cline.indexOf(QChar::fromLatin1(';'))); } //Type 2: Block Type anything between ( and ) is a comment // Example G28 (Home)Z if (d->cline.contains(QChar::fromLatin1('('))) { //Remove (.....) from the line d->cline.remove(QRegularExpression(QStringLiteral(".(?<=[(])(.*)(?=[)])."))); } d->cline = d->cline.simplified(); } void PrintThread::setState(const AtCore::STATES &newState) { if (d->state == AtCore::STATES::DISCONNECTED && ( newState == AtCore::STATES::PAUSE || newState == AtCore::STATES::STOP ) ) { qCDebug(PRINT_THREAD) << "Serial not connected !"; return; } if (newState != d->state) { qCDebug(PRINT_THREAD) << QStringLiteral("State changed from [%1] to [%2]") .arg(QVariant::fromValue(d->state).value(), QVariant::fromValue(newState).value()); disconnect(d->core, &AtCore::stateChanged, this, &PrintThread::setState); d->state = newState; - emit(stateChanged(d->state)); + emit stateChanged(d->state); connect(d->core, &AtCore::stateChanged, this, &PrintThread::setState, Qt::QueuedConnection); } } void PrintThread::injectCommand(QString &command) { //remove the ; command.remove(0, 1); command.prepend(QStringLiteral("0:")); QStringList cmd = command.split(QLatin1Char(':')); cmd.replace(1, cmd.at(1).simplified().toLower()); cmd.replace(2, cmd.at(2).simplified()); static QCommandLineParser parser; if (parser.optionNames().isEmpty()) { parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); parser.addOptions(d->options); } qCDebug(PRINT_THREAD) << "attempting to inject " << cmd; parser.process(cmd); if (parser.isSet(QStringLiteral("pause"))) { d->core->pause(parser.positionalArguments().at(0)); } else if (parser.isSet(QStringLiteral("extruder temperature"))) { QStringList args = parser.positionalArguments().at(0).split(QLatin1Char(',')); bool wait = !QString::compare(args.at(2).simplified(), QStringLiteral("true"), Qt::CaseInsensitive); d->core->setExtruderTemp(args.at(0).toInt(), args.at(1).toInt(), wait); } else if (parser.isSet(QStringLiteral("bed temperature"))) { QStringList args = parser.positionalArguments().at(0).split(QLatin1Char(',')); bool wait = !QString::compare(args.at(1).simplified(), QStringLiteral("true"), Qt::CaseInsensitive); d->core->setBedTemp(args.at(0).toInt(), wait); } else if (parser.isSet(QStringLiteral("print speed"))) { d->core->setPrinterSpeed(parser.positionalArguments().at(0).toInt()); } else if (parser.isSet(QStringLiteral("fan speed"))) { d->core->setFanSpeed(parser.positionalArguments().at(0).toInt(), parser.positionalArguments().at(1).toInt()); } else if (parser.isSet(QStringLiteral("flow rate"))) { d->core->setFlowRate(parser.positionalArguments().at(0).toInt()); } else if (parser.isSet(QStringLiteral("message"))) { d->core->showMessage(parser.positionalArguments().at(0)); } else if (parser.isSet(QStringLiteral("command"))) { d->core->pushCommand(parser.positionalArguments().at(0)); } else { qCDebug(PRINT_THREAD) << "Attempted to inject unknown command: " << parser.positionalArguments(); } } diff --git a/src/core/seriallayer.cpp b/src/core/seriallayer.cpp index aff9f8d..c8fb913 100644 --- a/src/core/seriallayer.cpp +++ b/src/core/seriallayer.cpp @@ -1,147 +1,147 @@ /* AtCore Copyright (C) <2016> Authors: Patrick José Pereira Chris Rizzitello Tomaz Canabrava This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include "seriallayer.h" Q_LOGGING_CATEGORY(SERIAL_LAYER, "org.kde.atelier.core.serialLayer") namespace { QByteArray _return = QByteArray("\r"); QByteArray _newLine = QByteArray("\n"); QByteArray _newLineReturn = QByteArray("\n\r"); QStringList _validBaudRates = { QStringLiteral("9600"), QStringLiteral("14400"), QStringLiteral("19200"), QStringLiteral("28800"), QStringLiteral("38400"), QStringLiteral("57600"), QStringLiteral("76800"), QStringLiteral("115200"), QStringLiteral("230400"), QStringLiteral("250000"), QStringLiteral("500000"), QStringLiteral("1000000") }; } /** * @brief The SerialLayerPrivate class */ class SerialLayerPrivate { public: bool _serialOpened; //!< @param _serialOpened: is serial port opened QByteArray _rawData; //!< @param _rawData: the raw serial data QVector _rByteCommands; //!< @param _rByteCommand: received Messages QVector _sByteCommands; //!< @param _sByteCommand: sent Messages }; SerialLayer::SerialLayer(const QString &port, uint baud, QObject *parent) : QSerialPort(parent), d(new SerialLayerPrivate()) { setPortName(port); setBaudRate(baud); if (open(QIODevice::ReadWrite)) { d->_serialOpened = true; connect(this, &QSerialPort::readyRead, this, &SerialLayer::readAllData); } }; void SerialLayer::readAllData() { d->_rawData.append(readAll()); //Remove any \r in the string, then split by \n. //This removes any trailing \r or \n from the commands // Proper line endings are added when the command is pushed. d->_rawData = d->_rawData.replace(_return, QByteArray()); QList tempList = d->_rawData.split(_newLine.at(0)); for (auto i = tempList.begin(); i != tempList.end(); ++i) { // Get finished line to _byteCommands if (i < tempList.end() - 1) { d->_rByteCommands.append(*i); - emit(receivedCommand(*i)); + emit receivedCommand(*i); } else { d->_rawData.clear(); d->_rawData.append(*i); } } } void SerialLayer::pushCommand(const QByteArray &comm, const QByteArray &term) { if (!isOpen()) { qCDebug(SERIAL_LAYER) << "Serial not connected !"; return; } QByteArray tmp = comm + term; write(tmp); - emit(pushedCommand(tmp)); + emit pushedCommand(tmp); } void SerialLayer::pushCommand(const QByteArray &comm) { pushCommand(comm, _newLineReturn); } void SerialLayer::add(const QByteArray &comm, const QByteArray &term) { QByteArray tmp = comm + term; d->_sByteCommands.append(tmp); } void SerialLayer::add(const QByteArray &comm) { add(comm, _newLineReturn); } void SerialLayer::push() { if (!isOpen()) { qCDebug(SERIAL_LAYER) << "Serial not connected !"; return; } for (const auto &comm : d->_sByteCommands) { write(comm); - emit(pushedCommand(comm)); + emit pushedCommand(comm); } d->_sByteCommands.clear(); } bool SerialLayer::commandAvailable() const { return !d->_rByteCommands.isEmpty(); } QStringList SerialLayer::validBaudRates() const { return _validBaudRates; } diff --git a/src/plugins/marlinplugin.cpp b/src/plugins/marlinplugin.cpp index d4f7375..a876434 100644 --- a/src/plugins/marlinplugin.cpp +++ b/src/plugins/marlinplugin.cpp @@ -1,98 +1,98 @@ /* AtCore KDE Libary for 3D Printers Copyright (C) <2016> Authors: Tomaz Canabrava Chris Rizzitello Patrick José Pereira This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include "marlinplugin.h" #include "atcore.h" Q_LOGGING_CATEGORY(MARLIN_PLUGIN, "org.kde.atelier.core.firmware.marlin") QString MarlinPlugin::name() const { return QStringLiteral("Marlin"); } bool MarlinPlugin::isSdSupported() const { return true; } MarlinPlugin::MarlinPlugin() { qCDebug(MARLIN_PLUGIN) << name() << " plugin loaded!"; } void MarlinPlugin::validateCommand(const QString &lastMessage) { if (lastMessage.contains(QStringLiteral("End file list"))) { core()->setReadingSdCardList(false); } else if (core()->isReadingSdCardList()) { // Below is to not add directories if (!lastMessage.endsWith(QChar::fromLatin1('/'))) { QString fileName = lastMessage; fileName.chop(fileName.length() - fileName.lastIndexOf(QChar::fromLatin1(' '))); core()->appendSdCardFileList(fileName); } } else { if (lastMessage.contains(QStringLiteral("SD card ok"))) { core()->setSdMounted(true); } else if (lastMessage.contains(QStringLiteral("SD init fail"))) { core()->setSdMounted(false); } else if (lastMessage.contains(QStringLiteral("Begin file list"))) { core()->setSdMounted(true); core()->clearSdCardFileList(); core()->setReadingSdCardList(true); } else if (lastMessage.contains(QStringLiteral("SD printing byte"))) { if (core()->state() != AtCore::BUSY) { //This should only happen if Attached to an Sd printing machine. //Just tell the client were starting a job like normal. //For this to work the client should check if sdCardPrintStatus() //Upon the Connection to a known firmware with sdSupport core()->setState(AtCore::STARTPRINT); core()->setState(AtCore::BUSY); } QString temp = lastMessage; temp.replace(QStringLiteral("SD printing byte"), QString()); qlonglong total = temp.mid(temp.lastIndexOf(QChar::fromLatin1('/')) + 1, temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))).toLongLong(); if (total) { temp.chop(temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))); qlonglong remaining = total - temp.toLongLong(); float progress = float(total - remaining) * 100 / float(total); - core()->printProgressChanged(progress); + emit core()->printProgressChanged(progress); if (progress >= 100) { core()->setState(AtCore::FINISHEDPRINT); core()->setState(AtCore::IDLE); } } else { core()->setState(AtCore::FINISHEDPRINT); core()->setState(AtCore::IDLE); } } if (lastMessage.contains(QStringLiteral("ok"))) { emit readyForCommand(); } } } diff --git a/src/plugins/repetierplugin.cpp b/src/plugins/repetierplugin.cpp index 26c0e61..0183cc2 100644 --- a/src/plugins/repetierplugin.cpp +++ b/src/plugins/repetierplugin.cpp @@ -1,104 +1,104 @@ /* AtCore KDE Libary for 3D Printers Copyright (C) <2016> Authors: Tomaz Canabrava Chris Rizzitello Patrick José Pereira This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include #include #include "repetierplugin.h" #include "atcore.h" Q_LOGGING_CATEGORY(REPETIER_PLUGIN, "org.kde.atelier.core.firmware.repetier") QString RepetierPlugin::name() const { return QStringLiteral("Repetier"); } bool RepetierPlugin::isSdSupported() const { return true; } RepetierPlugin::RepetierPlugin() { qCDebug(REPETIER_PLUGIN) << name() << " plugin loaded!"; } void RepetierPlugin::validateCommand(const QString &lastMessage) { if (lastMessage.contains(QStringLiteral("End file list"))) { core()->setReadingSdCardList(false); } else if (core()->isReadingSdCardList()) { // Below is to not add directories if (!lastMessage.endsWith(QChar::fromLatin1('/'))) { QString fileName = lastMessage; fileName.chop(fileName.length() - fileName.lastIndexOf(QChar::fromLatin1(' '))); core()->appendSdCardFileList(fileName); } } else { if (lastMessage.contains(QStringLiteral("SD card"))) { if (lastMessage.contains(QStringLiteral("inserted"))) { core()->setSdMounted(true); } else if (lastMessage.contains(QStringLiteral("removed"))) { core()->setSdMounted(false); } } else if (lastMessage.contains(QStringLiteral("Begin file list"))) { core()->setSdMounted(true); core()->setReadingSdCardList(true); core()->clearSdCardFileList(); } else if (lastMessage.contains(QStringLiteral("SD printing byte"))) { if (lastMessage.contains(QStringLiteral("SD printing byte 0/0"))) { //not printing a file return; } if (core()->state() != AtCore::BUSY) { //This should only happen if Attached to an Sd printing machine. //Just tell the client were starting a job like normal. //For this to work the client should check if sdCardPrintStatus() //Upon the Connection to a known firmware with sdSupport core()->setState(AtCore::STARTPRINT); core()->setState(AtCore::BUSY); } QString temp = lastMessage; temp.replace(QStringLiteral("SD printing byte"), QString()); qlonglong total = temp.mid(temp.lastIndexOf(QChar::fromLatin1('/')) + 1, temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))).toLongLong(); if (total) { temp.chop(temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))); qlonglong remaining = total - temp.toLongLong(); float progress = float(total - remaining) * 100 / float(total); - core()->printProgressChanged(progress); + emit core()->printProgressChanged(progress); if (progress >= 100) { core()->setState(AtCore::FINISHEDPRINT); core()->setState(AtCore::IDLE); } } else { core()->setState(AtCore::FINISHEDPRINT); core()->setState(AtCore::IDLE); } } if (lastMessage.contains(QStringLiteral("ok"))) { emit readyForCommand(); } } } diff --git a/src/widgets/commandwidget.cpp b/src/widgets/commandwidget.cpp index 8948a4b..fafadd5 100644 --- a/src/widgets/commandwidget.cpp +++ b/src/widgets/commandwidget.cpp @@ -1,70 +1,70 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "commandwidget.h" #include #include #include CommandWidget::CommandWidget(QWidget *parent) : QWidget(parent) { //Expose the least amount of object outside the creation function. // First we make our mainLayout auto mainLayout = new QVBoxLayout; //Begin making content from top to bottom or left to right. //Making child layouts in the order you want to put them // onto the mainLayout lineCommand = new QLineEdit; lineCommand->setPlaceholderText(tr("Send Command")); //we have a few buttons to make here. Lets name this newButton so its easier to reuse auto newButton = new QPushButton(tr("Send")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(commandPressed(lineCommand->text())); + emit commandPressed(lineCommand->text()); lineCommand->clear(); }); //When you have created a Row put the items into layout. auto hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(lineCommand); hBoxLayout->addWidget(newButton); //Put the Layout or Widget on the mainLayout when its finished. //This will free your pointers for reuse. mainLayout->addLayout(hBoxLayout); //Start making items for the next layout to place onto the mainLayout. lineMessage = new QLineEdit; lineMessage->setPlaceholderText(tr("Show Message")); //Reuse our button pointer. newButton = new QPushButton(tr("Send")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(messagePressed(lineMessage->text())); + emit messagePressed(lineMessage->text()); lineMessage->clear(); }); //We reuse the hBoxLayout pointer in the same way as the button pointer. hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(lineMessage); hBoxLayout->addWidget(newButton); mainLayout->addLayout(hBoxLayout); setLayout(mainLayout); } diff --git a/src/widgets/movementwidget.cpp b/src/widgets/movementwidget.cpp index 8c11cd8..4e58aa7 100644 --- a/src/widgets/movementwidget.cpp +++ b/src/widgets/movementwidget.cpp @@ -1,98 +1,98 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "axiscontrol.h" #include "movementwidget.h" MovementWidget::MovementWidget(bool showHomeAndDisableWidgets, QWidget *parent) : QWidget(parent) { auto mainLayout = new QVBoxLayout; auto hBoxLayout = new QHBoxLayout; auto newButton = new QPushButton; if (showHomeAndDisableWidgets) { newButton = new QPushButton(tr("Home All")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(homeAllPressed()); + emit homeAllPressed(); }); newButton = new QPushButton(tr("Home X")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(homeXPressed()); + emit homeXPressed(); }); newButton = new QPushButton(tr("Home Y")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(homeYPressed()); + emit homeYPressed(); }); newButton = new QPushButton(tr("Home Z")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(homeZPressed()); + emit homeZPressed(); }); mainLayout->addLayout(hBoxLayout); newButton = new QPushButton(tr("Disable Motors")); mainLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(disableMotorsPressed()); + emit disableMotorsPressed(); }); } comboMoveAxis = new QComboBox; comboMoveAxis->addItem(tr("Move X Axis to")); comboMoveAxis->addItem(tr("Move Y Axis to")); comboMoveAxis->addItem(tr("Move Z Axis to")); sbMoveAxis = new QDoubleSpinBox; sbMoveAxis->setRange(0, 200); newButton = new QPushButton(tr("Go")); connect(newButton, &QPushButton::clicked, this, [this] { if (comboMoveAxis->currentIndex() == 0) { - emit(absoluteMove(QLatin1Char('X'), sbMoveAxis->value())); + emit absoluteMove(QLatin1Char('X'), sbMoveAxis->value()); } else if (comboMoveAxis->currentIndex() == 1) { - emit(absoluteMove(QLatin1Char('Y'), sbMoveAxis->value())); + emit absoluteMove(QLatin1Char('Y'), sbMoveAxis->value()); } else if (comboMoveAxis->currentIndex() == 2) { - emit(absoluteMove(QLatin1Char('Z'), sbMoveAxis->value())); + emit absoluteMove(QLatin1Char('Z'), sbMoveAxis->value()); } }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(comboMoveAxis); hBoxLayout->addWidget(sbMoveAxis); hBoxLayout->addWidget(newButton); mainLayout->addLayout(hBoxLayout); auto axisControl = new AxisControl; mainLayout->addWidget(axisControl); connect(axisControl, &AxisControl::clicked, this, &MovementWidget::relativeMove); setLayout(mainLayout); } diff --git a/src/widgets/printwidget.cpp b/src/widgets/printwidget.cpp index 2086dd0..e2208f1 100644 --- a/src/widgets/printwidget.cpp +++ b/src/widgets/printwidget.cpp @@ -1,125 +1,125 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "printwidget.h" #include #include #include #include PrintWidget::PrintWidget(bool showAllControls, QWidget *parent) : QWidget(parent) { auto mainLayout = new QVBoxLayout; QPushButton *newButton = nullptr; QLabel *newLabel = nullptr; QHBoxLayout *hBoxLayout = nullptr; if (showAllControls) { buttonPrint = new QPushButton(tr("Print File")); connect(buttonPrint, &QPushButton::clicked, this, [this] { - emit(printPressed()); + emit printPressed(); }); newButton = new QPushButton(tr("Emergency Stop")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(emergencyStopPressed()); + emit emergencyStopPressed(); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(buttonPrint); hBoxLayout->addWidget(newButton); mainLayout->addLayout(hBoxLayout); newLabel = new QLabel(tr("On Pause:")); linePostPause = new QLineEdit; linePostPause->setPlaceholderText(QStringLiteral("G91,G0 Z1,G90,G1 X0 Y195")); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(newLabel); hBoxLayout->addWidget(linePostPause); mainLayout->addLayout(hBoxLayout); } newLabel = new QLabel(tr("Printer Speed")); sbPrintSpeed = new QSpinBox; sbPrintSpeed->setRange(1, 300); sbPrintSpeed->setValue(100); sbPrintSpeed->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(printSpeedChanged(sbPrintSpeed->value())); + emit printSpeedChanged(sbPrintSpeed->value()); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(newLabel, 60); hBoxLayout->addWidget(sbPrintSpeed, 20); hBoxLayout->addWidget(newButton, 20); mainLayout->addLayout(hBoxLayout); newLabel = new QLabel(tr("Flow Rate")); sbFlowRate = new QSpinBox; sbFlowRate->setRange(1, 300); sbFlowRate->setValue(100); sbFlowRate->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(flowRateChanged(sbFlowRate->value())); + emit flowRateChanged(sbFlowRate->value()); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(newLabel, 60); hBoxLayout->addWidget(sbFlowRate, 20); hBoxLayout->addWidget(newButton, 20); mainLayout->addLayout(hBoxLayout); comboFanSelect = new QComboBox; sbFanSpeed = new QSpinBox; sbFanSpeed->setRange(0, 100); sbFanSpeed->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(fanSpeedChanged(sbFanSpeed->value(), comboFanSelect->currentIndex())); + emit fanSpeedChanged(sbFanSpeed->value(), comboFanSelect->currentIndex()); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(comboFanSelect, 60); hBoxLayout->addWidget(sbFanSpeed, 20); hBoxLayout->addWidget(newButton, 20); mainLayout->addLayout(hBoxLayout); setLayout(mainLayout); } QString PrintWidget::postPauseCommand(void) const { return linePostPause->text(); } void PrintWidget::setPrintText(const QString &text) { buttonPrint->setText(text); } void PrintWidget::updateFanCount(const int count) { for (int i = 0; i < count; i++) { comboFanSelect->insertItem(i, tr("Fan %1 speed").arg(i)); } } diff --git a/src/widgets/sdwidget.cpp b/src/widgets/sdwidget.cpp index 3fe9b4e..c2820aa 100644 --- a/src/widgets/sdwidget.cpp +++ b/src/widgets/sdwidget.cpp @@ -1,72 +1,72 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "sdwidget.h" SdWidget::SdWidget(QWidget *parent) : QWidget(parent) { auto hBoxLayout = new QHBoxLayout; auto newButton = new QPushButton(tr("Get List")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - emit(requestSdList()); + emit requestSdList(); }); newButton = new QPushButton(tr("Print Selected")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { if (listSdFiles->currentRow() != -1) { - emit(printSdFile(listSdFiles->currentItem()->text())); + emit printSdFile(listSdFiles->currentItem()->text()); } }); newButton = new QPushButton(tr("Delete Selected")); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { if (listSdFiles->currentRow() != -1) { - emit(deleteSdFile(listSdFiles->currentItem()->text())); + emit deleteSdFile(listSdFiles->currentItem()->text()); listSdFiles->setCurrentRow(-1); } }); auto groupFiles = new QGroupBox(tr("Files On Sd Card")); listSdFiles = new QListWidget; auto groupLayout = new QVBoxLayout; groupLayout->addWidget(listSdFiles); groupFiles->setLayout(groupLayout); auto mainLayout = new QVBoxLayout; mainLayout->addItem(hBoxLayout); mainLayout->addWidget(groupFiles); setLayout(mainLayout); } void SdWidget::updateFilelist(const QStringList &fileList) { listSdFiles->clear(); listSdFiles->addItems(fileList); } diff --git a/src/widgets/statuswidget.cpp b/src/widgets/statuswidget.cpp index c4cf4a5..944a71b 100644 --- a/src/widgets/statuswidget.cpp +++ b/src/widgets/statuswidget.cpp @@ -1,118 +1,118 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "statuswidget.h" StatusWidget::StatusWidget(bool showStop, QWidget *parent) : QWidget(parent) { //first create the item for the print Progress. auto hBoxLayout = new QHBoxLayout; printingProgress = new QProgressBar; printingProgress->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); hBoxLayout->addWidget(printingProgress); if (showStop) { auto newButton = new QPushButton(style()->standardIcon(QStyle::SP_BrowserStop), QString()); connect(newButton, &QPushButton::clicked, this, [this] { - emit(stopPressed()); + emit stopPressed(); }); hBoxLayout->addWidget(newButton); } lblTime = new QLabel(QStringLiteral("00:00:00")); lblTime->setAlignment(Qt::AlignHCenter); auto newLabel = new QLabel(QStringLiteral(" / ")); lblTimeLeft = new QLabel(QStringLiteral("??:??:??")); lblTimeLeft->setAlignment(Qt::AlignHCenter); hBoxLayout->addWidget(lblTime); hBoxLayout->addWidget(newLabel); hBoxLayout->addWidget(lblTimeLeft); printProgressWidget = new QWidget(); printProgressWidget->setLayout(hBoxLayout); //Then Create the full bar. newLabel = new QLabel(tr("AtCore State:")); lblState = new QLabel(tr("Not Connected")); lblSd = new QLabel(); spacer = new QSpacerItem(10, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(newLabel); hBoxLayout->addWidget(lblState); hBoxLayout->addSpacerItem(new QSpacerItem(5, 20, QSizePolicy::Fixed)); hBoxLayout->addWidget(lblSd); hBoxLayout->addSpacerItem(spacer); hBoxLayout->addWidget(printProgressWidget); setLayout(hBoxLayout); printTime = new QTime(); printTimer = new QTimer(); printTimer->setInterval(1000); printTimer->setSingleShot(false); connect(printTimer, &QTimer::timeout, this, &StatusWidget::updatePrintTime); } void StatusWidget::setSD(bool hasSd) { QString labelText = hasSd ? tr("SD") : QString(); lblSd->setText(labelText); } void StatusWidget::setState(const QString &state) { lblState->setText(state); } void StatusWidget::showPrintArea(bool visible) { printProgressWidget->setVisible(visible); if (visible) { spacer->changeSize(10, 20, QSizePolicy::Fixed, QSizePolicy::Fixed); printTime->start(); printTimer->start(); } else { printTimer->stop(); spacer->changeSize(10, 20, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); } } void StatusWidget::updatePrintTime() { QTime temp(0, 0, 0); lblTime->setText(temp.addMSecs(printTime->elapsed()).toString(QStringLiteral("hh:mm:ss"))); } void StatusWidget::updatePrintProgress(const float &progress) { printingProgress->setValue(progress); if (progress >= 1) { QTime temp(0, 0, 0); lblTimeLeft->setText(temp.addMSecs((100 - progress) * (printTime->elapsed() / progress)).toString(QStringLiteral("hh:mm:ss"))); } else { lblTimeLeft->setText(QStringLiteral("??:??:??")); } } diff --git a/src/widgets/temperaturewidget.cpp b/src/widgets/temperaturewidget.cpp index ef48778..85283ef 100644 --- a/src/widgets/temperaturewidget.cpp +++ b/src/widgets/temperaturewidget.cpp @@ -1,72 +1,72 @@ /* AtCore Test Client Copyright (C) <2018> Author: 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 "temperaturewidget.h" #include #include #include #include TemperatureWidget::TemperatureWidget(QWidget *parent) : QWidget(parent) { auto *mainLayout = new QVBoxLayout; checkAndWait = new QCheckBox(tr("Wait Until Temperature Stabilizes")); mainLayout->addWidget(checkAndWait); auto label = new QLabel(tr("Bed Temp")); sbBedTemp = new QSpinBox; sbBedTemp->setRange(0, 120); sbBedTemp->setSuffix(QStringLiteral("°C")); auto *newButton = new QPushButton(tr("Set")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(bedTempChanged(sbBedTemp->value(), checkAndWait->isChecked())); + emit bedTempChanged(sbBedTemp->value(), checkAndWait->isChecked()); }); auto *hboxLayout = new QHBoxLayout; hboxLayout->addWidget(label, 80); hboxLayout->addWidget(sbBedTemp); hboxLayout->addWidget(newButton); mainLayout->addItem(hboxLayout); comboExtruderSelect = new QComboBox; sbExtruderTemp = new QSpinBox; sbExtruderTemp->setRange(0, 275); sbExtruderTemp->setSuffix(QStringLiteral("°C")); newButton = new QPushButton(tr("Set")); connect(newButton, &QPushButton::clicked, this, [this] { - emit(extTempChanged(sbExtruderTemp->value(), comboExtruderSelect->currentIndex(), checkAndWait->isChecked())); + emit extTempChanged(sbExtruderTemp->value(), comboExtruderSelect->currentIndex(), checkAndWait->isChecked()); }); hboxLayout = new QHBoxLayout; hboxLayout->addWidget(comboExtruderSelect, 80); hboxLayout->addWidget(sbExtruderTemp); hboxLayout->addWidget(newButton); mainLayout->addItem(hboxLayout); setLayout(mainLayout); } void TemperatureWidget::updateExtruderCount(const int count) { for (int i = 0; i < count; i++) { comboExtruderSelect->insertItem(i, tr("Extruder %1").arg(i)); } }