diff --git a/CMakeLists.txt b/CMakeLists.txt index 29295e4..d3485b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,120 +1,129 @@ project(AtCore) cmake_minimum_required(VERSION 3.8) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) include(CMakePackageConfigHelpers) include(ECMGenerateHeaders) include(ECMGeneratePriFile) include(ECMInstallIcons) include(ECMSetupVersion) include(FeatureSummary) include(GenerateExportHeader) include(KDECompilerSettings NO_POLICY_SCOPE) include(KDEInstallDirs) include(KDECMakeSettings) option(BUILD_GUI "Build the Test Gui") option(BUILD_DOCS "Build and Install Documents (Requires Doxygen)") option(BUILD_TESTS "Build and Run Unittests") option(DEPLOY_PLUGINS_WITH_BINARY "Deploy Plugins to bin/plugins (Use for win/mac)") +include(KDEClangFormat) +file(GLOB_RECURSE + ALL_CLANG_FORMAT_SOURCE_FILES + *.cpp + *.h +) + +kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES}) + set_package_properties( ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra modules and scripts for CMake" URL "git://anongit.kde.org/extra-cmake-modules") set(PROJECT_VERSION "1.0.70") set(KF5_DEP_VERSION "5.24.0") # handled by release scripts set(REQUIRED_QT_VERSION 5.4.0) set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/AtCore") # Generate version check file. ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX ATCORE VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/atcore_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/AtCoreConfigVersion.cmake" SOVERSION ${PROJECT_VERSION_MAJOR} ) # Get the version from git if it's a git repository IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) FIND_PACKAGE(Git) IF(GIT_FOUND) EXECUTE_PROCESS( COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" OUTPUT_VARIABLE "GIT_VERSION" ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) MESSAGE( STATUS "Git Commit: ${GIT_VERSION}" ) add_definitions( -DGIT_REVISION="${GIT_VERSION}") ENDIF(GIT_FOUND) ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) add_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_URL_CAST_FROM_STRING) find_package(Qt5 REQUIRED COMPONENTS Core SerialPort Charts Widgets ) include(ECMPoQmTools) if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ecm_install_po_files_as_qm(po) endif() # Set default build type to be release if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX OR CMAKE_COMPILER_IS_CLANG) # Turn warnings on by default set(CMAKE_CXX_FLAGS "-Wall -Wextra") # Set debug mode to use -g set(CMAKE_CXX_FLAGS_DEBUG "-g") # Use optimization set(CMAKE_CXX_FLAGS_RELEASE "-O3") endif() include_directories(${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_AUTOMOC ON) add_subdirectory(src) #optional Parts. if(BUILD_GUI) add_subdirectory(testclient) endif() if (BUILD_TESTS) add_subdirectory(unittests) endif() if (BUILD_DOCS) add_subdirectory(doc) endif() install(FILES "${CMAKE_CURRENT_BINARY_DIR}/AtCoreConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/atcore_version.h" DESTINATION "${INCLUDE_INSTALL_DIR}/AtCore/" COMPONENT Devel ) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/doc/contrib.md b/doc/contrib.md index 5175ac7..5deefb0 100644 --- a/doc/contrib.md +++ b/doc/contrib.md @@ -1,61 +1,69 @@ # Contributing To AtCore AtCore is an open source project and all open source projects need contrubitors. Thank you for taking the time to read this document and Thank you for your future contributions to this project. ---- ## Prerequisites In order to contrbute directly to AtCore you will need to have a [KDE Identity]. You should create a fork on [KDE Invent] to work within. You may wish to join us on [IRC] or [Telegram]. ## Ways you can contribute There are several ways you can contribute - Submit or Help to confirm bugs in our [Bug Tracker]. - Find Errors in the documentation or help to otherwise improve it - Help users solve their issues - Help to review Code (Watch the project on [KDE Invent]) - Commit new code or code to fix bugs. ## General Contribution Workflow The Following Is the General work flow for most contrubitions - Create changes on your local fork in a new branch - - When your ready to submit your change create a Merge Request on [KDE Invent] + - Format your code by building the clang-format target. + - Submit your change create a Merge Request on [KDE Invent] - Wait for review - Update your commits with any changes, and update your Merge Request after. - Mark all your "Issues" resolved in your MR. - Repeat Review / Update until changes is accepted. - A Maintainer will Merge when the changes is ready. ### General Coding Guidelines The following guidelines apply to all submited code. - Follow the [KDE style guidelines] - Use constant referances when possible - Includes should be alphabetical. - - Run the style script before you commit. + - Use the target clang-format before you commit to format your code. - Headers should use `#pragma once`. - Auto should not be used if the type is not explict. - Doxygen comments should be created/updated with code. - Objects should have logical varible and function names - - Code should always be readable, comment your code when it makes sense. + - Code should always be readable, comment your code when it makes sense. + +#### Using Clang format + You can use the make target clang-format to format your source code correctly. + to do so you must first have run cmake to generate build file. + In your IDE you can build the target "clang-format" + Or manually from inside your build directory with `make clang-format` ### Commit Guidelines Keeping a clean project history requires that we take care when choosing how we will commit our code. Consider the following when creating commits. ALL COMMITS MUST BE REVIEWED BEFORE PUSHING TO MASTER. - Follow the [KDE commit guidelines] + - Format your code using the clang-format make target (see above) - Reviewers: rizzitello, patrickelectric, laysrodrigues, tcanabrava - Be sure to make any review issues as resolved. - Keep your base upto date. - Amend your local commits to fix review issues. - - Always Ammend commits to update them + - Always Ammend commits to update them - Never fix a commit with another commit. - Update your commits with `git commit --amend` - Update your MR with `git push --force` - Revisions require a majority acceptance rate before landing - Your Merge Request will be merged when your code when its ready [IRC]: https://webchat.freenode.net/ [Telegram]: https://telegram.me/KDEAtelier [Bug Tracker]: https://bugs.kde.org/enter_bug.cgi?product=Atelier&component=AtCore [KDE Identity]: https://identity.kde.org/ [KDE Invent]: https://invent.kde.org [KDE style guidelines]: https://community.kde.org/Policies/Kdelibs_Coding_Style [KDE commit guidelines]: https://community.kde.org/Policies/Commit_Policy diff --git a/scripts/pre-commit.style b/scripts/pre-commit.style deleted file mode 100755 index 422328b..0000000 --- a/scripts/pre-commit.style +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# To install: -# - Move to .git/hooks/ -# - Rename it pre-commit -# - Turn executatble $ chmod +x pre-commit -# Check if this is the initial commit -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - echo "pre-commit: About to create a new commit..." - against=HEAD -else - echo "pre-commit: About to create the first commit..." - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# Use git diff-index to check for whitespace errors -echo "pre-commit: Running style correction script..." - -files=$(git diff-index --name-status --cached HEAD | grep -v ^D | cut -c3-) -echo $files -if [ "$files" != "" ] -then - sh scripts/style.sh - git add $files -fi - diff --git a/scripts/style.sh b/scripts/style.sh deleted file mode 100644 index 7eb0ae0..0000000 --- a/scripts/style.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/bin/sh - -# Apply kdelibs coding style to all c, cpp and header files in and below the current directory -# -# The coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style -# -# Requirements: -# - installed astyle, with patches below -# -# IMPORTANT: astyle misparses the Qt "keywords" like foreach and Q_FOREACH, which -# makes it style wrongly not just the space after the keyword, but also everything -# inside the parenthesis, leading to things like: -# Q_FOREACH(const QString & it, l) // note the space after the '&'. -# -# To fix this, patch astyle with http://www.davidfaure.fr/kde/astyle_qt.diff -# Mentionned upstream in https://sourceforge.net/p/astyle/bugs/154/ -# -# Another feature was implemented: removing spaces before ',' and ';'. -# Apply http://www.davidfaure.fr/kde/astyle_comma.diff -# This has been sent upstream in https://sourceforge.net/p/astyle/bugs/100/ -# -# Instructions for OpenSuSE users: -# zypper si astyle -# cd ~/rpmbuild/SOURCES ; wget http://www.davidfaure.fr/kde/astyle_qt.diff -# wget http://www.davidfaure.fr/kde/astyle_comma.diff -# cd ../SPECS ; wget http://www.davidfaure.fr/kde/astyle.spec.diff -# patch astyle.spec < astyle.spec.diff -# rpmbuild -ba astyle.spec -# sudo rpm -Uvh --force ~/rpmbuild/RPMS/x86_64/astyle-*.rpm - -files=`find -type f -name '*.c' -or -name '*.cpp' -or -name '*.cc' -or -name '*.h'` -if [ -z "$files" ]; then - # nothing to do - exit 0 -fi - -astyle -n -Q \ - --indent=spaces=4 --style=otbs \ - --indent-labels --pad-oper --unpad-paren --pad-header \ - --keep-one-line-statements \ - --convert-tabs \ - --indent-preprocessor \ - --align-pointer=name \ - $files - -# --max-code-length=100 is not used, on purpose. It's a hard limit, sometimes making things -# less readable than if the code is kept on a single line. 100 is just a recommendation -# in the coding style. - -# Watch out for things that lead to method implementations being parsed as if inside other methods, -# e.g. due to '{' inside #ifdef and #else and '}' outside. -grep '^\S* \S*::.*) {$' $files && echo "WARNING: check for wrong '{' placement in method definitions, in above grep results" - -# Remove old emacs mode-lines -perl -pi -e '$_ = "" if /c-basic-offset: [1-8]/' $files - -# Remove old kate mode-lines -perl -pi -e '$_ = "" if /kate: .*indent-width/ || /kate:.*tab-width/' $files - -# Remove old vim mode-lines -perl -pi -e '$_ = "" if /\/\/.* vim:/' $files -# They are often in a two-liner C comment, so we need a bit of perl magic to remove these -perl - $files <; - if( \$str =~ m/vim:/ ) { - #print STDERR "Removing multi-line vim modeline from \$file\n"; - \$str =~ s!/\*\**\s*\**\s*vim:[^\n]*\n\s*\*/!!smg; - seek F, 0, 0; - print F \$str; - truncate F, tell(F); - } - close F; - } -EOF - -# Remove consecutive blank lines -perl - $files <; - if (\$str =~ s/\s*\n\s*\n\s*\n\n*/\n\n/smg ) { - seek F, 0, 0; - print F \$str; - truncate F, tell(F); - } - close F; - } -EOF - -# TODO: add command-line option to trigger this -# It's not wanted when working on a fix -#git commit -q -a -m "Code reformatted using kde-dev-scripts/astyle-kdelibs. -#Use git blame -w `git rev-parse --short HEAD` to show authorship as it was before this commit." - diff --git a/src/core/atcore.cpp b/src/core/atcore.cpp index 2b03a79..8d91931 100644 --- a/src/core/atcore.cpp +++ b/src/core/atcore.cpp @@ -1,959 +1,948 @@ /* AtCore Copyright (C) <2016 - 2019> 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 #include +#include #include +#include +#include +#include +#include #include "atcore.h" +#include "atcore_default_folders.h" #include "atcore_version.h" -#include "seriallayer.h" #include "gcodecommands.h" #include "printthread.h" -#include "atcore_default_folders.h" +#include "seriallayer.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 AtCore::AtCorePrivate { /** firmwarePlugin: pointer to firmware plugin */ IFirmware *firmwarePlugin = nullptr; /** serial: pointer to the serial layer */ SerialLayer *serial = nullptr; /** pluginLoader: QPluginLoader */ QPluginLoader pluginLoader; /** plugins: Map of plugins name / path */ QMap plugins; /** lastMessage: lastMessage from the printer */ QByteArray lastMessage; /** lastCommand: the last command sent to the printer */ QString lastCommand; /** extruderCount: extruder count */ int extruderCount = 1; /** temperature: Temperature object */ std::shared_ptr temperature = nullptr; /** autoTemperatureReport: True if using auto Temperature Reporting*/ bool autoTemperatureReport = false; /** bedDeform: BedDeform object */ std::shared_ptr bedDeform = nullptr; /** commandQueue: the list of commands to send to the printer */ QStringList commandQueue; /** ready: True if printer is ready for a command */ bool ready = false; /** temperatureTimer: timer connected to the checkTemperature function */ QTimer temperatureTimer; /** sdPrintProgressTimer: timer used to check in on sdJobs */ QTimer sdPrintProgressTimer; /** percentage: print job percent */ float percentage = 0.0; /** posString: stored string from last M114 return */ QByteArray posString; /** printerState: State of the Printer */ AtCore::STATES printerState = AtCore::DISCONNECTED; /** seralPorts: Detected serial Ports */ QStringList serialPorts; /** serialTimer: Timer connected to locateSerialPorts */ QTimer serialTimer; /** sdCardMounted: True if Sd Card is mounted. */ bool sdCardMounted = false; /** sdCardReadingFileList: True while getting file names from sd card */ bool sdCardReadingFileList = false; /** sdCardPrinting: True if currently printing from sd card. */ bool sdCardPrinting = false; /** sdCardFileName: name of file being used from sd card. */ QString sdCardFileName; /** sdCardFileList: List of files on sd card. */ QStringList sdCardFileList; /** tempMultiString: Hold temp returns for multiline returns when needed */ QStringList tempMultiString; }; -AtCore::AtCore(QObject *parent) : - QObject(parent), - d(new AtCorePrivate) +AtCore::AtCore(QObject *parent) + : QObject(parent) + , d(new AtCorePrivate) { d->temperature.reset(new Temperature); d->bedDeform.reset(new BedDeform); - //Register MetaTypes + // Register MetaTypes qRegisterMetaType("AtCore::STATES"); setState(AtCore::STATES::DISCONNECTED); - //Connect our Timers + // Connect our Timers connect(&d->sdPrintProgressTimer, &QTimer::timeout, this, &AtCore::sdCardPrintStatus); connect(&d->serialTimer, &QTimer::timeout, this, &AtCore::locateSerialPort); connect(&d->temperatureTimer, &QTimer::timeout, this, &AtCore::checkTemperature); //<<<<<>>>>>>> - connect(d->bedDeform.get(), &BedDeform::dataChanged, this, [](const QVariantList & bedData) { - qDebug() << bedData; - }); + connect(d->bedDeform.get(), &BedDeform::dataChanged, this, [](const QVariantList &bedData) { qDebug() << bedData; }); - //Attempt to find our plugins + // Attempt to find our plugins qCDebug(ATCORE_PLUGIN) << "Detecting Plugin path"; QStringList paths = AtCoreDirectories::pluginDir; - //add our current runtime path + // add our current runtime path paths.prepend(qApp->applicationDirPath() + QStringLiteral("/../Plugins/AtCore")); paths.prepend(qApp->applicationDirPath() + QStringLiteral("/AtCore")); paths.prepend(qApp->applicationDirPath() + QStringLiteral("/plugins")); for (const auto &path : paths) { qCDebug(ATCORE_PLUGIN) << "Checking: " << path; - QMap tempMap = findFirmwarePlugins(path); + QMap tempMap = findFirmwarePlugins(path); if (!tempMap.isEmpty()) { d->plugins = tempMap; emit availableFirmwarePluginsChanged(); return; } } setState(AtCore::STATES::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; } IFirmware *AtCore::firmwarePlugin() const { return d->firmwarePlugin; } void AtCore::close() { exit(0); } Temperature *AtCore::temperature() { return d->temperature.get(); } void AtCore::findFirmware(const QByteArray &message) { emit receivedMessage(message); 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 + // remove leading space fwName.remove(0, 1); } if (fwName.contains(QChar::fromLatin1(' '))) { - //check there is a space or dont' resize + // 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 + // 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. + // Plugin was not loaded, Provide some debug info. qCDebug(ATCORE_CORE) << "Plugin Loading: Failed."; qCDebug(ATCORE_CORE) << d->pluginLoader.errorString(); setState(AtCore::STATES::CONNECTING); } else { - //Plugin was loaded successfully. + // Plugin was loaded successfully. d->firmwarePlugin = qobject_cast(d->pluginLoader.instance()); firmwarePlugin()->init(this); disconnect(d->serial, &SerialLayer::receivedCommand, this, {}); connect(d->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")) { setTemperatureTimerInterval(5000); } setState(IDLE); emit atcoreMessage(tr("Connected to printer using %1 plugin").arg(d->firmwarePlugin->name())); } } else { qCDebug(ATCORE_CORE) << "Plugin:" << fwName << ": Not found."; emit atcoreMessage(tr("No plugin found for %1.").arg(fwName)); } } void AtCore::waitForPrinterReboot(const QByteArray &message, const QString &fwName) { emit receivedMessage(message); if (message.isEmpty()) { return; } if (message.contains("Grbl")) { loadFirmwarePlugin(QString::fromLatin1("grbl")); } else if (message.contains("Smoothie")) { loadFirmwarePlugin(QString::fromLatin1("smoothie")); } else if (message.contains("start")) { if (!d->plugins.contains(fwName)) { disconnect(d->serial, &SerialLayer::receivedCommand, this, {}); connect(d->serial, &SerialLayer::receivedCommand, this, &AtCore::findFirmware); QTimer::singleShot(500, this, &AtCore::requestFirmware); } else { loadFirmwarePlugin(fwName); } } - } bool AtCore::newConnection(const QString &port, int baud, const QString &fwName, bool disableROC) { if (disableROC) { disableResetOnConnect(port); } d->serial = new SerialLayer(port, baud, this); connect(d->serial, &SerialLayer::serialError, this, &AtCore::handleSerialError); if (serialInitialized() && d->serial->isWritable()) { setState(AtCore::STATES::CONNECTING); connect(d->serial, &SerialLayer::pushedCommand, this, &AtCore::newCommand); if (!disableROC) { emit atcoreMessage(tr("Waiting for machine restart")); - connect(d->serial, &SerialLayer::receivedCommand, this, [this, fwName](const QByteArray & message) { - waitForPrinterReboot(message, fwName); - }); + connect(d->serial, &SerialLayer::receivedCommand, this, [this, fwName](const QByteArray &message) { waitForPrinterReboot(message, fwName); }); } else { loadFirmwarePlugin(fwName); } if (d->serialTimer.isActive()) { d->serialTimer.stop(); } return true; } 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 d->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. + // 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); } } int AtCore::serialTimerInterval() const { return d->serialTimer.interval(); } void AtCore::setSerialTimerInterval(int newTime) { newTime = std::max(newTime, 0); if (newTime != d->serialTimer.interval()) { d->serialTimer.setInterval(newTime); emit serialTimerIntervalChanged(newTime); } if (newTime == 0 && d->serialTimer.isActive()) { d->serialTimer.stop(); } else { d->serialTimer.start(newTime); } } int AtCore::temperatureTimerInterval() const { return d->temperatureTimer.interval(); } void AtCore::setTemperatureTimerInterval(int newTime) { newTime = std::max(newTime, 0); if (newTime != d->temperatureTimer.interval()) { d->temperatureTimer.setInterval(newTime); emit temperatureTimerIntervalChanged(newTime); } if (!newTime && d->temperatureTimer.isActive()) { d->temperatureTimer.stop(); } else { d->temperatureTimer.start(newTime); } } void AtCore::setAutoTemperatureReport(bool autoReport) { if (autoReport == d->autoTemperatureReport) { return; } d->autoTemperatureReport = autoReport; emit autoTemperatureReportChanged(autoReport); if (autoReport) { setTemperatureTimerInterval(0); d->commandQueue.removeAll(GCode::toCommand(GCode::M105)); setAutoCheckTemperatureInterval(5); } else { setAutoCheckTemperatureInterval(0); setTemperatureTimerInterval(5000); } - } void AtCore::setAutoCheckTemperatureInterval(int newTime) { if (state() >= 2 && state() != AtCore::ERRORSTATE) { pushCommand(GCode::toCommand(GCode::M155, QString::number(newTime))); } emit autoCheckTemperatureIntervalChanged(newTime); } bool AtCore::autoTemperatureReport() const { return d->autoTemperatureReport; } void AtCore::newMessage(const QByteArray &message) { d->lastMessage = message; if (d->lastMessage.contains(QString::fromLatin1("Cap:AUTOREPORT_TEMP:1").toLocal8Bit())) { setAutoTemperatureReport(true); } if (d->lastCommand.startsWith(GCode::toCommand(GCode::GCode::G29))) { if (d->lastMessage.contains("ok")) { d->bedDeform.get()->decodeDeform(d->tempMultiString); } d->tempMultiString.append(QString::fromLatin1(d->lastMessage)); } - //Check if the message has current coordinates. - if (d->lastCommand.startsWith(GCode::toCommand(GCode::MCommands::M114)) - && d->lastMessage.startsWith(QString::fromLatin1("X:").toLocal8Bit())) { + // Check if the message has current coordinates. + if (d->lastCommand.startsWith(GCode::toCommand(GCode::MCommands::M114)) && d->lastMessage.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 + // Check if have temperature info and decode it if (d->lastMessage.contains("T:") || d->lastMessage.contains("B:")) { temperature()->decodeTemp(d->lastMessage); } emit receivedMessage(d->lastMessage); } void AtCore::newCommand(const QByteArray &command) { emit pushedCommand(command); } void AtCore::setRelativePosition() { pushCommand(GCode::toCommand(GCode::GCommands::G91)); } void AtCore::setAbsolutePosition() { pushCommand(GCode::toCommand(GCode::GCommands::G90)); } float AtCore::percentagePrinted() const { return d->percentage; } void AtCore::print(const QString &fileName, bool sdPrint) { if (state() == AtCore::STATES::CONNECTING) { qCDebug(ATCORE_CORE) << "Load a firmware plugin to print."; return; } - //Start a print job. + // Start a print job. setState(AtCore::STATES::STARTPRINT); - //Only try to print from Sd if the firmware has support for sd cards + // 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. + // Printing from the sd card requires us to send some M commands. pushCommand(GCode::toCommand(GCode::MCommands::M23, fileName)); d->sdCardFileName = fileName; pushCommand(GCode::toCommand(GCode::MCommands::M24)); setState(AtCore::STATES::BUSY); d->sdCardPrinting = true; d->sdPrintProgressTimer.start(5000); 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. + // 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. auto thread = new QThread(this); auto 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) { -//Be sure our M112 is first in the queue. + // Be sure our M112 is first in the queue. if (comm == GCode::toCommand(GCode::MCommands::M112)) { d->commandQueue.prepend(comm); } else { d->commandQueue.append(comm); } if (d->ready) { - //The printer is ready for a command now so push one. + // The printer is ready for a command now so push one. processQueue(); } } void AtCore::closeConnection() { if (serialInitialized()) { if (AtCore::state() == AtCore::STATES::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. + // 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::STATES::STOP); } if (firmwarePluginLoaded()) { disconnect(firmwarePlugin(), &IFirmware::readyForCommand, this, &AtCore::processQueue); disconnect(d->serial, &SerialLayer::receivedCommand, this, &AtCore::newMessage); if (d->autoTemperatureReport) { blockSignals(true); setAutoTemperatureReport(false); blockSignals(false); } setTemperatureTimerInterval(0); - //Attempt to unload the firmware plugin. + // 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); d->firmwarePlugin = nullptr; } - //Do not reset the connect on disconnect when closing this will cause a reset on connect for the next connection. + // Do not reset the connect on disconnect when closing this will cause a reset on connect for the next connection. disconnect(d->serial, &SerialLayer::serialError, this, &AtCore::handleSerialError); disconnect(d->serial, &SerialLayer::pushedCommand, this, &AtCore::newMessage); d->serial->close(); - //Clear our copy of the sdcard filelist + // Clear our copy of the sdcard filelist clearSdCardFileList(); setState(AtCore::STATES::DISCONNECTED); d->serialTimer.start(); } } AtCore::STATES AtCore::state() { 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).toString(), - QVariant::fromValue(state).toString()); + qCDebug(ATCORE_CORE) << QStringLiteral("Atcore state changed from [%1] to [%2]").arg(QVariant::fromValue(d->printerState).toString(), QVariant::fromValue(state).toString()); d->printerState = state; if (state == AtCore::STATES::FINISHEDPRINT && d->sdCardPrinting) { - //Clean up the sd card print + // Clean up the sd card print d->sdCardPrinting = false; if (d->sdPrintProgressTimer.isActive()) { d->sdPrintProgressTimer.stop(); } } emit stateChanged(d->printerState); } } void AtCore::stop() { - //Stop a print job + // Stop a print job setState(AtCore::STATES::STOP); d->commandQueue.clear(); if (d->sdCardPrinting) { stopSdPrint(); } setExtruderTemp(0, 0); setBedTemp(0); home(AtCore::AXES::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. + // 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::STATES::BUSY) { if (!d->sdCardPrinting) { - //Stop our running print thread + // Stop our running print thread setState(AtCore::STATES::STOP); } } pushCommand(GCode::toCommand(GCode::MCommands::M112)); } void AtCore::stopSdPrint() { - //Stop an SdCard Print. + // Stop an SdCard Print. pushCommand(GCode::toCommand(GCode::MCommands::M25)); d->sdCardFileName = QString(); pushCommand(GCode::toCommand(GCode::MCommands::M23, d->sdCardFileName)); AtCore::setState(AtCore::STATES::FINISHEDPRINT); AtCore::setState(AtCore::STATES::IDLE); } void AtCore::requestFirmware() { if (serialInitialized()) { - //ensure M115 is sent on cold connect. + // ensure M115 is sent on cold connect. d->commandQueue.clear(); d->ready = true; qCDebug(ATCORE_CORE) << "Sending " << GCode::description(GCode::MCommands::M115); pushCommand(GCode::toCommand(GCode::MCommands::M115)); } else { qCDebug(ATCORE_CORE) << "There is no open device to send commands"; } } bool AtCore::firmwarePluginLoaded() const { return firmwarePlugin(); } QMap AtCore::findFirmwarePlugins(const QString &path) { QMap detectedPlugins; for (const QString &f : QDir(path).entryList({AtCoreDirectories::pluginExtFilter}, QDir::Files)) { QString file = f; file = file.split(QStringLiteral(".")).at(0).toLower().simplified(); if (file.startsWith(QStringLiteral("lib"))) { file = file.remove(QStringLiteral("lib")); } QString pluginString = QStringLiteral("%1/%2").arg(path, 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::MCommands::M25)); } - //Push the command to request current coordinates. - //This will be read by AtCore::newMessage and stored for use on resume. + // Push the command to request current coordinates. + // This will be read by AtCore::newMessage and stored for use on resume. pushCommand(GCode::toCommand(GCode::MCommands::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::MCommands::M24)); } else { - //Move back to previous coordinates. + // Move back to previous coordinates. pushCommand(GCode::toCommand(GCode::GCommands::G0, QString::fromLatin1(d->posString))); } setState(AtCore::BUSY); } /*~~~~~Control Slots ~~~~~~~~*/ void AtCore::home() { pushCommand(GCode::toCommand(GCode::GCommands::G28)); } void AtCore::home(uchar axis) { QString args; if (axis & AtCore::AXES::X) { args.append(QStringLiteral("X0 ")); } if (axis & AtCore::AXES::Y) { args.append(QStringLiteral("Y0 ")); } if (axis & AtCore::AXES::Z) { args.append(QStringLiteral("Z0")); } pushCommand(GCode::toCommand(GCode::GCommands::G28, args)); } void AtCore::setExtruderTemp(uint temp, uint extruder, bool andWait) { temp = std::min(temp, 10000); extruder = std::min(extruder, 10000); if (andWait) { pushCommand(GCode::toCommand(GCode::MCommands::M109, QString::number(temp), QString::number(extruder))); } else { pushCommand(GCode::toCommand(GCode::MCommands::M104, QString::number(extruder), QString::number(temp))); } } void AtCore::setBedTemp(uint temp, bool andWait) { temp = std::min(temp, 10000); if (andWait) { pushCommand(GCode::toCommand(GCode::MCommands::M190, QString::number(temp))); } else { pushCommand(GCode::toCommand(GCode::MCommands::M140, QString::number(temp))); } } void AtCore::setFanSpeed(uint speed, uint fanNumber) { speed = std::min(speed, 10000); fanNumber = std::min(fanNumber, 10000); pushCommand(GCode::toCommand(GCode::MCommands::M106, QString::number(fanNumber), QString::number(speed))); } void AtCore::setPrinterSpeed(uint speed) { speed = std::min(speed, 10000); pushCommand(GCode::toCommand(GCode::MCommands::M220, QString::number(speed))); } void AtCore::setFlowRate(uint speed) { speed = std::min(speed, 10000); pushCommand(GCode::toCommand(GCode::MCommands::M221, QString::number(speed))); } void AtCore::move(AtCore::AXES axis, double arg) { const auto axisAsString = QMetaEnum::fromType().valueToKey(axis); move(QLatin1Char(axisAsString[0]), arg); } void AtCore::move(QLatin1Char axis, double arg) { - //Using QString::number(double, format, precision) - //f = 'format as [-]9.9' - //3 = use 3 decimal precision + // Using QString::number(double, format, precision) + // f = 'format as [-]9.9' + // 3 = use 3 decimal precision pushCommand(GCode::toCommand(GCode::GCommands::G1, QStringLiteral("%1 %2").arg(axis).arg(QString::number(arg, 'f', 3)))); } 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; } d->lastCommand = d->commandQueue.takeAt(0); if (firmwarePluginLoaded()) { d->serial->pushCommand(firmwarePlugin()->translate(d->lastCommand)); } else { d->serial->pushCommand(d->lastCommand.toLocal8Bit()); } d->ready = false; } void AtCore::checkTemperature() { - //One request for the temperature in the queue at a time. + // One request for the temperature in the queue at a time. if (d->commandQueue.contains(GCode::toCommand(GCode::MCommands::M105))) { return; } pushCommand(GCode::toCommand(GCode::MCommands::M105)); } void AtCore::showMessage(const QString &message) { if (!message.isEmpty()) { pushCommand(GCode::toCommand((GCode::MCommands::M117), message)); } } void AtCore::setUnits(AtCore::UNITS units) { switch (units) { case AtCore::UNITS::METRIC: pushCommand(GCode::toCommand(GCode::GCommands::G21)); break; case AtCore::UNITS::IMPERIAL: pushCommand(GCode::toCommand(GCode::GCommands::G20)); break; } } QStringList AtCore::portSpeeds() const { return d->serial->validBaudRates(); } void AtCore::disableMotors(uint delay) { - //Disables motors + // Disables motors if (delay) { pushCommand(GCode::toCommand(GCode::MCommands::M84, QString::number(delay))); } else { pushCommand(GCode::toCommand(GCode::MCommands::M84)); } } -//Most firmwares will not report if an sdcard is mounted on boot. +// 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); } } void AtCore::getSDFileList() { pushCommand(GCode::toCommand(GCode::MCommands::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); } void AtCore::clearSdCardFileList() { d->sdCardFileList.clear(); emit sdCardFileListChanged(d->sdCardFileList); } void AtCore::sdDelete(const QString &fileName) { if (d->sdCardFileList.contains(fileName)) { pushCommand(GCode::toCommand(GCode::MCommands::M30, fileName)); getSDFileList(); } else { qCDebug(ATCORE_CORE) << "Delete failed file not found:" << fileName; } } void AtCore::mountSd(uint slot) { pushCommand(GCode::toCommand(GCode::MCommands::M21, QString::number(slot))); } void AtCore::umountSd(uint slot) { pushCommand(GCode::toCommand(GCode::MCommands::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. + // One request for the Sd Job status in the queue at a time. if (d->commandQueue.contains(GCode::toCommand(GCode::MCommands::M27))) { return; } pushCommand(GCode::toCommand(GCode::MCommands::M27)); } void AtCore::disableResetOnConnect(const QString &port) { #if defined(Q_OS_UNIX) -//should work on all unix' + // should work on all unix' QProcess process(this); QStringList args({QStringLiteral("-F/dev/%1").arg(port), QStringLiteral("-hupcl")}); process.start(QStringLiteral("stty"), args); process.waitForFinished(500); - connect(&process, &QProcess::errorOccurred, this, [&process] { - qCDebug(ATCORE_CORE) << "Stty Error:" << process.errorString(); - }); + connect(&process, &QProcess::errorOccurred, this, [&process] { qCDebug(ATCORE_CORE) << "Stty Error:" << process.errorString(); }); #elif defined(Q_OS_WIN) - //TODO: Disable hangup on windows. + // TODO: Disable hangup on windows. #endif } void AtCore::handleSerialError(QSerialPort::SerialPortError error) { QString errorString; switch (error) { case (QSerialPort::SerialPortError::DeviceNotFoundError): errorString = tr("Device not found"); break; case (QSerialPort::SerialPortError::WriteError): errorString = tr("Unable to write to device"); break; case (QSerialPort::SerialPortError::ReadError): errorString = tr("Unable to read from device"); break; case (QSerialPort::SerialPortError::ResourceError): case (QSerialPort::SerialPortError::TimeoutError): errorString = tr("The device no longer available"); closeConnection(); break; case (QSerialPort::SerialPortError::UnsupportedOperationError): errorString = tr("Device does not support the operation"); break; case (QSerialPort::SerialPortError::UnknownError): errorString = tr("Unknown Error"); break; default: - //Not Directly processed errors - //QSerialPort::NoError, No error has happened - //QSerialPort::PermissionError), Already handled. - //QSerialPort::OpenError), Already handled. - //QSerialPort::NotOpenError, SerialLayer destroyed if not connected. - //QSerialPort::ParityError, Obsolete. Qt Docs "We strongly advise against using it in new code." - //QSerialPort::FramingError, Obsolete. Qt Docs "We strongly advise against using it in new code." - //QSerialPort::BreakConditionError, Obsolete. Qt Docs "We strongly advise against using it in new code." + // Not Directly processed errors + // QSerialPort::NoError, No error has happened + // QSerialPort::PermissionError), Already handled. + // QSerialPort::OpenError), Already handled. + // QSerialPort::NotOpenError, SerialLayer destroyed if not connected. + // QSerialPort::ParityError, Obsolete. Qt Docs "We strongly advise against using it in new code." + // QSerialPort::FramingError, Obsolete. Qt Docs "We strongly advise against using it in new code." + // QSerialPort::BreakConditionError, Obsolete. Qt Docs "We strongly advise against using it in new code." return; - };//End of Switch + }; // End of Switch qCDebug(ATCORE_CORE) << "SerialError:" << errorString; emit atcoreMessage(QStringLiteral("SerialError: %1").arg(errorString)); } std::shared_ptr AtCore::bedDeform() { return d->bedDeform; } diff --git a/src/core/atcore.h b/src/core/atcore.h index 97e61fb..d4f8045 100644 --- a/src/core/atcore.h +++ b/src/core/atcore.h @@ -1,666 +1,665 @@ /* AtCore Copyright (C) <2016 - 2019> 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 . */ #pragma once -#include #include #include #include +#include -#include "ifirmware.h" -#include "temperature.h" #include "atcore_export.h" #include "beddeform.h" +#include "ifirmware.h" +#include "temperature.h" class SerialLayer; class IFirmware; class QTime; /** * @brief The AtCore class * aims to provides a high level interface for serial based gcode devices
* * #### General Workflow * - Connect to a serial port with newConnection() * - Send commands to the device (pushCommand(), print(), ...) * - AtCore::close() when you are all done. * #### How AtCore Finds Plugins. * AtCore will check each directory below for plugins. * 1. QApplication::applicationDirPath/plugins (runtime) * 2. QApplication::applicationDirPath/AtCore (runtime) * 3. QApplication::applicationDirPath/../PlugIns/AtCore (runtime) * 4. Fullpath of KDE_PLUGIN_DIR (buildtime) * 5. Qt Plugin path/AtCore (runtime) * 6. ECM set KDE PLUGIN DIR (buildtime) * 7. Build Dir/plugins (buildtime) */ class ATCORE_EXPORT AtCore : public QObject { Q_OBJECT Q_PROPERTY(QString version READ version CONSTANT) Q_PROPERTY(QStringList availableFirmwarePlugins READ availableFirmwarePlugins NOTIFY availableFirmwarePluginsChanged) Q_PROPERTY(int extruderCount READ extruderCount WRITE setExtruderCount NOTIFY extruderCountChanged) Q_PROPERTY(int temperatureTimerInterval READ temperatureTimerInterval WRITE setTemperatureTimerInterval NOTIFY temperatureTimerIntervalChanged); Q_PROPERTY(int serialTimerInterval READ serialTimerInterval WRITE setSerialTimerInterval NOTIFY serialTimerIntervalChanged) Q_PROPERTY(QStringList serialPorts READ serialPorts NOTIFY portsChanged) Q_PROPERTY(float percentagePrinted READ percentagePrinted NOTIFY printProgressChanged) Q_PROPERTY(QStringList portSpeeds READ portSpeeds CONSTANT) Q_PROPERTY(QString connectedPort READ connectedPort CONSTANT) Q_PROPERTY(AtCore::STATES state READ state WRITE setState NOTIFY stateChanged) Q_PROPERTY(bool sdMount READ isSdMounted WRITE setSdMounted NOTIFY sdMountChanged) Q_PROPERTY(QStringList sdFileList READ sdFileList NOTIFY sdCardFileListChanged) Q_PROPERTY(bool autoTemperatureReport READ autoTemperatureReport WRITE setAutoTemperatureReport NOTIFY autoTemperatureReportChanged) Q_PROPERTY(Temperature *temperature READ temperature CONSTANT) friend class AtCoreTests; - //Add friends as Sd Card support is extended to more plugins. + // Add friends as Sd Card support is extended to more plugins. friend class RepetierPlugin; friend class MarlinPlugin; - //friend class SmoothiePlugin; - //friend class TeacupPlugin; - //friend class AprinterPlugin; - //friend class SprinterPlugin; + // friend class SmoothiePlugin; + // friend class TeacupPlugin; + // friend class AprinterPlugin; + // friend class SprinterPlugin; public: /** * @brief STATES enum Possible states the printer can be in */ enum STATES { - DISCONNECTED, //!< Not Connected to a printer, initial state - CONNECTING, //! bedDeform(); /** * @brief The temperature of the current hotend as told by the Firmware. */ Temperature *temperature(); /** - * @brief Return the amount of miliseconds the serialTimer is set to. 0 = Disabled - */ + * @brief Return the amount of miliseconds the serialTimer is set to. 0 = Disabled + */ int serialTimerInterval() const; /** - * @brief Return the amount of miliseconds the temperatureTimer is set to. 0 = Disabled - */ + * @brief Return the amount of miliseconds the temperatureTimer is set to. 0 = Disabled + */ int temperatureTimerInterval() const; /** * @brief Attempt to Mount an sd card * @param slot: Sd card Slot on machine (0 is default) */ Q_INVOKABLE void mountSd(uint slot = 0); /** * @brief Attempt to Unmount an sd card * @param slot: Sd card Slot on machine (0 is default) */ Q_INVOKABLE void umountSd(uint slot = 0); /** * @brief sdFileList * @return List of files on the sd card. */ QStringList sdFileList(); /** * @brief Check if an sd card is mounted on the printer * @return True if card mounted */ bool isSdMounted() const; /** * @brief Check if using automatic Temperature reporting to monitor temperatures * @return True if using automatic temperature reporting */ bool autoTemperatureReport() const; signals: /** * @brief Message emit from atcore these should be displayed to the user for debug. * * Possable Messages Are: * - Waiting for firmware detect. * - No Plugin found for (detected FW) * - Failed to open device in Read / Write mode. * - Device Errors. * @param msg: the message. */ void atcoreMessage(const QString &msg); /** * @brief New number of extruders * @sa extruderCount(), setExtruderCount(int newCount) */ void extruderCountChanged(const int newCount); /** * @brief Print job's precentage changed. * @param newProgress : Message * @sa percentagePrinted() */ void printProgressChanged(const float newProgress); /** * @brief New message was received from the printer * @param message: Message that was received */ void receivedMessage(const QByteArray &message); /** - * @brief New interval for serial timer - * @sa setSerialTimerInterval() - */ + * @brief New interval for serial timer + * @sa setSerialTimerInterval() + */ void serialTimerIntervalChanged(const int newTime); /** - * @brief New interval for temperature timer - * @sa setTemperatureTimerInterval() - */ + * @brief New interval for temperature timer + * @sa setTemperatureTimerInterval() + */ void temperatureTimerIntervalChanged(const int newTime); /** * @brief use of automatic temperature reporting has changed * @param autoReport: True if using automatic Reporting mode. */ void autoTemperatureReportChanged(bool autoReport); /** - * @brief New interval for automatic temperature report - * @sa setautoTemperatureReport() - */ + * @brief New interval for automatic temperature report + * @sa setautoTemperatureReport() + */ void autoCheckTemperatureIntervalChanged(const int newTime); /** * @brief The Printer's State Changed * @param newState : the new state of the printer * @sa setState(), state(), AtCore::STATES */ void stateChanged(AtCore::STATES newState); /** * @brief Available serialports Changed */ void portsChanged(const QStringList &portList); /** * @brief Sd Card Mount Changed */ void sdMountChanged(bool newState); /** * @brief The files on the sd card have changed. */ void sdCardFileListChanged(const QStringList &fileList); /** * @brief pushedCommand via serialLayer connect this to your log to see send commands * @param comm: the command sent. */ void pushedCommand(const QByteArray &comm); /** * @brief availableFirmwarePluginsChanged notify about the new plugins available */ void availableFirmwarePluginsChanged(); public slots: /** * @brief Set the printers state * @param state : printer state. * @sa state(), stateChanged(), AtCore::STATES */ void setState(AtCore::STATES state); /** * @brief Push a command into the command queue * * @param comm : Command */ Q_INVOKABLE void pushCommand(const QString &comm); /** * @brief Public Interface for printing a file * @param fileName: the gcode file to print. * @param sdPrint: set true to print fileName from Sd card */ Q_INVOKABLE void print(const QString &fileName, bool sdPrint = false); /** * @brief Stop the Printer by empting the queue and aborting the print job (if running) * @sa emergencyStop(), pause(), resume() */ Q_INVOKABLE void stop(); /** * @brief stop the printer via the emergency stop Command (M112) * @sa stop(), pause(), resume() */ Q_INVOKABLE void emergencyStop(); /** * @brief pause an in process print job * * Sends M114 on pause to store the location where the head stoped. * This is known to cause problems on fake printers * @param pauseActions: Gcode to run after pausing commands are ',' separated * @sa resume(), stop(), emergencyStop() */ void pause(const QString &pauseActions); /** * @brief resume a paused print job. * After returning to location pause was triggered. * @sa pause(), stop(), emergencyStop() */ Q_INVOKABLE void resume(); /** * @brief Send home \p axis command * @param axis: the axis(es) to home (use X Y Z or any combo of) * @sa home(), move() */ Q_INVOKABLE void home(uchar axis); /** * @brief Send home all command * @sa home(uchar axis), move() */ Q_INVOKABLE void home(); /** * @brief Set extruder temperature * @param temp : new temperature * @param extruder : extruder number * @param andWait: True for heat and ignore commands until temperature is reached */ Q_INVOKABLE void setExtruderTemp(uint temp = 0, uint extruder = 0, bool andWait = false); /** * @brief move an axis of the printer * @param axis the axis to move AXES (X Y Z E ) * @param arg the distance to move the axis or the place to move to depending on printer mode * @sa home(), home(uchar axis), move(QLatin1Char axis, int arg) */ Q_INVOKABLE void move(AtCore::AXES axis, double arg); /** * @brief move an axis of the printer * @param axis the axis to move AXES (X Y Z E ) * @param arg the distance to move the axis or the place to move to depending on printer mode * @sa home(), home(uchar axis), move(AtCore::AXES, int arg) */ Q_INVOKABLE void move(QLatin1Char axis, double arg); /** * @brief Set the bed temperature * @param temp : new temperature * @param andWait: True for heat and ignore commands until temperature is reached * @sa setExtruderTemp() */ Q_INVOKABLE void setBedTemp(uint temp = 0, bool andWait = false); /** * @brief setFanSpeed set the fan speed * @param fanNumber: fan number * @param speed: new speed of the fan 0-100 */ Q_INVOKABLE void setFanSpeed(uint speed = 0, uint fanNumber = 0); /** * @brief Set printer to absolute position mode * @sa setRelativePosition() */ Q_INVOKABLE void setAbsolutePosition(); /** * @brief Set printer to relative position mode * @sa setAbsolutePosition() */ Q_INVOKABLE void setRelativePosition(); /** * @brief Disable motors after a delay * @param delay: Seconds until motors are disabled. 0= No delay */ Q_INVOKABLE void disableMotors(uint delay = 0); /** * @brief set the Printers speed * @param speed: speed in % (default is 100); */ Q_INVOKABLE void setPrinterSpeed(uint speed = 100); /** * @brief set extruder Flow rate * @param rate: flow rate in % (default is 100) */ Q_INVOKABLE void setFlowRate(uint rate = 100); /** * @brief close any open items. * You should call this on close events to force any stuck jobs to close * @sa closeConnection() */ Q_INVOKABLE void close(); /** * @brief showMessage push a message to the printers LCD * @param message: message to show on the LCD */ Q_INVOKABLE void showMessage(const QString &message); /** * @brief setUnits sets the measurement units do be used * @param units : the measurement units to use(METRIC / IMPERIAL) * @sa AtCore::UNITS */ Q_INVOKABLE void setUnits(AtCore::UNITS units); /** * @brief Set the time between checks for new serialPorts (0 is default) * @param newTime: Milliseconds between checks. values <= 0 will Disable Checks. */ void setSerialTimerInterval(int newTime); /** * @brief Set the time between checks for new Temperature (5000 is default on new connections) * @param newTime: Milliseconds between checks. values <= 0 will Disable Checks. */ void setTemperatureTimerInterval(int newTime); /** @brief Set if atcore should Enable auto temperature reporting. Temperature timer will also be stopped. * @param autoReport: True to enable automatic reporting of temperatures. * @sa setAutoCheckTemperature */ void setAutoTemperatureReport(bool autoReport); /** * @brief Tell the machine to start reporting its temperature automaticly * @param newTime: Time in seconds between reports (0: disabled) */ Q_INVOKABLE void setAutoCheckTemperatureInterval(int newTime); /** * @brief delete file from sd card */ Q_INVOKABLE void sdDelete(const QString &fileName); /** * @brief Queue the Printer for status of sd card print */ void sdCardPrintStatus(); private slots: /** * @brief processQueue send commands from the queue. */ void processQueue(); /** * @brief Send M105 to the printer if one is not in the Queue */ void checkTemperature(); /** * @brief Connect to SerialLayer::receivedCommand * @param message: new message. */ void newMessage(const QByteArray &message); /** * @brief Connect to SerialLayer::pushedCommand * @param command: newCommand. */ void newCommand(const QByteArray &command); /** * @brief Search for firmware string in message. * A Helper function for Firmware detection * @param message */ void findFirmware(const QByteArray &message); /** * @brief Search for new serial ports */ void locateSerialPort(); /** * @brief Attempts to disableResetOnConnect for the selected port. * @param port: the port. */ void disableResetOnConnect(const QString &port); /** * @brief Send request to the printer for the sd card file list. */ void getSDFileList(); /** * @brief Handle serial Errors. */ void handleSerialError(QSerialPort::SerialPortError error); private: - /** * @brief Load A firmware plugin * @param fwName : name of the firmware * @sa firmwarePlugin(), availableFirmwarePlugins() */ Q_INVOKABLE void loadFirmwarePlugin(const QString &fwName); /** * @brief True if a firmware plugin is loaded */ bool firmwarePluginLoaded() const; /** * @brief True if a serial port is initialized */ bool serialInitialized() const; /** * @brief send firmware request to the printer */ void requestFirmware(); /** * @brief Search for atcore firmware plugins * @param path: the path to check * @return QMap of the plugings found */ QMap findFirmwarePlugins(const QString &path); /** * @brief returns AtCorePrivate::sdCardReadingFileList * @return True if printer is returning sd card file list */ bool isReadingSdCardList() const; /** * @brief stops print just for sd prints used internally * @sa stop(), emergencyStop() */ void stopSdPrint(); /** * @brief New connections need to wait for the machine to be ready if it needs reboot * @param message: message from the firmware * @param fwName: fwName to load */ void waitForPrinterReboot(const QByteArray &message, const QString &fwName); /** * @brief Hold private data of AtCore. */ struct AtCorePrivate; AtCorePrivate *d; protected: /** * @brief Set the number of extruders on the machine. * @param newCount * @sa extruderCount(), extruderCountChanged(int newCount) */ void setExtruderCount(int newCount); /** * @brief Append a file to AtCorePrivate::sdCardFileList. * @param fileName: new FileName */ void appendSdCardFileList(const QString &fileName); /** * @brief Clear AtCorePrivate::sdCardFileList. */ void clearSdCardFileList(); /** * @brief Set if the sd card is mounted by the printer * @param mounted: True is mounted */ void setSdMounted(const bool mounted); /** * @brief set AtCorePrivate::sdCardReadingFileList * @param readingList set true if reading file list */ void setReadingSdCardList(bool readingList); }; diff --git a/src/core/beddeform.cpp b/src/core/beddeform.cpp index 7856e2f..bed384f 100644 --- a/src/core/beddeform.cpp +++ b/src/core/beddeform.cpp @@ -1,74 +1,74 @@ /* AtCore Copyright (C) <2019> 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 "beddeform.h" +#include struct BedDeform::BedDeformPrivate { /** bedData Beddeform data*/ QVariantList bedData; /** Regex to capture lines containing valid data */ static const QRegularExpression lineRegEx; /** Regex to capture Data from in lines*/ static const QRegularExpression valueRegEx; }; /** * @brief Line with the pattern of digit(s) a single space then '+' or '-'. * Examples: - * 0 -0.155 +5.123 -4.567 + * 0 -0.155 +5.123 -4.567 * 10 +8.901 -2.345 +6.789 */ const QRegularExpression BedDeform::BedDeformPrivate::lineRegEx = QRegularExpression(QStringLiteral(R"((?:\d+\s(\+|\-)))")); /** * @brief Numeric value with a decimal (maybe negative) * example Input : 0 +0.005 -1.110, +1.040 * captured values from above line: 0.005, -1.110, 1.04 */ const QRegularExpression BedDeform::BedDeformPrivate::valueRegEx = QRegularExpression(QStringLiteral(R"((?\-?\d+\.?\d+))")); BedDeform::BedDeform(QObject *parent) : QObject(parent) , d(new BedDeformPrivate) { } void BedDeform::decodeDeform(const QStringList &rawData) { d->bedData.clear(); QVariantList coreList; for (const QString &line : rawData) { QRegularExpressionMatch lineCheck = d->lineRegEx.match(line); if (lineCheck.hasMatch()) { QRegularExpressionMatchIterator valueCheck = d->valueRegEx.globalMatch(line); while (valueCheck.hasNext()) { coreList.append(valueCheck.next().captured(QStringLiteral("value")).toDouble()); } d->bedData.push_back(coreList); coreList.clear(); } } emit dataChanged(d->bedData); } QVariantList BedDeform::bedDeformationGrid() { return d->bedData; } diff --git a/src/core/beddeform.h b/src/core/beddeform.h index b1aba77..3589a4b 100644 --- a/src/core/beddeform.h +++ b/src/core/beddeform.h @@ -1,67 +1,68 @@ /* AtCore Copyright (C) <2019> 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 . */ #pragma once #include #include "atcore_export.h" /** * @brief The Bed Deform class * * Read and hold data for the Bed Deformation of the printer */ class ATCORE_EXPORT BedDeform : public QObject { Q_OBJECT Q_PROPERTY(QVariantList bedDeformationGrid READ bedDeformationGrid NOTIFY dataChanged) public: /** * @brief BedDeform Create a new bedDeform object * @param parent: Objects parent */ explicit BedDeform(QObject *parent = nullptr); /** * @brief decodeDeform Decode the deform list from the provided lines * @param rawData: raw returns containing deform data */ void decodeDeform(const QStringList &rawData); /** * @brief get bed Deform info * @return: bed Deform grid, Variant Format: QList> * The Inner QList contains, * one row worth of offsets for the deformation grid. * the outer list is a list of rows data. * For a grid with 2x3 proble points the size of the inner list will be 2 and the outer list 3 * example: QVariant(QVariantList, (QVariant(double, 0.25), QVariant(double, 0.225)) * ,QVariant(QVariantList, (QVariant(double, 0.045), QVariant(double, 0.01)) * , QVariant(QVariantList, (QVariant(double, -0.168), QVariant(double, -0.24))) */ QVariantList bedDeformationGrid(); signals: void dataChanged(const QVariantList &data); + private: struct BedDeformPrivate; BedDeformPrivate *d; }; diff --git a/src/core/gcodecommands.cpp b/src/core/gcodecommands.cpp index da52675..826d143 100644 --- a/src/core/gcodecommands.cpp +++ b/src/core/gcodecommands.cpp @@ -1,568 +1,568 @@ /* AtCore Copyright (C) <2016> Authors: Lays Rodrigues Tomaz Canabrava Patrick José Pereira 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 "gcodecommands.h" const QString GCode::commandRequiresArgument = QObject::tr("%1%2: requires an argument"); const QString GCode::commandNotSupported = QObject::tr("Not implemented or not supported!"); QString GCode::description(GCommands gcode) { switch (gcode) { - case G0://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G0: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G0: Rapid linear move"); - case G1://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case G1: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("G1: Linear move"); - case G2://Sprinter - Marlin - Repetier - Smoothie + case G2: // Sprinter - Marlin - Repetier - Smoothie return QObject::tr("G2: Controlled Arc Move clockwise"); - case G3://Sprinter - Marlin - Repetier - Smoothie + case G3: // Sprinter - Marlin - Repetier - Smoothie return QObject::tr("G3: Controlled Arc Move counterclockwise"); - case G4://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G4: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G4: Dwell"); - case G10://Marlin - Repetier > 0.92 - Smoothie + case G10: // Marlin - Repetier > 0.92 - Smoothie return QObject::tr("G10: Retract"); - case G11://Marlin - Repetier > 0.92 - Smoothie + case G11: // Marlin - Repetier > 0.92 - Smoothie return QObject::tr("G11: Unretract"); - case G20://Teacup - Sprinter - Repetier - Smoothie - RepRap Firmware + case G20: // Teacup - Sprinter - Repetier - Smoothie - RepRap Firmware return QObject::tr("G20: Set units to inches"); - case G21://Teacup - Sprinter - Repetier - Smoothie - RepRap Firmware + case G21: // Teacup - Sprinter - Repetier - Smoothie - RepRap Firmware return QObject::tr("G21: Set units to millimeters"); - case G28://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G28: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G28: Move to Origin Home"); - case G29://Marlin - Repetier 0.91.7 + case G29: // Marlin - Repetier 0.91.7 return QObject::tr("G29: Detailed Z-Probe"); - case G30:// Marlin - Repetier - Smoothie - RepRap Firmware + case G30: // Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("G30: Single Z-Probe"); - case G31://Repetier 0.91.7 - Smoothie - RepRap Firmware - Marlin + case G31: // Repetier 0.91.7 - Smoothie - RepRap Firmware - Marlin return QObject::tr("G31: Set or report current probe status / Dock Z Probe sled for Marlin"); - case G32://Repetier 0.92.8 - Smoothie - RepRap Firmware - Marlin + case G32: // Repetier 0.92.8 - Smoothie - RepRap Firmware - Marlin return QObject::tr("G32: Probe Z and calculate Z plane(Bed Leveling)/ UnDoc Z Probe sled for Marlin"); - case G33://Repetier 0.92.8 + case G33: // Repetier 0.92.8 return QObject::tr("G33: Measure/List/Adjust Distortion Matrix"); - case G90://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G90: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G90: Set to absolute positioning"); - case G91://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G91: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G91: Set to relative positioning"); - case G92://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case G92: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("G92: Set position"); - case G100://Repetier 0.92 + case G100: // Repetier 0.92 return QObject::tr("G100: Calibrate floor or rod radius"); - case G130://MakerBot + case G130: // MakerBot return QObject::tr("G130: Set digital potentiometer value"); - case G131://Repetier 0.91 + case G131: // Repetier 0.91 return QObject::tr("G131: Recase Move offset"); - case G132://Repetier 0.91 + case G132: // Repetier 0.91 return QObject::tr("G132: Calibrate endstops offsets"); - case G133://Repetier 0.91 + case G133: // Repetier 0.91 return QObject::tr("G133: Measure steps to top"); - case G161://Teacup - MakerBot + case G161: // Teacup - MakerBot return QObject::tr("G161: Home axis to minimum"); - case G162://Teacup - MakerBot + case G162: // Teacup - MakerBot return QObject::tr("G162: Home axis to maximum"); default: return commandNotSupported; } } QString GCode::toCommand(GCommands gcode, const QString &value1) { QString code = QStringLiteral("G%1").arg(QString::number(gcode)); switch (gcode) { case G29: case G90: case G91: return code; case G32: return code.append(QStringLiteral(" S1")); case G0: case G1: case G28: code = value1.isEmpty() ? code : code.append(QStringLiteral(" %1").arg(value1)); return code; default: return commandNotSupported; } } QString GCode::description(MCommands gcode) { switch (gcode) { - case M0://Marlin - Teacup - RepRap Firmware + case M0: // Marlin - Teacup - RepRap Firmware return QObject::tr("M0: Stop or unconditional stop"); - case M1://Marlin - RepRap Firmware + case M1: // Marlin - RepRap Firmware return QObject::tr("M1: Sleep or unconditional stop"); - case M2://Teacup - Maker Bot + case M2: // Teacup - Maker Bot return QObject::tr("M2: Program End"); - case M6://Teacup + case M6: // Teacup return QObject::tr("M6: Tool Change"); - case M17://Teacup - Marlin - Smoothie + case M17: // Teacup - Marlin - Smoothie return QObject::tr("M17: Enable/power all steppers motors"); - case M18://Teacup - Marlin(M84) - Smoothie -RepRap Firmware + case M18: // Teacup - Marlin(M84) - Smoothie -RepRap Firmware return QObject::tr("M18: Disable all steppers motors"); - case M20://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M20: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M20: List SDCard"); - case M21://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M21: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M21: Initialize SDCard"); - case M22://Teacup - Sprinter - Marlin - Repetier - RepRap Firmware + case M22: // Teacup - Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M22: Release SDCard"); - case M23://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M23: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M23: Select SD file"); - case M24://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M24: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M24: Start/resume SD print"); - case M25://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M25: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M25: Pause SD print"); - case M26://Sprinter - Marlin - Repetier - Smoothie(abort) - RepRap Firmware + case M26: // Sprinter - Marlin - Repetier - Smoothie(abort) - RepRap Firmware return QObject::tr("M26: Set SD position"); - case M27://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M27: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M27: Report SD print status"); - case M28://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M28: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M28: Begin write to SD card"); - case M29:// Sprinter - Marlin - Repetier - RepRap Firmware + case M29: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M29: Stop writing to SD card"); - case M30://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M30: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M30: Delete a file on the SD card"); - case M31://Marlin + case M31: // Marlin return QObject::tr("M31: Output time since last M109 or SD card start to serial"); - case M32://Marlin - Smoothie - RepRap Firmware + case M32: // Marlin - Smoothie - RepRap Firmware return QObject::tr("M32: Select file and start SD print"); - case M33://Marlin + case M33: // Marlin return QObject::tr("M33: Get the long name for an SD card file or folder"); - case M34://Marlin + case M34: // Marlin return QObject::tr("M34: Set SD file sorting options"); - case M36://RepRap Firmware + case M36: // RepRap Firmware return QObject::tr("M36: Return file information"); - case M42://Sprinter - Marlin - Repetier - RepRap Firmware + case M42: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M42: Switch I/O pin"); - case M48://Marlin + case M48: // Marlin return QObject::tr("M48: Measure Z-Probe repeatability"); - case M70://MakerBot + case M70: // MakerBot return QObject::tr("M70: Display message"); - case M72://MakerBot + case M72: // MakerBot return QObject::tr("M72: Play a tone or song"); - case M73://MakerBot + case M73: // MakerBot return QObject::tr("M73: Set build percentage"); - case M80://Teacup(automatic) - Sprinter - Marlin - Repetier - RepRap Firmware + case M80: // Teacup(automatic) - Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M80: ATX Power On"); - case M81://Teacup(automatic) - Sprinter - Marlin - Repetier - RepRap Firmware + case M81: // Teacup(automatic) - Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M81: ATX Power Off"); - case M82://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M82: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M82: Set extruder to absolute mode"); - case M83://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M83: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M83: Set extruder to relative mode"); - case M84://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M84: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M84: Stop idle hold"); - case M85://Sprinter - Marlin - Repetier + case M85: // Sprinter - Marlin - Repetier return QObject::tr("M85: Set Inactivity shutdown timer"); - case M92:// Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M92: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M92: Set axis steps per unit"); - case M93:// Sprinter + case M93: // Sprinter return QObject::tr("M93: Send axis steps per unit"); - case M98: //RepRap Firmware + case M98: // RepRap Firmware return QObject::tr("M98: Call Macro/Subprogram"); - case M99://RepRap Firmware + case M99: // RepRap Firmware return QObject::tr("M99: Return from Macro/Subprogram"); - case M101://Teacup + case M101: // Teacup return QObject::tr("M101: Turn extruder 1 on Forward, Undo Retraction"); - case M103://Teacup + case M103: // Teacup return QObject::tr("M103: Turn all extruders off - Extruder Retraction"); - case M104://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case M104: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("M104: Set Extruder Temperature"); - case M105://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case M105: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("M105: Get Extruder Temperature"); - case M106://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M106: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M106: Fan On"); - case M107:// Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M107: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M107: Fan Off"); - case M108://Marlin + case M108: // Marlin return QObject::tr("M108: Cancel Heating"); - case M109:// Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case M109: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("M109: Set Extruder Temperature and Wait"); - case M110:// Marlin - Repetier - Smoothie - RepRap Firmware + case M110: // Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M110: Set Current Line Number"); - case M111://Teacup - Marlin - Repetier - RepRap Firmware + case M111: // Teacup - Marlin - Repetier - RepRap Firmware return QObject::tr("M111: Set Debug Level"); - case M112://Teacup - Marlin - Repetier - Smoothie - RepRap Firmware + case M112: // Teacup - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M112: Emergency Stop"); - case M114://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case M114: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("M114: Get Current Position"); - case M115://Teacup - Sprinter - Marlin - Repetier - RepRap Firmware + case M115: // Teacup - Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M115: Get Firmware Version and Capabilities"); - case M116://Teacup - Repetier - RepRap Firmware - MakerBot + case M116: // Teacup - Repetier - RepRap Firmware - MakerBot return QObject::tr("M116: Wait"); - case M117:// Marlin - Repetier - Smoothie - RepRap Firmware + case M117: // Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M117: Display Message"); - case M119://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M119: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M119: Get Endstop Status"); - case M120://Marlin - Smoothie - RepRap Firmware + case M120: // Marlin - Smoothie - RepRap Firmware return QObject::tr("M120: Push for Smoothie and RepRap Firmware / Enable Endstop detection for Marlin"); - case M121://Marlin - Smoothie - RepRap Firmware + case M121: // Marlin - Smoothie - RepRap Firmware return QObject::tr("M121: Pop for Smoothie and RepRap Firmware / Disable Endstop detection for Marlin"); - case M122://RepRap Firmware + case M122: // RepRap Firmware return QObject::tr("M122: Diagnose"); - case M126://Marlin - MakerBot + case M126: // Marlin - MakerBot return QObject::tr("M126: Open valve"); - case M127://Marlin - MakerBot + case M127: // Marlin - MakerBot return QObject::tr("M127: Close valve"); - case M130://Teacup + case M130: // Teacup return QObject::tr("M130: Set PID P value"); - case M131://Teacup + case M131: // Teacup return QObject::tr("M131: Set PID I value"); - case M132://Teacup - MakerBot + case M132: // Teacup - MakerBot return QObject::tr("M132: Set PID D value"); - case M133://Teacup - MakerBot + case M133: // Teacup - MakerBot return QObject::tr("M133: Set PID I limit value"); - case M134://Teacup - MakerBot + case M134: // Teacup - MakerBot return QObject::tr("M134: Write PID values to EEPROM"); - case M135://RepRap Firmware - MakerBot + case M135: // RepRap Firmware - MakerBot return QObject::tr("M135: Set PID sample interval"); - case M140://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot + case M140: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware - MakerBot return QObject::tr("M140: Set Bed Temperature - Fast"); - case M141://RepRap Firmware + case M141: // RepRap Firmware return QObject::tr("M141: Set Chamber Temperature - Fast"); - case M143://RepRap Firmware + case M143: // RepRap Firmware return QObject::tr("M143: Maximum hot-end temperature"); - case M144://RepRap Firmware + case M144: // RepRap Firmware return QObject::tr("M144: Stand by your bed"); - case M150://Marlin + case M150: // Marlin return QObject::tr("M150: Set display color"); - case M155: //Look for Cap:AUTOREPORT_TEMP:1 in M115 to check for support + case M155: // Look for Cap:AUTOREPORT_TEMP:1 in M115 to check for support return QObject::tr("M155: Set Temperature auto report"); - case M163://Repetier > 0.92 + case M163: // Repetier > 0.92 return QObject::tr("M163: Set weight of mixed material"); - case M164://Repetier > 0.92 + case M164: // Repetier > 0.92 return QObject::tr("M164: Store weights"); - case M190://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M190: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M190: Wait for bed temperature to reach target temp"); - case M200://Marlin - Repetier - Smoothie + case M200: // Marlin - Repetier - Smoothie return QObject::tr("M200: Set filament diameter"); - case M201://Sprinter - Marlin - Repetier - RepRap Firmware + case M201: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M201: Set max printing acceleration"); - case M202://Marlin - Repetier + case M202: // Marlin - Repetier return QObject::tr("M202: Set max travel acceleration"); - case M203://Marlin - Repetier - Smoothie - RepRap Firmware + case M203: // Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M203: Set maximum feedrate"); - case M204://Sprinter - Marlin - Repetier - Smoothie + case M204: // Sprinter - Marlin - Repetier - Smoothie return QObject::tr("M204: Set default acceleration"); - case M205://Sprinter - Marlin - Repetier - Smoothie + case M205: // Sprinter - Marlin - Repetier - Smoothie return QObject::tr("M205: Advanced settings"); - case M206://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M206: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M206: Offset axes for Sprinter, Marlin, Smoothie, RepRap Firmware / Set eeprom value for Repetier"); - case M207://Marlin - Smoothie + case M207: // Marlin - Smoothie return QObject::tr("M207: Set retract length"); - case M208://Marlin - Smoothie + case M208: // Marlin - Smoothie return QObject::tr("M208: Set unretract length"); - case M209://Marlin - Repetier + case M209: // Marlin - Repetier return QObject::tr("M209: Enable automatic retract"); - case M212://Marlin + case M212: // Marlin return QObject::tr("M212: Set Bed Level Sensor Offset"); - case M218://Marlin + case M218: // Marlin return QObject::tr("M218: Set Hotend Offset"); - case M220://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M220: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M220: Set speed factor override percentage"); - case M221://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M221: // Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M221: Set extrude factor override percentage"); - case M226://Marlin - Repetier + case M226: // Marlin - Repetier return QObject::tr("M226: Wait for pin state"); - case M231://Repetier + case M231: // Repetier return QObject::tr("M231: Set OPS parameter"); - case M232://Repetier + case M232: // Repetier return QObject::tr("M232: Read and reset max. advance values"); - case M240://Marlin + case M240: // Marlin return QObject::tr("M240: Trigger camera"); - case M250://Marlin + case M250: // Marlin return QObject::tr("M250: Set LCD contrast"); - case M251://Repetier + case M251: // Repetier return QObject::tr("M251: Measure Z steps from homing stop (Delta printers)"); - case M280://Marlin + case M280: // Marlin return QObject::tr("M280: Set servo position"); - case M300://Marlin - Repetier - RepRap Firmware - MakerBot + case M300: // Marlin - Repetier - RepRap Firmware - MakerBot return QObject::tr("M300: Play beep sound"); - case M301://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M301: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M301: Set PID parameters"); - case M302://Marlin - Repetier > 0.92 - RepRap Firmware + case M302: // Marlin - Repetier > 0.92 - RepRap Firmware return QObject::tr("M302: Allow cold extrudes "); - case M303://Sprinter - Marlin - Repetier - Smoothie + case M303: // Sprinter - Marlin - Repetier - Smoothie return QObject::tr("M303: Run PID tuning"); - case M304://Marlin - RepRap Firmware + case M304: // Marlin - RepRap Firmware return QObject::tr("M304: Set PID parameters - Bed"); - case M305:// Smoothie - RepRap Firmware + case M305: // Smoothie - RepRap Firmware return QObject::tr("M305: Set thermistor and ADC parameters"); - case M306:// Smoothie + case M306: // Smoothie return QObject::tr("M306: set home offset calculated from toolhead position"); - case M320://Repeier + case M320: // Repeier return QObject::tr("M320: Activate autolevel (Repetier)"); - case M321://Repetier + case M321: // Repetier return QObject::tr("M321: Deactivate autolevel (Repetier)"); - case M322://Repetier + case M322: // Repetier return QObject::tr("M322: Reset autolevel matrix (Repetier)"); - case M323://Repetier + case M323: // Repetier return QObject::tr("M323: Distortion correction on/off (Repetier)"); - case M340://Repetier + case M340: // Repetier return QObject::tr("M340: Control the servos"); - case M350://Marlin - Repetier - RepRap Firmware + case M350: // Marlin - Repetier - RepRap Firmware return QObject::tr("M350: Set microstepping mode"); - case M351://Marlin + case M351: // Marlin return QObject::tr("M351: Toggle MS1 MS2 pins directly"); - case M355://Repetier > 0.92.2 + case M355: // Repetier > 0.92.2 return QObject::tr("M355: Turn case lights on/off"); - case M360://Repetier > 9.92.2 + case M360: // Repetier > 9.92.2 return QObject::tr("M360: Report firmware configuration"); - case M361://Smoothie + case M361: // Smoothie return QObject::tr("M361: Move to Theta 90 degree position"); - case M362://Smoothie + case M362: // Smoothie return QObject::tr("M362: Move to Psi 0 degree position"); - case M363://Smoothie + case M363: // Smoothie return QObject::tr("M363: Move to Psi 90 degree position"); - case M364://Smoothie + case M364: // Smoothie return QObject::tr("M364: Move to Psi + Theta 90 degree position"); - case M365://Smoothie + case M365: // Smoothie return QObject::tr("M365: SCARA scaling factor"); - case M366://Smoothie + case M366: // Smoothie return QObject::tr("M366: SCARA convert trim"); - case M370://Smoothie + case M370: // Smoothie return QObject::tr("M370: Morgan manual bed level - clear map"); - case M371://Smoothie + case M371: // Smoothie return QObject::tr("M371: Move to next calibration position"); - case M372://Smoothie + case M372: // Smoothie return QObject::tr("M372: Record calibration value, and move to next position"); - case M373://Smoothie + case M373: // Smoothie return QObject::tr("M373: End bed level calibration mode"); - case M374://Smoothie + case M374: // Smoothie return QObject::tr("M374: Save calibration grid"); - case M375://Smoothie + case M375: // Smoothie return QObject::tr("M375: Display matrix / Load Matrix"); - case M380://Marlin + case M380: // Marlin return QObject::tr("M380: Activate solenoid"); - case M381://Marlin + case M381: // Marlin return QObject::tr("M381: Disable all solenoids"); - case M400://Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware + case M400: // Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M400: Wait for current moves to finish"); - case M401://Marlin + case M401: // Marlin return QObject::tr("M401: Lower z-probe"); - case M402://Marlin + case M402: // Marlin return QObject::tr("M402: Raise z-probe"); - case M404://Marlin - RepRap Firmware + case M404: // Marlin - RepRap Firmware return QObject::tr("M404: Filament width and nozzle diameter"); - case M405://Marlin + case M405: // Marlin return QObject::tr("M405: Filament Sensor on"); - case M406://Marlin + case M406: // Marlin return QObject::tr("M406: Filament Sensor off"); - case M407://Marlin - RepRap Firmware + case M407: // Marlin - RepRap Firmware return QObject::tr("M407: Display filament diameter"); - case M408://RepRap Firmware + case M408: // RepRap Firmware return QObject::tr("M408: Report JSON-style response"); case M420: return QObject::tr("M420: Enable/Disable Mesh Leveling (Marlin)"); - case M450://Repetier + case M450: // Repetier return QObject::tr("M450: Report Printer Mode"); - case M451://Repetier + case M451: // Repetier return QObject::tr("M451: Select FFF Printer Mode"); - case M452://Repetier + case M452: // Repetier return QObject::tr("M452: Select Laser Printer Mode"); - case M453://Repetier + case M453: // Repetier return QObject::tr("M453: Select CNC Printer Mode"); - case M460://Repetier + case M460: // Repetier return QObject::tr("M460: Define temperature range for thermistor controlled fan"); - case M500://Sprinter - Marlin - Repetier - RepRap Firmware + case M500: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M500: Store parameters in EEPROM"); - case M501://Sprinter - Marlin - Repetier - RepRap Firmware + case M501: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M501: Read parameters from EEPROM"); - case M502://Sprinter - Marlin - Repetier - RepRap Firmware + case M502: // Sprinter - Marlin - Repetier - RepRap Firmware return QObject::tr("M502: Revert to the default 'factory settings'."); - case M503://Sprinter - Marlin - RepRap Firmware + case M503: // Sprinter - Marlin - RepRap Firmware return QObject::tr("M503: Print settings "); - case M540://Marlin + case M540: // Marlin return QObject::tr("M540: Enable/Disable 'Stop SD Print on Endstop Hit'"); - case M550://RepRap Firmware + case M550: // RepRap Firmware return QObject::tr("M550: Set Name"); - case M551://RepRap Firmware + case M551: // RepRap Firmware return QObject::tr("M551: Set Password"); - case M552://RepRap Firmware + case M552: // RepRap Firmware return QObject::tr("M552: Set IP address"); - case M553://RepRap Firmware + case M553: // RepRap Firmware return QObject::tr("M553: Set Netmask"); - case M554://RepRap Firmware + case M554: // RepRap Firmware return QObject::tr("M554: Set Gateway"); - case M555://RepRap Firmware + case M555: // RepRap Firmware return QObject::tr("M555: Set compatibility"); - case M556://RepRap Firmware + case M556: // RepRap Firmware return QObject::tr("M556: Axis compensation"); - case M557://Smoothie - RepRap Firmware + case M557: // Smoothie - RepRap Firmware return QObject::tr("M557: Set Z probe point"); - case M558://RepRap Firmware + case M558: // RepRap Firmware return QObject::tr("M558: Set Z probe type"); - case M559://RepRap Firmware + case M559: // RepRap Firmware return QObject::tr("M559: Upload configuration file"); - case M560://RepRap Firmware + case M560: // RepRap Firmware return QObject::tr("M560: Upload web page file"); - case M561://Smoothie - RepRap Firmware + case M561: // Smoothie - RepRap Firmware return QObject::tr("M561: Set Identity Transform"); - case M562://RepRap Firmware + case M562: // RepRap Firmware return QObject::tr("M562: Reset temperature fault"); - case M563://RepRap Firmware + case M563: // RepRap Firmware return QObject::tr("M563: Define or remove a tool"); - case M564://RepRap Firmware + case M564: // RepRap Firmware return QObject::tr("M564: Limit axes"); - case M565://Smoothie + case M565: // Smoothie return QObject::tr("M565: Set Z probe offset"); - case M566://RepRap Firmware + case M566: // RepRap Firmware return QObject::tr("M566: Set allowable instantaneous speed change"); - case M567://RepRap Firmware + case M567: // RepRap Firmware return QObject::tr("M567: Set tool mix ratio"); - case M568://RepRap Firmware + case M568: // RepRap Firmware return QObject::tr("M568: Turn off/on tool mix ratio"); - case M569://RepRap Firmware + case M569: // RepRap Firmware return QObject::tr("M569: Set axis direction and enable values"); - case M570://RepRap Firmware + case M570: // RepRap Firmware return QObject::tr("M570: Set heater timeout"); - case M571://RepRap Firmware + case M571: // RepRap Firmware return QObject::tr("M571: Set output on extrude"); - case M573://RepRap Firmware + case M573: // RepRap Firmware return QObject::tr("M573: Report heater PWM"); - case M574://RepRap Firmware + case M574: // RepRap Firmware return QObject::tr("M574: Set endstop configuration"); - case M575://RepRap Firmware + case M575: // RepRap Firmware return QObject::tr("M575: Set serial comms parameters"); - case M577://RepRap Firmware + case M577: // RepRap Firmware return QObject::tr("M577: Wait until endstop is triggered"); - case M578://RepRap Firmware + case M578: // RepRap Firmware return QObject::tr("M578: Fire inkjet bits"); - case M579://RepRap Firmware + case M579: // RepRap Firmware return QObject::tr("M579: Scale Cartesian axes"); - case M580://RepRap Firmware + case M580: // RepRap Firmware return QObject::tr("M580: Select Roland"); - case M600://Marlin + case M600: // Marlin return QObject::tr("M600: Filament change pause"); - case M605://Marlin + case M605: // Marlin return QObject::tr("M605: Set dual x-carriage movement mode"); - case M665://Marlin - Smoothie - RepRap Firmware + case M665: // Marlin - Smoothie - RepRap Firmware return QObject::tr("M665: Set delta configuration"); - case M666://Marlin - Repetier - Smoothie - RepRap Firmware + case M666: // Marlin - Repetier - Smoothie - RepRap Firmware return QObject::tr("M666: Set delta endstop adjustment"); - case M667://RepRap Firmware + case M667: // RepRap Firmware return QObject::tr("M667: Select CoreXY mode"); - case M851://Marlin + case M851: // Marlin return QObject::tr("M851: Set Z-Probe Offset"); - case M906://RepRap Firmware + case M906: // RepRap Firmware return QObject::tr("M906: Set motor currents"); - case M907://Marlin - Repetier - Smoothie + case M907: // Marlin - Repetier - Smoothie return QObject::tr("M907: Set digital trimpot motor"); - case M908://Marlin - Repetier > 0.92 + case M908: // Marlin - Repetier > 0.92 return QObject::tr("M908: Control digital trimpot directly"); - case M911://RepRap Firmware + case M911: // RepRap Firmware return QObject::tr("M911: Set power monitor threshold voltages"); - case M912://RepRap Firmware + case M912: // RepRap Firmware return QObject::tr("M912: Set electronics temperature monitor adjustment"); - case M913://RepRap Firmware + case M913: // RepRap Firmware return QObject::tr("M913: Set motor percentage of normal current"); - case M928://Marlin + case M928: // Marlin return QObject::tr("M928: Start SD logging"); - case M997://RepRap Firmware + case M997: // RepRap Firmware return QObject::tr("M997: Perform in-application firmware update"); - case M998://RepRap Firmware + case M998: // RepRap Firmware return QObject::tr("M998: Request resend of line"); - case M999://Marlin - Smoothie - RepRap Firmware + case M999: // Marlin - Smoothie - RepRap Firmware return QObject::tr("M999: Restart after being stopped by error"); default: return commandNotSupported; } } QString GCode::toCommand(MCommands gcode, const QString &value1, const QString &value2) { QString code = QStringLiteral("M%1").arg(QString::number(gcode)); switch (gcode) { case M20: case M24: case M25: case M27: case M105: case M107: case M112: case M114: case M115: case M116: case M119: return code; case M21: case M22: code = value1.isEmpty() ? code : code.append(QStringLiteral(" P%1").arg(value1)); return code; case M23: case M28: case M29: case M30: case M117: code = value1.isEmpty() ? GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)) : code.append(QStringLiteral(" %1").arg(value1)); return code; case M109: case M140: case M155: case M190: case M220: case M221: code = value1.isEmpty() ? GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)) : code.append(QStringLiteral(" S%1").arg(value1)); return code; case M84: code = value1.isEmpty() ? code : code.append(QStringLiteral(" S%1").arg(value1)); return code; case M104: code = value2.isEmpty() ? code.append(QStringLiteral(" S%1").arg(value1)) : code.append(QStringLiteral(" P%1 S%2").arg(value1, value2)); - code = value1.isEmpty() ? GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)) : code ; + code = value1.isEmpty() ? GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)) : code; return code; case M106: code = value2.isEmpty() ? code.append(QStringLiteral(" S%1").arg(value1)) : code.append(QStringLiteral(" P%1 S%2").arg(value1, value2)); - code = value1.isEmpty() ? QStringLiteral("M106") : code ; + code = value1.isEmpty() ? QStringLiteral("M106") : code; return code; /// For M26 values that end with %. AtCore will send the percentage verison of the command (optional in firmwares) /// For all values not ending in % it will start on that byte. This is the standard Sd resume supported by all reprap based firmware. case M26: { if (!value1.isEmpty()) { if (value1.endsWith(QStringLiteral("%"))) { QString temp = value1; temp.replace(QStringLiteral("%"), QStringLiteral("")); return code.append(QStringLiteral(" P%1").arg(temp.toDouble() / 100)); } return code.append(QStringLiteral(" S%1").arg(value1)); } return GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)); } default: return commandNotSupported; } } diff --git a/src/core/gcodecommands.h b/src/core/gcodecommands.h index e051c58..85c3795 100644 --- a/src/core/gcodecommands.h +++ b/src/core/gcodecommands.h @@ -1,144 +1,322 @@ /* AtCore Copyright (C) <2016> Authors: Lays Rodrigues Tomaz Canabrava Patrick José Pereira 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 . */ #pragma once -#include #include +#include #include "atcore_export.h" /** * @brief The GCode class * Provides Descriptions and Commands strings for G and M Commands */ class ATCORE_EXPORT GCode { Q_GADGET friend class GCodeTests; + public: /** * @brief The GCommands enum */ - enum GCommands { - G0, G1, G2, G3, G4, - G10 = 10, G11, - G20 = 20, G21, G22, G23, G28 = 28, G29, - G30, G31, G32, G33, - G90 = 90, G91, G92, - G100 = 100, - G130 = 130, G131, G132, G133, - G161 = 161, G162 - }; + enum GCommands { G0, G1, G2, G3, G4, G10 = 10, G11, G20 = 20, G21, G22, G23, G28 = 28, G29, G30, G31, G32, G33, G90 = 90, G91, G92, G100 = 100, G130 = 130, G131, G132, G133, G161 = 161, G162 }; Q_ENUM(GCommands) /** * @brief The MCommands enum */ enum MCommands { - M0, M1, M2, M6 = 6, - M17 = 17, M18, - M20 = 20, M21, M22, M23, M24, M25, M26, M27, M28, M29, - M30, M31, M32, M33, M34, M36 = 36, M37, M38, - M40 = 40, M41, M42, M43, M48 = 48, - M70 = 70, M72 = 72, M73, - M80 = 80, M81, M82, M83, M84, M85, - M92 = 92, M93, M98 = 98, M99, - M101 = 101, M102, M103, M104, M105, M106, M107, M108, M109, - M110, M111, M112, M113, M114, M115, M116, M117, M118, M119, - M120, M121, M122, M123, M124, M126 = 126, M127, M128, M129, - M130, M131, M132, M133, M134, M135, M136, - M140 = 140, M141, M142, M143, M144, M146 = 146, M149 = 149, - M150 = 150, M155 = 155, - M160 = 160, M163 = 163, M164 = 164, - M190 = 190, M191, - M200 = 200, M201, M202, M203, M204, M205, M206, M207, M208, M209, - M210, M211, M212, M218 = 218, - M220 = 220, M221, M222, M223, M224, M225, M226, M227, M228, M229, - M230, M231, M232, - M240 = 240, M241, M245 = 245, M246, - M250 = 250, M251, + M0, + M1, + M2, + M6 = 6, + M17 = 17, + M18, + M20 = 20, + M21, + M22, + M23, + M24, + M25, + M26, + M27, + M28, + M29, + M30, + M31, + M32, + M33, + M34, + M36 = 36, + M37, + M38, + M40 = 40, + M41, + M42, + M43, + M48 = 48, + M70 = 70, + M72 = 72, + M73, + M80 = 80, + M81, + M82, + M83, + M84, + M85, + M92 = 92, + M93, + M98 = 98, + M99, + M101 = 101, + M102, + M103, + M104, + M105, + M106, + M107, + M108, + M109, + M110, + M111, + M112, + M113, + M114, + M115, + M116, + M117, + M118, + M119, + M120, + M121, + M122, + M123, + M124, + M126 = 126, + M127, + M128, + M129, + M130, + M131, + M132, + M133, + M134, + M135, + M136, + M140 = 140, + M141, + M142, + M143, + M144, + M146 = 146, + M149 = 149, + M150 = 150, + M155 = 155, + M160 = 160, + M163 = 163, + M164 = 164, + M190 = 190, + M191, + M200 = 200, + M201, + M202, + M203, + M204, + M205, + M206, + M207, + M208, + M209, + M210, + M211, + M212, + M218 = 218, + M220 = 220, + M221, + M222, + M223, + M224, + M225, + M226, + M227, + M228, + M229, + M230, + M231, + M232, + M240 = 240, + M241, + M245 = 245, + M246, + M250 = 250, + M251, M280 = 280, - M300 = 300, M301, M302, M303, M304, M305, M306, - M320 = 320, M321, M322, M323, + M300 = 300, + M301, + M302, + M303, + M304, + M305, + M306, + M320 = 320, + M321, + M322, + M323, M340 = 340, - M350 = 350, M351, M355 = 355, - M360 = 360, M361, M362, M363, M364, M365, M366, - M370 = 370, M371, M372, M373, M374, M375, - M380 = 380, M381, - M400 = 400, M401, M402, M404 = 404, M405, M406, M407, M408, - M420 = 420, M421, - M450 = 450, M451, M452, M453, + M350 = 350, + M351, + M355 = 355, + M360 = 360, + M361, + M362, + M363, + M364, + M365, + M366, + M370 = 370, + M371, + M372, + M373, + M374, + M375, + M380 = 380, + M381, + M400 = 400, + M401, + M402, + M404 = 404, + M405, + M406, + M407, + M408, + M420 = 420, + M421, + M450 = 450, + M451, + M452, + M453, M460 = 460, - M500 = 500, M501, M502, M503, + M500 = 500, + M501, + M502, + M503, M540 = 540, - M550 = 550, M551, M552, M553, M554, M555, M556, M557, M558, M559, - M560, M561, M562, M563, M564, M565, M566, M567, M568, M569, - M570, M571, M572, M573, M574, M575, M577 = 577, M578, M579, - M580 = 580, M581, M582, M583, M584, - M600 = 600, M605 = 605, M665 = 665, M666 = 666, M667, M668, - M700 = 700, M701, M702, M703, + M550 = 550, + M551, + M552, + M553, + M554, + M555, + M556, + M557, + M558, + M559, + M560, + M561, + M562, + M563, + M564, + M565, + M566, + M567, + M568, + M569, + M570, + M571, + M572, + M573, + M574, + M575, + M577 = 577, + M578, + M579, + M580 = 580, + M581, + M582, + M583, + M584, + M600 = 600, + M605 = 605, + M665 = 665, + M666 = 666, + M667, + M668, + M700 = 700, + M701, + M702, + M703, M710 = 710, - M800 = 800, M801, + M800 = 800, + M801, M851 = 851, - M906 = 906, M907, M908, - M910 = 910, M911, M912, M913, + M906 = 906, + M907, + M908, + M910 = 910, + M911, + M912, + M913, M928 = 928, - M997 = 997, M998, M999 + M997 = 997, + M998, + M999 }; Q_ENUM(MCommands) /** * @brief Return Description of command \p gcode * @param gcode: Command to describe * @return description of GCommand */ static QString description(GCommands gcode); /** * @brief Return Description of command \p gcode * @param gcode: Command to describe * @return description of MCommand */ static QString description(MCommands gcode); /** * @brief Convert GCode::GCommands to command * @param gcode: GCode::GCommands * @param value1: Value of argument * @return Command String to send to printer */ static QString toCommand(GCommands gcode, const QString &value1 = QString()); /** * @brief Convert GCode::MCommands to command * @param gcode: GCode::MCommands * @param value1: Value of argument 1 * @param value2: Value of argument 2 * @return Command String to send to printer */ static QString toCommand(MCommands gcode, const QString &value1 = QString(), const QString &value2 = QString()); + protected: static const QString commandRequiresArgument; static const QString commandNotSupported; }; diff --git a/src/core/ifirmware.h b/src/core/ifirmware.h index 6523aec..a7e73f5 100644 --- a/src/core/ifirmware.h +++ b/src/core/ifirmware.h @@ -1,99 +1,100 @@ /* AtCore 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 . */ #pragma once #include #include #include "atcore_export.h" class Temperature; class AtCore; /** * @brief The IFirmware class * Base Class for Firmware Plugins */ -class ATCORE_EXPORT IFirmware : public QObject +class ATCORE_EXPORT IFirmware : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(bool sdSupport READ isSdSupported CONSTANT) public: IFirmware(); void init(AtCore *parent); ~IFirmware() override = default; /** * @brief Check for plugin support of sd cards. * @return True if firmware plugin supports sd cards. */ virtual bool isSdSupported() const = 0; /** * @brief Virtual name to be reimplemented by Firmware plugin * * Return the name the firmware the plugin is for * @return Firmware Name */ virtual QString name() const = 0; /** * @brief Virtual validateCommand to filter commands from messages * @param lastMessage: last Message from printer */ virtual void validateCommand(const QString &lastMessage); /** * @brief Virtual translate to be reimplemented by Firmwareplugin * * Translate common commands to firmware specific command. * @param command: Command command to translate * @return firmware specific translated command */ virtual QByteArray translate(const QString &command); /** * @brief AtCore Parent of the firmware plugin * @return */ AtCore *core() const; + private: struct IFirmwarePrivate; IFirmwarePrivate *d; public slots: /** * @brief call Validate Command * @param lastMessage: last message from printer */ void checkCommand(const QByteArray &lastMessage); signals: /** * @brief emit when firmware is ready for a command */ void readyForCommand(void); }; Q_DECLARE_INTERFACE(IFirmware, "org.kde.atelier.core.firmware") diff --git a/src/core/machineinfo.cpp b/src/core/machineinfo.cpp index 11719c7..2232abc 100644 --- a/src/core/machineinfo.cpp +++ b/src/core/machineinfo.cpp @@ -1,195 +1,193 @@ /* AtCore Copyright (C) <2019> 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 "machineinfo.h" #include #include Q_LOGGING_CATEGORY(MACHINE_INFO, "org.kde.atelier.core.machineInfo") -const QMap MachineInfo::decoderMap = { - {KEY::NAME, {QStringLiteral("Name"), QStringLiteral("ProfileName")}}, - {KEY::BAUDRATE, {QStringLiteral("bps"), 115200}}, - {KEY::FIRMWARE, {QStringLiteral("firmware"), QStringLiteral("Auto-Detect")}}, - {KEY::MAXBEDTEMP, {QStringLiteral("maximumTemperatureBed"), 0}}, - {KEY::MAXEXTTEMP, {QStringLiteral("maximumTemperatureExtruder"), 0}}, - {KEY::POSTPAUSE, {QStringLiteral("postPause"), QString()}}, - {KEY::ISCARTESIAN, {QStringLiteral("isCartesian"), false}}, - {KEY::XMAX, {QStringLiteral("dimensionX"), 200}}, - {KEY::YMAX, {QStringLiteral("dimensionY"), 200}}, - {KEY::ZMAX, {QStringLiteral("dimensionZ"), 180}}, - {KEY::AUTOTEMPREPORT, {QStringLiteral("autoReportTemp"), false}} -}; +const QMap MachineInfo::decoderMap = {{KEY::NAME, {QStringLiteral("Name"), QStringLiteral("ProfileName")}}, + {KEY::BAUDRATE, {QStringLiteral("bps"), 115200}}, + {KEY::FIRMWARE, {QStringLiteral("firmware"), QStringLiteral("Auto-Detect")}}, + {KEY::MAXBEDTEMP, {QStringLiteral("maximumTemperatureBed"), 0}}, + {KEY::MAXEXTTEMP, {QStringLiteral("maximumTemperatureExtruder"), 0}}, + {KEY::POSTPAUSE, {QStringLiteral("postPause"), QString()}}, + {KEY::ISCARTESIAN, {QStringLiteral("isCartesian"), false}}, + {KEY::XMAX, {QStringLiteral("dimensionX"), 200}}, + {KEY::YMAX, {QStringLiteral("dimensionY"), 200}}, + {KEY::ZMAX, {QStringLiteral("dimensionZ"), 180}}, + {KEY::AUTOTEMPREPORT, {QStringLiteral("autoReportTemp"), false}}}; MachineInfo *MachineInfo::instance() { static MachineInfo m; return &m; } -MachineInfo::MachineInfo(QObject *parent) : - QObject(parent) +MachineInfo::MachineInfo(QObject *parent) + : QObject(parent) , m_settings(new QSettings(QSettings::IniFormat, QSettings::UserScope, QStringLiteral("atcore"), QStringLiteral("profiles"), this)) { } QObject *MachineInfo::qmlSingletonRegister(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(scriptEngine) engine->setObjectOwnership(instance(), QQmlEngine::CppOwnership); return instance(); } QVariantMap MachineInfo::readProfile(const QString &profileName) const { m_settings->sync(); m_settings->beginGroup(profileName); - QVariantMap data{{decoderMap[KEY::NAME].name, m_settings->group()}}; + QVariantMap data {{decoderMap[KEY::NAME].name, m_settings->group()}}; for (int i = 1; i < decoderMap.size(); i++) { data.insert(decoderMap[MachineInfo::KEY(i)].name, m_settings->value(decoderMap[MachineInfo::KEY(i)].name, decoderMap[MachineInfo::KEY(i)].defaultValue)); } m_settings->endGroup(); return data; } QVariant MachineInfo::readKey(const QString &profileName, MachineInfo::KEY key) const { if (profileName.isEmpty()) { return decoderMap[key].defaultValue; } if (key == KEY::NAME) { return profileName; } m_settings->sync(); return m_settings->value(QStringLiteral("%1/%2").arg(profileName, decoderMap[key].name), decoderMap[key].defaultValue); } bool MachineInfo::storeKey(const QString &profileName, const MachineInfo::KEY key, const QVariant &value) const { if (key == KEY::NAME) { - //copyProfile emits profilesChanged + // copyProfile emits profilesChanged return copyProfile(profileName, value.toString(), true); } if (!profileNames().contains(profileName)) { qCWarning(MACHINE_INFO) << "Keysave: Profile does not exsits, create profile before attempting to store keys."; return false; } if (readKey(profileName, key) == value) { return false; } m_settings->beginGroup(profileName); m_settings->setValue(decoderMap[key].name, value); m_settings->endGroup(); m_settings->sync(); emit profilesChanged(); return true; } bool MachineInfo::copyProfile(const QString &srcProfile, const QString &destProfile, bool rmSrc) const { if (srcProfile.isEmpty() || destProfile.isEmpty()) { qCWarning(MACHINE_INFO) << "Profile Copy Error: Source or Destination Profile Is Empty."; return false; } if (!profileNames().contains(srcProfile)) { qCWarning(MACHINE_INFO) << "Profile Copy Error: Source Not Found."; return false; } if (srcProfile == destProfile) { qCWarning(MACHINE_INFO) << "Profile Copy Error: Source is Destination."; return false; } QVariantMap newProfile = readProfile(srcProfile); m_settings->beginGroup(destProfile); for (int i = 1; i < decoderMap.size(); i++) { m_settings->setValue(decoderMap[MachineInfo::KEY(i)].name, newProfile[decoderMap[MachineInfo::KEY(i)].name]); } m_settings->endGroup(); m_settings->sync(); if (rmSrc) { removeProfile(srcProfile); - //removeProfile emits profilesChanged + // removeProfile emits profilesChanged } else { emit profilesChanged(); } return true; } bool MachineInfo::removeProfile(const QString &profileName) const { if (!profileNames().contains(profileName)) { qCWarning(MACHINE_INFO) << "Profile Remove Error: Profile not found."; return false; } m_settings->beginGroup(profileName); m_settings->remove(QString()); m_settings->endGroup(); m_settings->sync(); emit profilesChanged(); - return true; + return true; } void MachineInfo::storeProfile(const QMap &profile) const { m_settings->beginGroup(profile[KEY::NAME].toString()); for (int i = 1; i < decoderMap.size(); i++) { m_settings->setValue(decoderMap[MachineInfo::KEY(i)].name, profile[MachineInfo::KEY(i)]); } m_settings->endGroup(); m_settings->sync(); emit profilesChanged(); } void MachineInfo::storeProfile(const QVariantMap &profile) const { m_settings->beginGroup(profile.first().toString()); for (auto it = profile.begin(), end = profile.end(); it != end; ++it) { m_settings->setValue(it.key(), it.value()); } m_settings->endGroup(); m_settings->sync(); emit profilesChanged(); } QStringList MachineInfo::profileNames() const { m_settings->sync(); return m_settings->childGroups(); } QString MachineInfo::keyName(const MachineInfo::KEY key) const { auto it = decoderMap.find(key); if (it != decoderMap.end()) { return it.value().name; } return QString(); } diff --git a/src/core/machineinfo.h b/src/core/machineinfo.h index d12129b..737cf0a 100644 --- a/src/core/machineinfo.h +++ b/src/core/machineinfo.h @@ -1,164 +1,164 @@ /* AtCore Copyright (C) <2019> 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 . */ #pragma once #include "atcore_export.h" #include -#include #include +#include #include class ATCORE_EXPORT MachineInfo : public QObject { Q_OBJECT Q_PROPERTY(QStringList profileNames READ profileNames NOTIFY profilesChanged) public: /** * @brief KEYS enum Possible keys for the printer settings */ enum class KEY { NAME = 0, //!< Profile Name BAUDRATE, //!< Machine BAUD Rate - FIRMWARE, //! &profile) const; /** * @brief Store a new profile, Must be used for new profiles or to override a profile. * @param profile: A complete machine profile or one that at very least has a profile Name and any other valid Key. * @sa storeKey() */ Q_INVOKABLE void storeProfile(const QVariantMap &profile) const; /** * @brief Store a key to an existing profile, Sending a key of Key::NAME will rename the profile * @param profileName: profile to write into * @param key: The key you will write to * @param value: The value you will store. * @return true if successful * @sa storeProfile() */ Q_INVOKABLE bool storeKey(const QString &profileName, const MachineInfo::KEY key, const QVariant &value) const; /** * @brief copyies a profile and optionally deletes the src profile * @param srcProfile: profiles Current Name * @param destProfile: profiles New Name * @param rmSrc: delete srcProfile (defalut false) * @return true if successful */ Q_INVOKABLE bool copyProfile(const QString &srcProfile, const QString &destProfile, bool rmSrc = false) const; /** * @brief Remove a full profile * @param profileName: name of the profile you want to remove. * @return true if successful. */ Q_INVOKABLE bool removeProfile(const QString &profileName) const; /** * @brief Get a list of all the profile names * @return QStringList containing the stored profile names. */ QStringList profileNames() const; /** * @brief Translate a key enum to string * @param key: name of the key to be translated. * @return key string if successful. */ Q_INVOKABLE QString keyName(const MachineInfo::KEY key) const; signals: /** * @brief A profile has changed */ void profilesChanged() const; private: - MachineInfo *operator = (MachineInfo &other) = delete; + MachineInfo *operator=(MachineInfo &other) = delete; MachineInfo(const MachineInfo &other) = delete; explicit MachineInfo(QObject *parent = nullptr); ~MachineInfo() = default; /** * @brief used to hold MachineInfo::KEY name and defaultValues. */ struct keyInfo { - QString name; //!< Key name used in the settings file + QString name; //!< Key name used in the settings file QVariant defaultValue; //!< Defaut Value for the key }; /** * @brief Map of MachineInfo::KEY , KeyString and DefaultValue */ static const QMap decoderMap; /** * @brief m_settings our settings object. */ QSettings *m_settings = nullptr; }; diff --git a/src/core/printthread.cpp b/src/core/printthread.cpp index 59bfcae..9837d83 100644 --- a/src/core/printthread.cpp +++ b/src/core/printthread.cpp @@ -1,229 +1,220 @@ /* 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 +#include #include "printthread.h" Q_LOGGING_CATEGORY(PRINT_THREAD, "org.kde.atelier.core.printThread") /** * @brief The PrintThreadPrivate class */ class PrintThread::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. + 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, const QString &fileName) : d(new PrintThreadPrivate) +PrintThread::PrintThread(AtCore *parent, const 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); 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); 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->stillSize -= d->cline.size() + 1; // remove read chars d->printProgress = float(d->totalSize - d->stillSize) * 100 / float(d->totalSize); qCDebug(PRINT_THREAD) << "progress:" << QString::number(double(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 + // 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 + // Type 2: Block Type anything between ( and ) is a comment // Example G28 (Home)Z if (d->cline.contains(QChar::fromLatin1('('))) { - //Remove (.....) from the line + // 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 - ) - ) { + 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).toString(), - QVariant::fromValue(newState).toString()); + qCDebug(PRINT_THREAD) << QStringLiteral("State changed from [%1] to [%2]").arg(QVariant::fromValue(d->state).toString(), QVariant::fromValue(newState).toString()); disconnect(d->core, &AtCore::stateChanged, this, &PrintThread::setState); d->state = newState; emit stateChanged(d->state); connect(d->core, &AtCore::stateChanged, this, &PrintThread::setState, Qt::QueuedConnection); } } void PrintThread::injectCommand(QString &command) { - //remove the ; + // 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).toUInt(), args.at(1).toUInt(), 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).toUInt(), wait); } else if (parser.isSet(QStringLiteral("print speed"))) { d->core->setPrinterSpeed(parser.positionalArguments().at(0).toUInt()); } else if (parser.isSet(QStringLiteral("fan speed"))) { d->core->setFanSpeed(parser.positionalArguments().at(0).toUInt(), parser.positionalArguments().at(1).toUInt()); } else if (parser.isSet(QStringLiteral("flow rate"))) { d->core->setFlowRate(parser.positionalArguments().at(0).toUInt()); } 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/printthread.h b/src/core/printthread.h index 50a44a8..c0157bd 100644 --- a/src/core/printthread.h +++ b/src/core/printthread.h @@ -1,153 +1,153 @@ /* 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 . */ #pragma once -#include #include +#include #include "atcore.h" /** * @brief The PrintThread class * A Thread for running a print job * * see AtCore::print() for example of how to create a print thread. * */ class ATCORE_EXPORT PrintThread : public QObject { Q_OBJECT public: /** * @brief Create a new Print Thread * @param parent: Parent of the tread * @param fileName: gcode File to print */ PrintThread(AtCore *parent, const QString &fileName); signals: /** - * @brief Print job has finished - */ + * @brief Print job has finished + */ void finished(); /** * @brief A command has caused an error * @param err: the offending command */ void error(QString err); /** * @brief The print job's progress has changed */ void printProgressChanged(const float); /** * @brief the next command of the job * @param comm: Command to be sent next */ void nextCommand(const QString &comm); /** * @brief Printer state was changed * @param state: new state */ void stateChanged(const AtCore::STATES &state); public slots: /** * @brief start the print thread */ void start(); private slots: /** * @brief process the current job */ void processJob(); /** * @brief Set printer state * @param state: the new printer state */ void setState(const AtCore::STATES &state); private: /** * @brief parse the next line */ void nextLine(); /** * @brief end the print */ void endPrint(); /** * @brief injectCommand Attempt to inject a Command from the currently printing file. * * One of the following on a line that starts with ';-' \n * example line ;-Message: Hello \n * * - Pause: ppc\n * Pause the print job and then run the comma-separated commands after pausing the job.\n * + ppc: A comma-separated list of Commands to send after pause. ex(G91, G0 Z1, G90, G1 X0 Y195)\n *\n * - Extruder %Temperature:newTemp,extnum,wait \n * Set extruder temperature. \n * + newTemp: new target temperature. \n * + extnum: Extruder number you want to Heat. Starting at 0. \n * + wait: ignore commands until the target is reached. [true | false] \n *\n * - Bed %Temperature: newTemp,wait \n * Set the bed temperature. \n * + newTemp: new target temperature \n * + wait: ignore commands until the target is reached. [true | false] \n *\n * - Fan Speed:newSpeed, fanNum \n * Set the Fan speed. \n * + newSpeed: new fan speed. \n * + fanNum: Fan number. Starting at 0.\n *\n * - Print Speed:newSpeed \n * Set the printer speed. \n * + newSpeed: the print speed. 100= movement speed defined in file. \n *\n * - Flow Rate:newRate \n * Set the flow rate \n * + newRate: the flow rate. 100 = flow rate defined in file. \n *\n * - Message:message \n * Show a message the printer's LCD \n * + message: the message to print. \n *\n * - Command:command \n * Inject your own command. Command are sent as is. Be sure your line is correct. \n * + command: Commands to inject \n */ void injectCommand(QString &command); /** * @brief d: Private storage for the thread */ class PrintThreadPrivate; PrintThreadPrivate *d; }; diff --git a/src/core/seriallayer.cpp b/src/core/seriallayer.cpp index ba4b6c0..5c7d516 100644 --- a/src/core/seriallayer.cpp +++ b/src/core/seriallayer.cpp @@ -1,167 +1,165 @@ /* AtCore Copyright (C) <2016 - 2018> 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") /** * @brief The SerialLayerPrivate class */ struct SerialLayer::SerialLayerPrivate { /** _lastError: the last reported error */ QSerialPort::SerialPortError _lastError = QSerialPort::NoError; /** New Line String */ static const QByteArray _newLine; /** New Line Return String */ static const QByteArray _newLineReturn; /** _rawData: the raw serial data */ QByteArray _rawData; /** _rByteCommand: received Messages */ QVector _rByteCommands; /** Return String */ static const QByteArray _return; /** _sByteCommand: sent Messages */ QVector _sByteCommands; /** _serialOpened: is Serial port opened */ bool _serialOpened = false; /** List of valid Baud Rates */ static const QStringList _validBaudRates; }; const QByteArray SerialLayer::SerialLayerPrivate::_newLine = QByteArray("\n"); const QByteArray SerialLayer::SerialLayerPrivate::_newLineReturn = QByteArray("\n\r"); const QByteArray SerialLayer::SerialLayerPrivate::_return = QByteArray("\r"); -const QStringList SerialLayer::SerialLayerPrivate::_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") -}; - -SerialLayer::SerialLayer(const QString &port, int32_t baud, QObject *parent) : - QSerialPort(parent), d(new SerialLayerPrivate()) +const QStringList SerialLayer::SerialLayerPrivate::_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")}; + +SerialLayer::SerialLayer(const QString &port, int32_t 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); connect(this, &QSerialPort::errorOccurred, this, &SerialLayer::handleError); } }; 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 + // 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(d->_return, QByteArray()); QList tempList = d->_rawData.split(d->_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); } 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); - } void SerialLayer::pushCommand(const QByteArray &comm) { pushCommand(comm, d->_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, d->_newLineReturn); } void SerialLayer::push() { if (!isOpen()) { qCDebug(SERIAL_LAYER) << "Serial not connected !"; return; } for (const auto &comm : qAsConst(d->_sByteCommands)) { write(comm); emit pushedCommand(comm); } d->_sByteCommands.clear(); } bool SerialLayer::commandAvailable() const { return !d->_rByteCommands.isEmpty(); } QStringList SerialLayer::validBaudRates() const { return d->_validBaudRates; } void SerialLayer::handleError(QSerialPort::SerialPortError error) { if (d->_lastError == error) { return; } d->_lastError = error; emit serialError(error); } diff --git a/src/core/seriallayer.h b/src/core/seriallayer.h index 3fdacbf..b4cc49b 100644 --- a/src/core/seriallayer.h +++ b/src/core/seriallayer.h @@ -1,136 +1,136 @@ /* AtCore Copyright (C) <2016 - 2018> 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 . */ #pragma once #include #include #include "atcore_export.h" /** * @brief The SerialLayer class. * Provide the low level serial operations */ class ATCORE_EXPORT SerialLayer : public QSerialPort { Q_OBJECT private: struct SerialLayerPrivate; SerialLayerPrivate *d; /** * @brief Read all available serial data * */ void readAllData(); signals: /** * @brief Emit signal when command is pushed * * @param comm : Command */ void pushedCommand(const QByteArray &comm); /** * @brief Emit signal when command is received * * @param comm : Command */ void receivedCommand(const QByteArray &comm); /** * @brief Emit a signal if an error has happened. * @param error: the Error */ void serialError(QSerialPort::SerialPortError error); -public: +public: /** * @brief SerialLayer Class to realize communication * * @param port : Port (/dev/ttyUSB ACM) * @param baud : Baud rate (115200) * @param parent : Parent */ SerialLayer(const QString &port, int32_t baud, QObject *parent = nullptr); /** * @brief Add command to be pushed * * @param comm : Command * @param term : Terminator */ void add(const QByteArray &comm, const QByteArray &term); /** * @brief Add command to be pushed * * @param comm : Command, default terminator will be used */ void add(const QByteArray &comm); /** * @brief handleError Handle Errors from the serial port * @param error: The reported error */ void handleError(QSerialPort::SerialPortError error); /** * @brief Push command directly * * @param comm : Command * @param term : Terminator */ void pushCommand(const QByteArray &comm, const QByteArray &term); /** * @brief Push command directly * * @param comm : Command, default terminator will be used */ void pushCommand(const QByteArray &comm); /** * @brief Push all commands used in add to serial write * */ void push(); /** * @brief Check if is a command available * * @return bool */ bool commandAvailable() const; /** * @brief Return a QStringList of valids serial baud rates * * @return QStringList */ QStringList validBaudRates() const; }; diff --git a/src/core/temperature.h b/src/core/temperature.h index 13a11cc..047f538 100644 --- a/src/core/temperature.h +++ b/src/core/temperature.h @@ -1,107 +1,108 @@ /* AtCore Copyright (C) <2016> Authors: Tomaz Canabrava 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 . */ #pragma once #include #include "atcore_export.h" /** * @brief The Temperature class * * Read and hold the Temperature info for the printer */ class ATCORE_EXPORT Temperature : public QObject { Q_OBJECT Q_PROPERTY(float bedTemperature READ bedTemperature NOTIFY bedTemperatureChanged) Q_PROPERTY(float bedTargetTemperature READ bedTargetTemperature NOTIFY bedTargetTemperatureChanged) Q_PROPERTY(float extruderTemperature READ extruderTemperature NOTIFY extruderTemperatureChanged) Q_PROPERTY(float extruderTargetTemperature READ extruderTargetTemperature NOTIFY extruderTargetTemperatureChanged) friend class TemperatureTests; public: /** * @brief Create a new Temperature object * @param parent */ explicit Temperature(QObject *parent = nullptr); /** * @brief Get bed current temperature */ float bedTemperature() const; /** * @brief Get bed target temperature */ float bedTargetTemperature() const; /** * @brief decode Temp values from string \p msg * @param msg: string to read vaules from */ void decodeTemp(const QByteArray &msg); /** * @brief Get extruder temperature */ float extruderTemperature() const; /** * @brief Get extruder target temperature */ float extruderTargetTemperature() const; signals: /** * @brief bed temperature has changed */ void bedTemperatureChanged(); /** * @brief bed target temperature has changed */ void bedTargetTemperatureChanged(); /** * @brief extruder temperature has changed */ void extruderTemperatureChanged(); /** * @brief extruder target temperature has changed */ void extruderTargetTemperatureChanged(); protected: /** * @brief Reset internal temperature data, For Tests-Only */ void resetData(); + private: struct TemperaturePrivate; TemperaturePrivate *d; }; diff --git a/src/imports/atcoreextensionplugin.cpp b/src/imports/atcoreextensionplugin.cpp index 22c91ec..15d01e1 100644 --- a/src/imports/atcoreextensionplugin.cpp +++ b/src/imports/atcoreextensionplugin.cpp @@ -1,35 +1,33 @@ /* AtCore Imports Copyright (C) <2019> Authors: Lays Rodrigues 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 "atcoreextensionplugin.h" +#include #include -#include #include -#include +#include void AtCoreExtensionPlugin::registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("org.kde.atcore")); qmlRegisterType("org.kde.atcore", 1, 0, "AtCore"); qmlRegisterType("org.kde.atcore", 1, 0, "Temperature"); - qmlRegisterSingletonType("org.kde.atcore", 1, 0, "MachineInfo", [](QQmlEngine *engine, QJSEngine *jsEngine) -> QObject * { - return MachineInfo::instance()->qmlSingletonRegister(engine, jsEngine); - }); + qmlRegisterSingletonType("org.kde.atcore", 1, 0, "MachineInfo", [](QQmlEngine *engine, QJSEngine *jsEngine) -> QObject * { return MachineInfo::instance()->qmlSingletonRegister(engine, jsEngine); }); } diff --git a/src/imports/atcoreextensionplugin.h b/src/imports/atcoreextensionplugin.h index 37d5936..7d57386 100644 --- a/src/imports/atcoreextensionplugin.h +++ b/src/imports/atcoreextensionplugin.h @@ -1,30 +1,31 @@ /* AtCore Imports Copyright (C) <2019> Authors: Lays Rodrigues 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 . */ #pragma once #include -class AtCoreExtensionPlugin : public QQmlExtensionPlugin { +class AtCoreExtensionPlugin : public QQmlExtensionPlugin +{ Q_OBJECT Q_PLUGIN_METADATA(IID "org.kde.atcore") public: void registerTypes(const char *uri) override; }; diff --git a/src/plugins/grblplugin.cpp b/src/plugins/grblplugin.cpp index 845a18c..fd8e6f6 100644 --- a/src/plugins/grblplugin.cpp +++ b/src/plugins/grblplugin.cpp @@ -1,77 +1,77 @@ /* 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 "grblplugin.h" #include #include #include -#include "grblplugin.h" Q_LOGGING_CATEGORY(GRBL_PLUGIN, "org.kde.atelier.core.firmware.grbl") QString GrblPlugin::name() const { return QStringLiteral("Grbl"); } GrblPlugin::GrblPlugin() { qCDebug(GRBL_PLUGIN) << name() << " plugin loaded!"; } bool GrblPlugin::isSdSupported() const { return false; } void GrblPlugin::validateCommand(const QString &lastMessage) { if (lastMessage.contains(QStringLiteral("ok"))) { emit readyForCommand(); } } QByteArray GrblPlugin::translate(const QString &command) { QString temp = command; - //Match all G and M commands followed by one or more digits up to and include the space, - //if thats followed by a letter capture any non G or M starting text - //else just grab the digits that follow. - //ex: G28 X Y M1 would capture "G28 X Y" and "M1" + // Match all G and M commands followed by one or more digits up to and include the space, + // if thats followed by a letter capture any non G or M starting text + // else just grab the digits that follow. + // ex: G28 X Y M1 would capture "G28 X Y" and "M1" static const auto regEx = QRegularExpression(QStringLiteral("[GM]\\d+.(?(?=\\D)[^GM]+|\\d+)?")); QRegularExpressionMatch secondCommand = regEx.match(temp, 1); if (secondCommand.hasMatch()) { QRegularExpressionMatchIterator commandMatch = regEx.globalMatch(temp); temp.clear(); while (commandMatch.hasNext()) { QRegularExpressionMatch t = commandMatch.next(); temp.append(t.captured().simplified()); if (commandMatch.hasNext()) { temp.append(QStringLiteral("\r\n")); } } } return temp.toLocal8Bit(); } diff --git a/src/plugins/marlinplugin.cpp b/src/plugins/marlinplugin.cpp index a876434..39001c3 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" +#include "marlinplugin.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 + // 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); 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 0183cc2..b7c94fe 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" +#include "repetierplugin.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 + // 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 + // 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); 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/smoothieplugin.cpp b/src/plugins/smoothieplugin.cpp index f335fb0..79cef7d 100644 --- a/src/plugins/smoothieplugin.cpp +++ b/src/plugins/smoothieplugin.cpp @@ -1,46 +1,46 @@ /* 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 "smoothieplugin.h" #include "atcore.h" +#include "smoothieplugin.h" Q_LOGGING_CATEGORY(SMOOTHIE_PLUGIN, "org.kde.atelier.core.firmware.smoothie") QString SmoothiePlugin::name() const { return QStringLiteral("Smoothie"); } bool SmoothiePlugin::isSdSupported() const { return false; } SmoothiePlugin::SmoothiePlugin() { qCDebug(SMOOTHIE_PLUGIN) << name() << " plugin loaded!"; } diff --git a/src/plugins/sprinterplugin.cpp b/src/plugins/sprinterplugin.cpp index 90c57cd..daea139 100644 --- a/src/plugins/sprinterplugin.cpp +++ b/src/plugins/sprinterplugin.cpp @@ -1,46 +1,46 @@ /* 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 -#include "sprinterplugin.h" #include "atcore.h" +#include "sprinterplugin.h" Q_LOGGING_CATEGORY(SPRINTER_PLUGIN, "org.kde.atelier.core.firmware.sprinter") QString SprinterPlugin::name() const { return QStringLiteral("Sprinter"); } bool SprinterPlugin::isSdSupported() const { return false; } SprinterPlugin::SprinterPlugin() { qCDebug(SPRINTER_PLUGIN) << name() << " plugin loaded!"; } diff --git a/src/plugins/sprinterplugin.h b/src/plugins/sprinterplugin.h index c296875..80d618b 100644 --- a/src/plugins/sprinterplugin.h +++ b/src/plugins/sprinterplugin.h @@ -1,59 +1,58 @@ /* 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 . */ #pragma once #include #include "ifirmware.h" /** * @brief The SprinterPlugin class * Plugin for Sprinter */ class SprinterPlugin : public IFirmware { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kde.atelier.core.firmware") Q_INTERFACES(IFirmware) public: /** * @brief Create new SprinterPlugin */ SprinterPlugin(); ~SprinterPlugin() = default; /** * @brief Check for plugin support of sd cards. * @return True if firmware plugin supports sd cards. */ virtual bool isSdSupported() const override; /** * @brief Return Plugin name * @return Sprinter */ QString name() const override; - }; diff --git a/src/plugins/teacupplugin.cpp b/src/plugins/teacupplugin.cpp index dee9a70..b48aa72 100644 --- a/src/plugins/teacupplugin.cpp +++ b/src/plugins/teacupplugin.cpp @@ -1,59 +1,59 @@ /* 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 -#include "teacupplugin.h" #include "atcore.h" +#include "teacupplugin.h" Q_LOGGING_CATEGORY(TEACUP_PLUGIN, "org.kde.atelier.core.firmware.teacup") QString TeacupPlugin::name() const { return QStringLiteral("Teacup"); } bool TeacupPlugin::isSdSupported() const { return false; } TeacupPlugin::TeacupPlugin() { qCDebug(TEACUP_PLUGIN) << name() << " plugin loaded!"; } QByteArray TeacupPlugin::translate(const QString &command) { QString temp = command; if (command.contains(QStringLiteral("M109"))) { temp.replace(QStringLiteral("M109"), QStringLiteral("M104")); temp.append(QStringLiteral("\r\nM116")); } else if (command.contains(QStringLiteral("M190"))) { temp.replace(QStringLiteral("M190"), QStringLiteral("M140")); temp.append(QStringLiteral("\r\nM116")); } return temp.toLocal8Bit(); } diff --git a/src/widgets/about.cpp b/src/widgets/about.cpp index 36269ad..78e7f31 100644 --- a/src/widgets/about.cpp +++ b/src/widgets/about.cpp @@ -1,67 +1,67 @@ /* AtCore Test Client Copyright (C) <2017> Authors: Chris Rizzitello 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 "about.h" -About::About(QWidget *parent) : - QDialog(parent) +About::About(QWidget *parent) + : QDialog(parent) { setWindowTitle(QStringLiteral("About Atcore")); setWindowIcon(QIcon::fromTheme(QStringLiteral("help-about"), style()->standardIcon(QStyle::SP_MessageBoxInformation))); auto lbl_version = new QLabel(tr("Version: %1").arg(QCoreApplication::applicationVersion()), this); auto lbl_qt_version = new QLabel(tr("Using Qt: %1").arg(QString::fromLatin1(qVersion())), this); auto lbl_authors = new QLabel(tr("Authors:\n" " Chris Rizzitello \n" " Patrick José Pereira \n" " Lays Rodrigues \n" - " Tomaz Canabrava " - ""), this); + " Tomaz Canabrava "), + this); auto lbl_icon = new QLabel(this); lbl_icon->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); lbl_icon->setScaledContents(true); lbl_icon->setPixmap(QPixmap(QStringLiteral(":/icon/atcore"))); auto btn_close = new QPushButton(tr("Close"), this); connect(btn_close, &QPushButton::clicked, this, &QDialog::close); auto versionInfo = new QVBoxLayout; versionInfo->addWidget(lbl_version); versionInfo->addWidget(lbl_qt_version); auto topLayout = new QVBoxLayout; topLayout->setContentsMargins(0, 0, 0, 0); topLayout->addWidget(lbl_icon); topLayout->addItem(versionInfo); auto mainLayout = new QVBoxLayout; mainLayout->addItem(topLayout); mainLayout->addWidget(lbl_authors); mainLayout->addWidget(btn_close); setLayout(mainLayout); } diff --git a/src/widgets/axiscontrol.cpp b/src/widgets/axiscontrol.cpp index 181320a..9735dd1 100644 --- a/src/widgets/axiscontrol.cpp +++ b/src/widgets/axiscontrol.cpp @@ -1,123 +1,121 @@ /* AtCore Test Client Copyright (C) <2016 - 2018> Authors: Chris Rizzitello 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 "axiscontrol.h" #include #include #include #include -AxisControl::AxisControl(QWidget *parent) : - QWidget(parent) +AxisControl::AxisControl(QWidget *parent) + : QWidget(parent) , sbValue(new QDoubleSpinBox) { auto mainLayout = new QVBoxLayout; auto newLabel = new QLabel(tr("Move Axis"), this); sbValue->setSuffix(QStringLiteral(" mm")); sbValue->setDecimals(3); sbValue->setMaximum(100.0); sbValue->setValue(1); auto comboUnits = new QComboBox(this); comboUnits->addItems(QStringList {QStringLiteral("Metric"), QStringLiteral("Imperial")}); connect(comboUnits, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int selection) { if (selection == 0) { sbValue->setSuffix(QStringLiteral(" mm")); } else { sbValue->setSuffix(QStringLiteral(" in")); } emit unitsChanged(selection); }); auto layout = new QHBoxLayout(); layout->addWidget(newLabel); layout->addWidget(sbValue); layout->addWidget(comboUnits); auto newWidget = new QWidget(this); newWidget->setLayout(layout); newWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); mainLayout->addWidget(newWidget); QSize iconSize = QSize(fontMetrics().height(), fontMetrics().height()); auto glayout = new QGridLayout(); newLabel = new QLabel(QStringLiteral("X/Y"), this); newLabel->setAlignment(Qt::AlignCenter); glayout->addWidget(newLabel, 2, 1); - //Y-Axis + // Y-Axis glayout->addWidget(makeButton(QLatin1Char('Y'), 1, iconSize, QStringLiteral("arrow-up"), QStringLiteral("↑")), 1, 1); glayout->addWidget(makeButton(QLatin1Char('Y'), -1, iconSize, QStringLiteral("arrow-down"), QStringLiteral("↓")), 3, 1); - //X-Axis + // X-Axis glayout->addWidget(makeButton(QLatin1Char('X'), -1, iconSize, QStringLiteral("arrow-left"), QStringLiteral("←")), 2, 0); glayout->addWidget(makeButton(QLatin1Char('X'), 1, iconSize, QStringLiteral("arrow-right"), QStringLiteral("→")), 2, 3); auto bottomLayout = new QHBoxLayout(); bottomLayout->addItem(glayout); newWidget = makeSimpleAxis(QLatin1Char('Z'), iconSize); bottomLayout->addWidget(newWidget); newWidget = makeSimpleAxis(QLatin1Char('E'), iconSize); bottomLayout->addWidget(newWidget); mainLayout->addItem(bottomLayout); setLayout(mainLayout); } QPushButton *AxisControl::makeButton(const QLatin1Char axis, int multiplier, const QSize &iconSize, const QString &themeIcon, const QString &fallbackText) { auto button = new QPushButton(QIcon::fromTheme(themeIcon), QString(), this); button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); if (button->icon().isNull()) { button->setText(fallbackText); } else { button->setIconSize(iconSize); } - connect(button, &QPushButton::clicked, this, [this, axis, multiplier] { - emit clicked(axis, sbValue->value() *multiplier); - }); + connect(button, &QPushButton::clicked, this, [this, axis, multiplier] { emit clicked(axis, sbValue->value() * multiplier); }); return button; } QWidget *AxisControl::makeSimpleAxis(const QLatin1Char axis, const QSize &iconSize) { int multiplier = 1; if (axis == QLatin1Char('E')) { multiplier = -1; } auto vLayout = new QVBoxLayout; vLayout->addWidget(makeButton(axis, multiplier, iconSize, QStringLiteral("arrow-up"), QStringLiteral("↑"))); auto label = new QLabel(QString(axis), this); label->setAlignment(Qt::AlignCenter); vLayout->addWidget(label); multiplier *= -1; vLayout->addWidget(makeButton(axis, multiplier, iconSize, QStringLiteral("arrow-down"), QStringLiteral("↓"))); auto widget = new QWidget(this); widget->setLayout(vLayout); return widget; } diff --git a/src/widgets/commandwidget.cpp b/src/widgets/commandwidget.cpp index 6eaa4db..2a11515 100644 --- a/src/widgets/commandwidget.cpp +++ b/src/widgets/commandwidget.cpp @@ -1,81 +1,79 @@ /* 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) +CommandWidget::CommandWidget(QWidget *parent) + : QWidget(parent) { - //Expose the least amount of object outside the creation function. + // 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 + // 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(this); lineCommand->setPlaceholderText(tr("Send Command")); - //we have a few buttons to make here. Lets name this newButton so its easier to reuse + // we have a few buttons to make here. Lets name this newButton so its easier to reuse auto newButton = new QPushButton(tr("Send"), this); connect(newButton, &QPushButton::clicked, this, [this] { - if (!lineCommand->text().isEmpty()) - { + if (!lineCommand->text().isEmpty()) { if (lineCommand->text().startsWith(QStringLiteral("g"))) { lineCommand->setText(lineCommand->text().replace(0, 1, QStringLiteral("G"))); } else if (lineCommand->text().startsWith(QStringLiteral("m"))) { lineCommand->setText(lineCommand->text().replace(0, 1, QStringLiteral("M"))); } emit commandPressed(lineCommand->text()); lineCommand->clear(); } }); - //When you have created a Row put the items into layout. + // 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. + // 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. + // Start making items for the next layout to place onto the mainLayout. lineMessage = new QLineEdit(this); lineMessage->setPlaceholderText(tr("Show Message")); - //Reuse our button pointer. + // Reuse our button pointer. newButton = new QPushButton(tr("Send"), this); connect(newButton, &QPushButton::clicked, this, [this] { - if (!lineMessage->text().isEmpty()) - { + if (!lineMessage->text().isEmpty()) { emit messagePressed(lineMessage->text()); lineMessage->clear(); } }); - //We reuse the hBoxLayout pointer in the same way as the button pointer. + // 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/logwidget.cpp b/src/widgets/logwidget.cpp index 7381280..9cbf6c8 100644 --- a/src/widgets/logwidget.cpp +++ b/src/widgets/logwidget.cpp @@ -1,165 +1,164 @@ /* AtCore Test Client Copyright (C) <2018> Author: Chris Rizzitello - rizzitello@kde.org Patrick José Pereira 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 "logwidget.h" #include #include -#include #include +#include #include #include #include namespace { static constexpr QChar _newLine = QChar::fromLatin1('\n'); static constexpr QChar _return = QChar::fromLatin1('\r'); } -LogWidget::LogWidget(QTemporaryFile *tempFile, QWidget *parent) : - QWidget(parent), - logFile(tempFile) +LogWidget::LogWidget(QTemporaryFile *tempFile, QWidget *parent) + : QWidget(parent) + , logFile(tempFile) { QSize iconSize = QSize(fontMetrics().height(), fontMetrics().height()); auto page = new QWidget(this); textLog = new QPlainTextEdit(this); textLog->setReadOnly(true); textLog->setMaximumBlockCount(1000); auto pageLayout = new QVBoxLayout; pageLayout->addWidget(textLog); page->setLayout(pageLayout); auto mainStack = new QStackedWidget(this); mainStack->insertWidget(0, page); page = new QWidget(this); auto textbox = new QTextEdit(this); textbox->setReadOnly(true); - textbox->setHtml(tr("\ + textbox->setHtml( + tr("\

Special Log Entries

\

Failed to open device in read/write mode.

\

    The Device was not able to be opened.

\

       Check the device is not opened by another program.

\

       Check you have the correct permissions to open the device.

\

No plugin found for <Detected Firmware>

\

    Firmware plugins are missing or your firmware is not currently supported.

\

      Manually select the Marlin or Repetier plugin.

\

      If your firmware does not have a plugin please let us know.

\

Lots of “Waiting for firmware detect”

\

    Unable to send the firmware detect waiting for printer to restart

\

      Push the restart button on your printer or turn it on and off.

\

      Select a firmware plugin in place of auto detect.

")); pageLayout = new QVBoxLayout; pageLayout->addWidget(textbox); page->setLayout(pageLayout); mainStack->insertWidget(1, page); auto saveButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-save"), style()->standardIcon(QStyle::SP_DialogSaveButton)), tr("Save Session Log"), this); saveButton->setIconSize(iconSize); connect(saveButton, &QPushButton::clicked, this, &LogWidget::savePressed); auto helpButton = new QToolButton(this); helpButton->setCheckable(true); helpButton->setChecked(false); helpButton->setIconSize(iconSize); helpButton->setIcon(QIcon::fromTheme(QStringLiteral("help-about"), style()->standardIcon(QStyle::SP_DialogHelpButton))); - connect(helpButton, &QToolButton::clicked, this, [mainStack](bool checked) { - mainStack->setCurrentIndex(checked); - }); + connect(helpButton, &QToolButton::clicked, this, [mainStack](bool checked) { mainStack->setCurrentIndex(checked); }); auto buttonLayout = new QHBoxLayout; buttonLayout->addWidget(saveButton); buttonLayout->addWidget(helpButton); auto mainLayout = new QVBoxLayout; mainLayout->addWidget(mainStack); mainLayout->addLayout(buttonLayout); setLayout(mainLayout); } QString LogWidget::getTime() { return QTime::currentTime().toString(QStringLiteral("hh:mm:ss:zzz")); } void LogWidget::appendLog(const QString &msg) { QString message(QStringLiteral("[%1] %2").arg(getTime(), msg)); textLog->appendPlainText(message); writeTempFile(message); } void LogWidget::appendRLog(const QByteArray &bmsg) { QString message(QStringLiteral("[%1]< %2").arg(getTime(), QString::fromUtf8(bmsg))); textLog->appendPlainText(message); writeTempFile(message); } void LogWidget::appendSLog(const QByteArray &bmsg) { QString msg = QString::fromUtf8(bmsg); msg.replace(_newLine, QStringLiteral("\\n")); msg.replace(_return, QStringLiteral("\\r")); QString message(QStringLiteral("[%1]> %2").arg(getTime(), msg)); textLog->appendPlainText(message); writeTempFile(message); } void LogWidget::writeTempFile(const QString &text) { - //Add text to our unsynced string list when that hits 100 sync to the temp file. + // Add text to our unsynced string list when that hits 100 sync to the temp file. unsyncedStrings.append(text); if (unsyncedStrings.count() > 100) { flushTemp(); } } void LogWidget::flushTemp() { /* A QTemporaryFile will always be opened in QIODevice::ReadWrite mode, this allows easy access to the data in the file. This function will return true upon success and will set the fileName() to the unique filename used. */ logFile->open(); logFile->seek(logFile->size()); for (const auto &string : qAsConst(unsyncedStrings)) { logFile->write(string.toLatin1()); logFile->putChar('\n'); } logFile->close(); unsyncedStrings.clear(); } void LogWidget::savePressed() { - //If saving be sure we have flushed to temp. + // If saving be sure we have flushed to temp. flushTemp(); // Note that if a file with the name newName already exists, copy() returns false (i.e. QFile will not overwrite it). QString fileName = QDir::homePath() + QChar::fromLatin1('/') + QFileInfo(logFile->fileName()).fileName() + QStringLiteral(".txt"); QString saveFileName = QFileDialog::getSaveFileName(this, tr("Save Log to file"), fileName); QFile::copy(logFile->fileName(), saveFileName); logFile->close(); } bool LogWidget::endsWith(const QString &string) { return textLog->toPlainText().endsWith(string); } diff --git a/src/widgets/movementwidget.cpp b/src/widgets/movementwidget.cpp index 748608f..16456c5 100644 --- a/src/widgets/movementwidget.cpp +++ b/src/widgets/movementwidget.cpp @@ -1,99 +1,85 @@ /* 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) +MovementWidget::MovementWidget(bool showHomeAndDisableWidgets, QWidget *parent) + : QWidget(parent) { auto mainLayout = new QVBoxLayout; auto hBoxLayout = new QHBoxLayout; QPushButton *newButton = nullptr; if (showHomeAndDisableWidgets) { newButton = new QPushButton(tr("Home All"), this); hBoxLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit homeAllPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit homeAllPressed(); }); newButton = new QPushButton(tr("Home X"), this); hBoxLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit homeXPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit homeXPressed(); }); newButton = new QPushButton(tr("Home Y"), this); hBoxLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit homeYPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit homeYPressed(); }); newButton = new QPushButton(tr("Home Z"), this); hBoxLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit homeZPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit homeZPressed(); }); mainLayout->addLayout(hBoxLayout); newButton = new QPushButton(tr("Disable Motors"), this); mainLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit disableMotorsPressed(); - }); - + connect(newButton, &QPushButton::clicked, this, [this] { emit disableMotorsPressed(); }); } comboMoveAxis = new QComboBox(this); comboMoveAxis->addItem(tr("Move X Axis to")); comboMoveAxis->addItem(tr("Move Y Axis to")); comboMoveAxis->addItem(tr("Move Z Axis to")); sbMoveAxis = new QDoubleSpinBox(this); sbMoveAxis->setRange(0, 200); newButton = new QPushButton(tr("Go"), this); connect(newButton, &QPushButton::clicked, this, [this] { - if (comboMoveAxis->currentIndex() == 0) - { + if (comboMoveAxis->currentIndex() == 0) { emit absoluteMove(QLatin1Char('X'), sbMoveAxis->value()); - } else if (comboMoveAxis->currentIndex() == 1) - { + } else if (comboMoveAxis->currentIndex() == 1) { emit absoluteMove(QLatin1Char('Y'), sbMoveAxis->value()); - } else if (comboMoveAxis->currentIndex() == 2) - { + } else if (comboMoveAxis->currentIndex() == 2) { 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(this); mainLayout->addWidget(axisControl); connect(axisControl, &AxisControl::clicked, this, &MovementWidget::relativeMove); connect(axisControl, &AxisControl::unitsChanged, this, &MovementWidget::unitsChanged); setLayout(mainLayout); } diff --git a/src/widgets/plotwidget.cpp b/src/widgets/plotwidget.cpp index b692d81..ed8b9eb 100644 --- a/src/widgets/plotwidget.cpp +++ b/src/widgets/plotwidget.cpp @@ -1,97 +1,96 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2016> Author: Patrick José Pereira - patrickjp@kde.org Tomaz Canabrava Lays Rodrigues Chris Rizzitello 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 "plotwidget.h" #include -PlotWidget::PlotWidget(QWidget *parent) : - QWidget(parent) +PlotWidget::PlotWidget(QWidget *parent) + : QWidget(parent) , _chart(new QChartView(this)) , _axisX(new QDateTimeAxis(this)) , _axisY(new QValueAxis(this)) , m_maximumPoints(120) { - _axisX->setTickCount(3); _axisX->setFormat(QStringLiteral("hh:mm:ss")); _axisY->setLabelFormat(QStringLiteral("%d")); _axisY->setTitleText(tr("Temp.")); _axisY->setRange(0, 3e2); _axisX->setRange(QDateTime::currentDateTime().addSecs(-120), QDateTime::currentDateTime()); _chart->chart()->addAxis(_axisY, Qt::AlignLeft); _chart->chart()->addAxis(_axisX, Qt::AlignBottom); _chart->setRenderHint(QPainter::Antialiasing); if (palette().text().color().value() >= QColor(Qt::lightGray).value()) { _chart->chart()->setTheme(QChart::ChartThemeDark); } auto mainLayout = new QHBoxLayout; mainLayout->addWidget(_chart); setLayout(mainLayout); } void PlotWidget::addPlot(const QString &name) { plot _newPlot; _newPlot.setName(name); _chart->chart()->addSeries(_newPlot.serie()); _newPlot.serie()->attachAxis(_axisY); _newPlot.serie()->attachAxis(_axisX); _plots.insert(name, _newPlot); } void PlotWidget::removePlot(const QString &name) { _chart->chart()->removeSeries(_plots[name].serie()); _plots.remove(name); } void PlotWidget::appendPoint(const QString &name, float value) { if (_plots[name].serie()->count() > m_maximumPoints) { _plots[name].serie()->remove(0); } _plots[name].pushPoint(value); update(); } void PlotWidget::update() { _axisX->setRange(QDateTime::currentDateTime().addSecs(-120), QDateTime::currentDateTime()); } QStringList PlotWidget::plots() { return _plots.keys(); } void PlotWidget::setMaximumPoints(const int newMax) { m_maximumPoints = std::max(newMax, 0); } void PlotWidget::setMaximumTemperature(const uint maxTemp) { _axisY->setRange(0, maxTemp); } diff --git a/src/widgets/plotwidget.h b/src/widgets/plotwidget.h index a92f442..2606128 100644 --- a/src/widgets/plotwidget.h +++ b/src/widgets/plotwidget.h @@ -1,132 +1,133 @@ /* Atelier KDE Printer Host for 3D Printing Copyright (C) <2016> Author: Patrick José Pereira - patrickjp@kde.org Tomaz Canabrava Lays Rodrigues Chris Rizzitello 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 . */ #pragma once #include #include #include #include "atcorewidgets_export.h" /** * @brief PlotWidget Show a graph of the temperature over time. */ class ATCOREWIDGETS_EXPORT PlotWidget : public QWidget { Q_OBJECT public: explicit PlotWidget(QWidget *parent = nullptr); ~PlotWidget() = default; /** * @brief Create a new plot * @param name p_name: plot name */ void addPlot(const QString &name); /** * @brief Delete plot with name * @param name p_name: name */ void removePlot(const QString &name); /** * @brief Append point to plot * @param name p_name: plot name * @param value p_value: value */ void appendPoint(const QString &name, float value); /** * @brief plots * @return List of all named plots */ QStringList plots(); /** * @brief set The Maximum Number of points per series the plot widget stores * @param newMax: new maximum Number (default:120) */ void setMaximumPoints(const int newMax); /** * @brief set the maximum temperature shown on the plot * @param maxTemp : number greater then 0 */ void setMaximumTemperature(const uint maxTemp); private: class plot { public: - explicit plot() : _series(new QLineSeries()) + explicit plot() + : _series(new QLineSeries()) { } ~plot() { // Series will be deleted with chart } void pushPoint(float value) { QDateTime now = QDateTime::currentDateTime(); _series->append(now.toMSecsSinceEpoch(), value); } void setName(const QString &name) { _name = name; _series->setName(_name); - //Add 3 initial points to plot + // Add 3 initial points to plot QDateTime now = QDateTime::currentDateTime(); _series->append(now.toMSecsSinceEpoch() - 2 * 60e3, 0.0); _series->append(now.toMSecsSinceEpoch() - 60e3, 0.0); _series->append(now.toMSecsSinceEpoch(), 0.0); } QLineSeries *serie() const { return _series; } QString name() const { return _name; } private: QLineSeries *_series; QString _name; }; /** * @brief Update plot list, need to run after ALL plots added */ void update(); QChartView *_chart; QDateTimeAxis *_axisX; QValueAxis *_axisY; QMap _plots; int m_maximumPoints; }; diff --git a/src/widgets/printwidget.cpp b/src/widgets/printwidget.cpp index c9807de..c1ff319 100644 --- a/src/widgets/printwidget.cpp +++ b/src/widgets/printwidget.cpp @@ -1,113 +1,105 @@ /* 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) +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"), this); - connect(buttonPrint, &QPushButton::clicked, this, [this] { - emit printPressed(); - }); + connect(buttonPrint, &QPushButton::clicked, this, [this] { emit printPressed(); }); newButton = new QPushButton(tr("Emergency Stop"), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit emergencyStopPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit emergencyStopPressed(); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(buttonPrint); hBoxLayout->addWidget(newButton); mainLayout->addLayout(hBoxLayout); } newLabel = new QLabel(tr("Printer Speed"), this); sbPrintSpeed = new QSpinBox(this); sbPrintSpeed->setRange(1, 300); sbPrintSpeed->setValue(100); sbPrintSpeed->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set"), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit printSpeedChanged(sbPrintSpeed->value()); - }); + connect(newButton, &QPushButton::clicked, this, [this] { 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"), this); sbFlowRate = new QSpinBox(this); sbFlowRate->setRange(1, 300); sbFlowRate->setValue(100); sbFlowRate->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set"), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit flowRateChanged(sbFlowRate->value()); - }); + connect(newButton, &QPushButton::clicked, this, [this] { 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(this); sbFanSpeed = new QSpinBox(this); sbFanSpeed->setRange(0, 100); sbFanSpeed->setSuffix(QStringLiteral("%")); newButton = new QPushButton(tr("Set"), this); connect(newButton, &QPushButton::clicked, this, [this] { - //Fan speed has a range of 0-255. + // Fan speed has a range of 0-255. int speed = sbFanSpeed->value() * 255 / 100; emit fanSpeedChanged(speed, comboFanSelect->currentIndex()); }); hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(comboFanSelect, 60); hBoxLayout->addWidget(sbFanSpeed, 20); hBoxLayout->addWidget(newButton, 20); mainLayout->addLayout(hBoxLayout); setLayout(mainLayout); } void PrintWidget::setPrintText(const QString &text) { buttonPrint->setText(text); } void PrintWidget::updateFanCount(const int count) { comboFanSelect->clear(); for (int i = 0; i < count; i++) { comboFanSelect->insertItem(i, tr("Fan %1 speed").arg(i)); } } diff --git a/src/widgets/profilemanager.cpp b/src/widgets/profilemanager.cpp index 77e59a9..d8cb9eb 100644 --- a/src/widgets/profilemanager.cpp +++ b/src/widgets/profilemanager.cpp @@ -1,327 +1,304 @@ /* AtCore - Widgets Copyright (C) <2019> 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 "profilemanager.h" #include "atcore_default_folders.h" #include "machineinfo.h" #include #include #include #include #include #include #include -ProfileManager::ProfileManager(QWidget *parent) : - QWidget(parent) +ProfileManager::ProfileManager(QWidget *parent) + : QWidget(parent) { auto newLabel = new QLabel(tr("Profile:")); cbProfile = new QComboBox(); cbProfile->setEditable(true); cbProfile->addItems(MachineInfo::instance()->profileNames()); cbProfile->setCompleter(new QCompleter(MachineInfo::instance()->profileNames())); connect(MachineInfo::instance(), &MachineInfo::profilesChanged, this, [this] { int index = cbProfile->currentIndex(); cbProfile->clear(); cbProfile->completer()->deleteLater(); cbProfile->addItems(MachineInfo::instance()->profileNames()); cbProfile->setCompleter(new QCompleter(MachineInfo::instance()->profileNames())); cbProfile->setCurrentIndex(std::min(index, cbProfile->count() - 1)); }); connect(cbProfile, QOverload::of(&QComboBox::currentIndexChanged), this, [this] { - if (MachineInfo::instance()->profileNames().contains(cbProfile->currentText())) - { + if (MachineInfo::instance()->profileNames().contains(cbProfile->currentText())) { loadProfile(cbProfile->currentText()); } }); connect(cbProfile->lineEdit(), &QLineEdit::editingFinished, this, &ProfileManager::onCbProfileEditingFinished); auto newHLayout = new QHBoxLayout(); newHLayout->addWidget(newLabel); newHLayout->addWidget(cbProfile, 75); auto newButton = new QToolButton(); newButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"), style()->standardIcon(QStyle::SP_DialogDiscardButton))); newButton->setToolTip(tr("Delete Current Profile")); newButton->setIconSize(QSize(fontMetrics().height(), fontMetrics().height())); connect(newButton, &QToolButton::clicked, this, [this] { - if (!cbProfile->currentText().isEmpty()) - { + if (!cbProfile->currentText().isEmpty()) { MachineInfo::instance()->removeProfile(cbProfile->currentText()); } }); auto mainLayout = new QVBoxLayout(); newHLayout->addWidget(newButton); mainLayout->addLayout(newHLayout); auto profileLayout = new QVBoxLayout(); auto boxLayout = new QVBoxLayout(); newLabel = new QLabel(tr("Name")); lineName = new QLineEdit(); connect(lineName, &QLineEdit::editingFinished, this, [this] { QString itemName = lineName->text(); - if (MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::NAME, itemName)) - { + if (MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::NAME, itemName)) { loadProfile(itemName); } }); newHLayout = new QHBoxLayout; newHLayout->addWidget(newLabel); newHLayout->addWidget(lineName); profileLayout->addLayout(newHLayout); newLabel = new QLabel(tr("Printer Type:")); radioDelta = new QRadioButton(tr("Delta")); radioCartesian = new QRadioButton(tr("Cartesian")); radioCartesian->setChecked(true); connect(radioCartesian, &QRadioButton::toggled, this, &ProfileManager::onRadioCartesianToggled); newHLayout = new QHBoxLayout; newHLayout->addWidget(newLabel); newHLayout->addWidget(radioCartesian); newHLayout->addWidget(radioDelta); boxLayout->addLayout(newHLayout); lblX = new QLabel(tr("Maximum X")); sbMaxX = new QSpinBox(); sbMaxX->setMaximum(std::numeric_limits::max()); sbMaxX->setSuffix(QStringLiteral("mm")); - connect(sbMaxX, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::XMAX, value); - }); + connect(sbMaxX, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::XMAX, value); }); newHLayout = new QHBoxLayout; newHLayout->addWidget(lblX); newHLayout->addWidget(sbMaxX); boxLayout->addLayout(newHLayout); newLabel = new QLabel(tr("Maximum Y")); sbMaxY = new QSpinBox(); sbMaxY->setMaximum(std::numeric_limits::max()); sbMaxY->setSuffix(QStringLiteral("mm")); - connect(sbMaxY, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::YMAX, value); - }); + connect(sbMaxY, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::YMAX, value); }); newHLayout = new QHBoxLayout; newHLayout->setContentsMargins(0, 0, 0, 0); newHLayout->addWidget(newLabel); newHLayout->addWidget(sbMaxY); axisY = new QWidget(this); axisY->setLayout(newHLayout); boxLayout->addWidget(axisY); lblZ = new QLabel(tr("Maximum Z")); sbMaxZ = new QSpinBox(); sbMaxZ->setMaximum(std::numeric_limits::max()); sbMaxZ->setSuffix(QStringLiteral("mm")); - connect(sbMaxZ, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::ZMAX, value); - }); + connect(sbMaxZ, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::ZMAX, value); }); newHLayout = new QHBoxLayout; newHLayout->addWidget(lblZ); newHLayout->addWidget(sbMaxZ); boxLayout->addLayout(newHLayout); auto groupBox = new QGroupBox(tr("Mechanics")); groupBox->setLayout(boxLayout); profileLayout->addWidget(groupBox); boxLayout = new QVBoxLayout; newLabel = new QLabel(tr("Bed Maximum")); sbMaxBedTemp = new QSpinBox(); sbMaxBedTemp->setMaximum(999); sbMaxBedTemp->setSuffix(QStringLiteral(" ºC")); - connect(sbMaxBedTemp, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::MAXBEDTEMP, value); - }); + connect(sbMaxBedTemp, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::MAXBEDTEMP, value); }); newHLayout = new QHBoxLayout; newHLayout->addWidget(newLabel); newHLayout->addWidget(sbMaxBedTemp); boxLayout->addLayout(newHLayout); sbMaxExtTemp = new QSpinBox(); sbMaxExtTemp->setMaximum(999); newLabel = new QLabel(tr("Extruder Maximum")); sbMaxExtTemp->setSuffix(QStringLiteral(" ºC")); - connect(sbMaxExtTemp, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::MAXEXTTEMP, value); - }); + connect(sbMaxExtTemp, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::MAXEXTTEMP, value); }); newHLayout = new QHBoxLayout(); newHLayout->addWidget(newLabel); newHLayout->addWidget(sbMaxExtTemp); boxLayout->addLayout(newHLayout); checkAutoTempReport = new QCheckBox(tr("Auto Temperature Report")); checkAutoTempReport->setLayoutDirection(Qt::RightToLeft); - connect(checkAutoTempReport, &QCheckBox::toggled, this, [this](bool checked) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::AUTOTEMPREPORT, checked); - }); + connect(checkAutoTempReport, &QCheckBox::toggled, this, [this](bool checked) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::AUTOTEMPREPORT, checked); }); boxLayout->addWidget(checkAutoTempReport, 0, Qt::AlignRight); groupBox = new QGroupBox(tr("Temperature")); groupBox->setLayout(boxLayout); profileLayout->addWidget(groupBox); boxLayout = new QVBoxLayout(); cbBaud = new QComboBox(); cbBaud->addItems(SERIAL::BAUDS); cbBaud->setCurrentText(QStringLiteral("115200")); - connect(cbBaud, &QComboBox::currentTextChanged, this, [this](const QString & newText) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::BAUDRATE, newText); - }); + connect(cbBaud, &QComboBox::currentTextChanged, this, [this](const QString &newText) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::BAUDRATE, newText); }); newLabel = new QLabel(tr("Bit Rate")); newHLayout = new QHBoxLayout(); newHLayout->addWidget(newLabel); newHLayout->addWidget(cbBaud); boxLayout->addLayout(newHLayout); newLabel = new QLabel(tr("Firmware")); cbFirmware = new QComboBox(); cbFirmware->addItem(QStringLiteral("Auto-Detect")); cbFirmware->addItems(detectFWPlugins()); - connect(cbFirmware, &QComboBox::currentTextChanged, this, [this](const QString & newText) { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::FIRMWARE, newText); - }); + connect(cbFirmware, &QComboBox::currentTextChanged, this, [this](const QString &newText) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::FIRMWARE, newText); }); newHLayout = new QHBoxLayout(); newHLayout->addWidget(newLabel); newHLayout->addWidget(cbFirmware); boxLayout->addLayout(newHLayout); linePostPause = new QLineEdit(); - connect(linePostPause, &QLineEdit::editingFinished, this, [this] { - MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::POSTPAUSE, linePostPause->text()); - }); + connect(linePostPause, &QLineEdit::editingFinished, this, [this] { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::POSTPAUSE, linePostPause->text()); }); newLabel = new QLabel(tr("PostPause")); newHLayout = new QHBoxLayout(); newHLayout->addWidget(newLabel); newHLayout->addWidget(linePostPause); boxLayout->addLayout(newHLayout); groupBox = new QGroupBox(tr("Advanced")); groupBox->setLayout(boxLayout); profileLayout->addWidget(groupBox); groupBox = new QGroupBox(tr("Profile")); groupBox->setLayout(profileLayout); mainLayout->addWidget(groupBox); setLayout(mainLayout); loadProfile(cbProfile->currentText()); } void ProfileManager::onCbProfileEditingFinished() { if (MachineInfo::instance()->profileNames().contains(cbProfile->currentText())) { loadProfile(cbProfile->currentText()); return; } - QMap newProfile = { - {MachineInfo::KEY::NAME, cbProfile->currentText()}, - {MachineInfo::KEY::FIRMWARE, cbFirmware->currentText()}, - {MachineInfo::KEY::BAUDRATE, cbBaud->currentText()}, - {MachineInfo::KEY::POSTPAUSE, linePostPause->text()}, - {MachineInfo::KEY::ISCARTESIAN, radioCartesian->isChecked()}, - {MachineInfo::KEY::XMAX, sbMaxX->value()}, - {MachineInfo::KEY::YMAX, sbMaxY->value()}, - {MachineInfo::KEY::ZMAX, sbMaxZ->value()}, - {MachineInfo::KEY::AUTOTEMPREPORT, checkAutoTempReport->isChecked()}, - {MachineInfo::KEY::MAXBEDTEMP, sbMaxBedTemp->value()}, - {MachineInfo::KEY::MAXEXTTEMP, sbMaxExtTemp->value()} - }; + QMap newProfile = {{MachineInfo::KEY::NAME, cbProfile->currentText()}, + {MachineInfo::KEY::FIRMWARE, cbFirmware->currentText()}, + {MachineInfo::KEY::BAUDRATE, cbBaud->currentText()}, + {MachineInfo::KEY::POSTPAUSE, linePostPause->text()}, + {MachineInfo::KEY::ISCARTESIAN, radioCartesian->isChecked()}, + {MachineInfo::KEY::XMAX, sbMaxX->value()}, + {MachineInfo::KEY::YMAX, sbMaxY->value()}, + {MachineInfo::KEY::ZMAX, sbMaxZ->value()}, + {MachineInfo::KEY::AUTOTEMPREPORT, checkAutoTempReport->isChecked()}, + {MachineInfo::KEY::MAXBEDTEMP, sbMaxBedTemp->value()}, + {MachineInfo::KEY::MAXEXTTEMP, sbMaxExtTemp->value()}}; MachineInfo::instance()->storeProfile(newProfile); loadProfile(newProfile[MachineInfo::KEY::NAME].toString()); } void ProfileManager::onRadioCartesianToggled(bool checked) { axisY->setVisible(checked); if (checked) { lblX->setText(tr("Maximum X")); lblZ->setText(tr("Maximum Z")); } else { lblX->setText(tr("Radius")); lblZ->setText(tr("Height")); } if (MachineInfo::instance()->profileNames().contains(cbProfile->currentText())) { MachineInfo::instance()->storeKey(cbProfile->currentText(), MachineInfo::KEY::ISCARTESIAN, checked); } } void ProfileManager::loadProfile(const QString &profileName) { if (profileName.isEmpty()) { return; } blockSignals(true); lineName->setText(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::NAME).toString()); radioCartesian->setChecked(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::ISCARTESIAN).toBool()); radioDelta->setChecked(!MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::ISCARTESIAN).toBool()); sbMaxX->setValue(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::XMAX).toInt()); sbMaxY->setValue(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::YMAX).toInt()); sbMaxZ->setValue(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::ZMAX).toInt()); checkAutoTempReport->setChecked(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::AUTOTEMPREPORT).toBool()); sbMaxBedTemp->setValue(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::MAXBEDTEMP).toInt()); sbMaxExtTemp->setValue(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::MAXEXTTEMP).toInt()); cbFirmware->setCurrentText(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::FIRMWARE).toString()); cbBaud->setCurrentText(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::BAUDRATE).toString()); linePostPause->setText(MachineInfo::instance()->readKey(profileName, MachineInfo::KEY::POSTPAUSE).toString()); cbProfile->setCurrentText(profileName); cbProfile->setCurrentIndex(MachineInfo::instance()->profileNames().indexOf(profileName)); blockSignals(false); } QStringList ProfileManager::detectFWPlugins() { QStringList firmwares; QStringList paths = AtCoreDirectories::pluginDir; - //Add our runtime paths + // Add our runtime paths const QString &p(qApp->applicationDirPath()); paths.prepend(p + QStringLiteral("/../Plugins/AtCore")); paths.prepend(p + QStringLiteral("/AtCore")); paths.prepend(p + QStringLiteral("/plugins")); for (const QString &path : qAsConst(paths)) { firmwares = firmwaresInPath(path); if (!firmwares.isEmpty()) { - //use path where plugins were detected. + // use path where plugins were detected. break; } } return firmwares; } QStringList ProfileManager::firmwaresInPath(const QString &path) { QStringList firmwares; for (QString file : QDir(path).entryList({AtCoreDirectories::pluginExtFilter}, QDir::Files)) { file = file.split(QStringLiteral(".")).at(0).toLower().simplified(); if (file.startsWith(QStringLiteral("lib"))) { file = file.remove(QStringLiteral("lib")); } firmwares.append(file); } return firmwares; } diff --git a/src/widgets/profilemanager.h b/src/widgets/profilemanager.h index 52a4c0f..a7bfd14 100644 --- a/src/widgets/profilemanager.h +++ b/src/widgets/profilemanager.h @@ -1,75 +1,73 @@ /* AtCore - Widgets Copyright (C) <2019> 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 . */ #pragma once +#include "atcorewidgets_export.h" #include #include #include #include #include #include -#include "atcorewidgets_export.h" class ATCOREWIDGETS_EXPORT ProfileManager : public QWidget { Q_OBJECT public: ProfileManager(QWidget *parent = nullptr); private: void onCbProfileEditingFinished(); void onRadioCartesianToggled(bool checked); - QStringList detectFWPlugins() ; + QStringList detectFWPlugins(); QStringList firmwaresInPath(const QString &path); void loadProfile(const QString &profileName); QCheckBox *checkAutoTempReport = nullptr; QComboBox *cbBaud = nullptr; QComboBox *cbFirmware = nullptr; QComboBox *cbProfile = nullptr; QRadioButton *radioCartesian = nullptr; QRadioButton *radioDelta = nullptr; QLabel *lblX = nullptr; QLabel *lblZ = nullptr; QLineEdit *lineName = nullptr; QLineEdit *linePostPause = nullptr; QSpinBox *sbMaxBedTemp = nullptr; QSpinBox *sbMaxExtTemp = nullptr; QSpinBox *sbMaxX = nullptr; QSpinBox *sbMaxY = nullptr; QSpinBox *sbMaxZ = nullptr; QWidget *axisY = nullptr; }; namespace SERIAL { -static const QStringList BAUDS = { - QStringLiteral("9600"), - QStringLiteral("14400"), - QStringLiteral("19200"), - QStringLiteral("28800"), - QStringLiteral("38400"), - QStringLiteral("57600"), - QStringLiteral("76800"), - QStringLiteral("115200"), - QStringLiteral("230400"), - QStringLiteral("250000"), - QStringLiteral("500000"), - QStringLiteral("1000000") -}; +static const QStringList BAUDS = {QStringLiteral("9600"), + QStringLiteral("14400"), + QStringLiteral("19200"), + QStringLiteral("28800"), + QStringLiteral("38400"), + QStringLiteral("57600"), + QStringLiteral("76800"), + QStringLiteral("115200"), + QStringLiteral("230400"), + QStringLiteral("250000"), + QStringLiteral("500000"), + QStringLiteral("1000000")}; } diff --git a/src/widgets/sdwidget.cpp b/src/widgets/sdwidget.cpp index a0d1efa..ef70887 100644 --- a/src/widgets/sdwidget.cpp +++ b/src/widgets/sdwidget.cpp @@ -1,72 +1,68 @@ /* 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) +SdWidget::SdWidget(QWidget *parent) + : QWidget(parent) { auto hBoxLayout = new QHBoxLayout; auto newButton = new QPushButton(tr("Get List"), this); hBoxLayout->addWidget(newButton); - connect(newButton, &QPushButton::clicked, this, [this] { - emit requestSdList(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit requestSdList(); }); newButton = new QPushButton(tr("Print Selected"), this); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - if (listSdFiles->currentRow() != -1) - { + if (listSdFiles->currentRow() != -1) { emit printSdFile(listSdFiles->currentItem()->text()); } }); newButton = new QPushButton(tr("Delete Selected"), this); hBoxLayout->addWidget(newButton); connect(newButton, &QPushButton::clicked, this, [this] { - if (listSdFiles->currentRow() != -1) - { + if (listSdFiles->currentRow() != -1) { emit deleteSdFile(listSdFiles->currentItem()->text()); listSdFiles->setCurrentRow(-1); } }); - auto groupFiles = new QGroupBox(tr("Files On Sd Card"), this); + auto groupFiles = new QGroupBox(tr("Files On Sd Card"), this); listSdFiles = new QListWidget(this); 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 acd77e4..c472865 100644 --- a/src/widgets/statuswidget.cpp +++ b/src/widgets/statuswidget.cpp @@ -1,120 +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) +StatusWidget::StatusWidget(bool showStop, QWidget *parent) + : QWidget(parent) { - //first create the item for the print Progress. + // first create the item for the print Progress. auto hBoxLayout = new QHBoxLayout; printingProgress = new QProgressBar(this); printingProgress->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); hBoxLayout->addWidget(printingProgress); if (showStop) { auto newButton = new QPushButton(style()->standardIcon(QStyle::SP_BrowserStop), QString(), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit stopPressed(); - }); + connect(newButton, &QPushButton::clicked, this, [this] { emit stopPressed(); }); hBoxLayout->addWidget(newButton); } lblTime = new QLabel(QStringLiteral("00:00:00"), this); lblTime->setAlignment(Qt::AlignHCenter); auto newLabel = new QLabel(QStringLiteral(" / "), this); lblTimeLeft = new QLabel(QStringLiteral("??:??:??"), this); lblTimeLeft->setAlignment(Qt::AlignHCenter); hBoxLayout->addWidget(lblTime); hBoxLayout->addWidget(newLabel); hBoxLayout->addWidget(lblTimeLeft); printProgressWidget = new QWidget(this); printProgressWidget->setLayout(hBoxLayout); - //Then Create the full bar. + // Then Create the full bar. newLabel = new QLabel(tr("AtCore State:"), this); lblState = new QLabel(tr("Not Connected"), this); lblSd = new QLabel(this); 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(this); 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 { if (printTimer->isActive()) { 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 int 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 03eb9b8..4ceec9a 100644 --- a/src/widgets/temperaturewidget.cpp +++ b/src/widgets/temperaturewidget.cpp @@ -1,73 +1,69 @@ /* 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) +TemperatureWidget::TemperatureWidget(QWidget *parent) + : QWidget(parent) { auto *mainLayout = new QVBoxLayout; checkAndWait = new QCheckBox(tr("Wait Until Temperature Stabilizes"), this); mainLayout->addWidget(checkAndWait); auto label = new QLabel(tr("Bed Temp"), this); sbBedTemp = new QSpinBox(this); sbBedTemp->setRange(0, 120); sbBedTemp->setSuffix(QStringLiteral("°C")); auto *newButton = new QPushButton(tr("Set"), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit bedTempChanged(sbBedTemp->value(), checkAndWait->isChecked()); - }); + connect(newButton, &QPushButton::clicked, this, [this] { 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(this); sbExtruderTemp = new QSpinBox(this); sbExtruderTemp->setRange(0, 275); sbExtruderTemp->setSuffix(QStringLiteral("°C")); newButton = new QPushButton(tr("Set"), this); - connect(newButton, &QPushButton::clicked, this, [this] { - emit extTempChanged(sbExtruderTemp->value(), comboExtruderSelect->currentIndex(), checkAndWait->isChecked()); - }); + connect(newButton, &QPushButton::clicked, this, [this] { 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) { comboExtruderSelect->clear(); for (int i = 0; i < count; i++) { comboExtruderSelect->insertItem(i, tr("Extruder %1").arg(i)); } } diff --git a/src/widgets/temperaturewidget.h b/src/widgets/temperaturewidget.h index 9c4c826..63daa6d 100644 --- a/src/widgets/temperaturewidget.h +++ b/src/widgets/temperaturewidget.h @@ -1,68 +1,67 @@ /* 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 . */ #pragma once #include #include #include #include #include "atcorewidgets_export.h" /** * @brief The TemperatureWidget Control the bed and extruder(s) temperatures */ class ATCOREWIDGETS_EXPORT TemperatureWidget : public QWidget { Q_OBJECT public: - /** * @brief TemperatureWidget * @param parent */ TemperatureWidget(QWidget *parent = nullptr); ~TemperatureWidget() = default; /** * @brief Update widget with count extruder controls * @param count: number of extruder controls needed. */ void updateExtruderCount(const int count); signals: /** * @brief User has changed the bed temperature. * @param temperature: new temperature * @param andWait: true if heat and wait mode */ void bedTempChanged(const int temperature, bool andWait); /** * @brief User has changed the extruder temperature. * @param temperature: new temperature * @param extNum: the extruder to change temperature of * @param andWait: true if head and wait mode. */ void extTempChanged(const int temperature, const int extNum, bool andWait); private: QCheckBox *checkAndWait = nullptr; QComboBox *comboExtruderSelect; QSpinBox *sbBedTemp = nullptr; QSpinBox *sbExtruderTemp; }; diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp index 78ce636..f5d107a 100644 --- a/testclient/mainwindow.cpp +++ b/testclient/mainwindow.cpp @@ -1,716 +1,699 @@ /* AtCore Test Client Copyright (C) <2016 - 2019> Authors: Patrick José Pereira Lays Rodrigues Chris Rizzitello Tomaz Canabrava 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 -#include "mainwindow.h" +#include "about.h" +#include "gcodecommands.h" #include "machineinfo.h" +#include "mainwindow.h" #include "seriallayer.h" -#include "gcodecommands.h" -#include "about.h" Q_LOGGING_CATEGORY(TESTCLIENT_MAINWINDOW, "org.kde.atelier.core") int MainWindow::fanCount = 4; -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - core(new AtCore(this)) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , core(new AtCore(this)) { setWindowTitle(tr("AtCore - Test Client")); setWindowIcon(QIcon(QStringLiteral(":/icon/windowIcon"))); QCoreApplication::setApplicationVersion(core->version()); initMenu(); initStatusBar(); initWidgets(); connect(core, &AtCore::atcoreMessage, logWidget, &LogWidget::appendLog); logWidget->appendLog(tr("Attempting to locate Serial Ports")); core->setSerialTimerInterval(1000); connect(core, &AtCore::stateChanged, this, &MainWindow::printerStateChanged); connect(core, &AtCore::portsChanged, this, &MainWindow::locateSerialPort); connect(core, &AtCore::sdCardFileListChanged, sdWidget, &SdWidget::updateFilelist); connect(core, &AtCore::autoTemperatureReportChanged, this, &MainWindow::updateAutoTemperatureReport); comboPort->setFocus(Qt::OtherFocusReason); if (comboProfile->count() == 0) { QMessageBox::information(this, tr("AtCore First Run"), tr("No Profiles Detected, use the Profile Manager to create one.")); profileDock->setVisible(true); move(profileDock->geometry().center()); profileDock->move(geometry().center()); profileDock->activateWindow(); } } void MainWindow::initMenu() { QMenu *menuFile = new QMenu(tr("File")); QAction *actionQuit = new QAction(style()->standardIcon(QStyle::SP_DialogCloseButton), tr("Quit")); connect(actionQuit, &QAction::triggered, this, &MainWindow::close); menuFile->addAction(actionQuit); menuView = new QMenu(tr("View")); QAction *actionShowDockTitles = new QAction(tr("Show Dock Titles")); actionShowDockTitles->setCheckable(true); actionShowDockTitles->setChecked(true); connect(actionShowDockTitles, &QAction::toggled, this, &MainWindow::toggleDockTitles); menuView->addAction(actionShowDockTitles); QMenu *menuHelp = new QMenu(tr("Help")); QAction *actionAbout = new QAction(tr("About")); actionAbout->setShortcut(QKeySequence(Qt::Key_F1)); connect(actionAbout, &QAction::triggered, this, [] { auto *dialog = new About; dialog->exec(); }); menuHelp->addAction(actionAbout); menuBar()->addMenu(menuFile); menuBar()->addMenu(menuView); menuBar()->addMenu(menuHelp); } void MainWindow::initStatusBar() { statusWidget = new StatusWidget; connect(statusWidget, &StatusWidget::stopPressed, core, &AtCore::stop); connect(core, &AtCore::printProgressChanged, statusWidget, &StatusWidget::updatePrintProgress); connect(core, &AtCore::sdMountChanged, statusWidget, &StatusWidget::setSD); statusBar()->addPermanentWidget(statusWidget, 100); } void MainWindow::initWidgets() { - //Make the Docks + // Make the Docks makeCommandDock(); makePrintDock(); makeTempTimelineDock(); makeLogDock(); makeConnectDock(); makeMoveDock(); makeTempControlsDock(); makeSdDock(); makeProfileDock(); setDangeriousDocksDisabled(true); setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North); setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North); tabifyDockWidget(moveDock, tempControlsDock); tabifyDockWidget(moveDock, sdDock); moveDock->raise(); tabifyDockWidget(connectDock, printDock); tabifyDockWidget(connectDock, commandDock); connectDock->raise(); tabifyDockWidget(logDock, profileDock); logDock->raise(); setCentralWidget(nullptr); - //More Gui stuff - //hide the printing progress bar. + // More Gui stuff + // hide the printing progress bar. statusWidget->showPrintArea(false); } void MainWindow::makeCommandDock() { commandWidget = new CommandWidget; - //Connect the commandPressed signal - connect(commandWidget, &CommandWidget::commandPressed, [this](const QString & command) { - core->pushCommand(command); - }); - //Connect the messagePressed signal - connect(commandWidget, &CommandWidget::messagePressed, [this](const QString & message) { - core->showMessage(message); - }); - //Create the dock, and set the Widget. + // Connect the commandPressed signal + connect(commandWidget, &CommandWidget::commandPressed, [this](const QString &command) { core->pushCommand(command); }); + // Connect the messagePressed signal + connect(commandWidget, &CommandWidget::messagePressed, [this](const QString &message) { core->showMessage(message); }); + // Create the dock, and set the Widget. commandDock = new QDockWidget(tr("Commands"), this); commandDock->setWidget(commandWidget); - //Push the toggle view action into our view menu + // Push the toggle view action into our view menu menuView->insertAction(nullptr, commandDock->toggleViewAction()); - //Place the Dock into a DockWidget Area. - //Failure todo this will create some odd side effects at runtime + // Place the Dock into a DockWidget Area. + // Failure todo this will create some odd side effects at runtime addDockWidget(Qt::LeftDockWidgetArea, commandDock); } void MainWindow::makePrintDock() { printWidget = new PrintWidget; connect(printWidget, &PrintWidget::printPressed, this, &MainWindow::printPBClicked); connect(printWidget, &PrintWidget::emergencyStopPressed, core, &AtCore::emergencyStop); connect(printWidget, &PrintWidget::fanSpeedChanged, core, &AtCore::setFanSpeed); - connect(printWidget, &PrintWidget::printSpeedChanged, this, [this](const int speed) { - core->setPrinterSpeed(uint(std::max(1, speed))); - }); + connect(printWidget, &PrintWidget::printSpeedChanged, this, [this](const int speed) { core->setPrinterSpeed(uint(std::max(1, speed))); }); - connect(printWidget, &PrintWidget::flowRateChanged, [this](const int rate) { - core->setFlowRate(uint(std::max(1, rate))); - }); + connect(printWidget, &PrintWidget::flowRateChanged, [this](const int rate) { core->setFlowRate(uint(std::max(1, rate))); }); printDock = new QDockWidget(tr("Print"), this); printDock->setWidget(printWidget); menuView->insertAction(nullptr, printDock->toggleViewAction()); addDockWidget(Qt::LeftDockWidgetArea, printDock); } void MainWindow::makeTempTimelineDock() { plotWidget = new PlotWidget; - //make and connect our plots in the widget. + // make and connect our plots in the widget. plotWidget->addPlot(tr("Actual Bed")); connect(core->temperature(), &Temperature::bedTemperatureChanged, this, [this] { float temp = core->temperature()->bedTemperature(); checkTemperature(0x00, 0, temp); plotWidget->appendPoint(tr("Actual Bed"), temp); }); plotWidget->addPlot(tr("Target Bed")); connect(core->temperature(), &Temperature::bedTargetTemperatureChanged, this, [this] { float temp = core->temperature()->bedTargetTemperature(); checkTemperature(0x01, 0, temp); plotWidget->appendPoint(tr("Target Bed"), temp); }); plotWidget->addPlot(tr("Actual Ext.1")); connect(core->temperature(), &Temperature::extruderTemperatureChanged, this, [this] { float temp = core->temperature()->extruderTemperature(); checkTemperature(0x02, 0, temp); plotWidget->appendPoint(tr("Actual Ext.1"), temp); }); plotWidget->addPlot(tr("Target Ext.1")); connect(core->temperature(), &Temperature::extruderTargetTemperatureChanged, this, [this] { float temp = core->temperature()->extruderTargetTemperature(); checkTemperature(0x03, 0, temp); plotWidget->appendPoint(tr("Target Ext.1"), temp); }); auto timerLayout = new QHBoxLayout; auto lblTimer = new QLabel(tr("Seconds Between Temperature Checks"), this); sbTemperatureTimer = new QSpinBox(this); sbTemperatureTimer->setRange(0, 90); - connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - core->setTemperatureTimerInterval(value * 1000); - }); + connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { core->setTemperatureTimerInterval(value * 1000); }); connect(core, &AtCore::temperatureTimerIntervalChanged, this, [this](int value) { if (value != sbTemperatureTimer->value()) { sbTemperatureTimer->blockSignals(true); sbTemperatureTimer->setValue(value / 1000); sbTemperatureTimer->blockSignals(false); } }); timerLayout->addWidget(lblTimer); timerLayout->addWidget(sbTemperatureTimer); auto tempDockLayout = new QVBoxLayout; tempDockLayout->addWidget(plotWidget); tempDockLayout->addLayout(timerLayout); auto tempDockMainWidget = new QWidget(this); tempDockMainWidget->setLayout(tempDockLayout); tempTimelineDock = new QDockWidget(tr("Temperature Timeline"), this); tempTimelineDock->setWidget(tempDockMainWidget); menuView->insertAction(nullptr, tempTimelineDock->toggleViewAction()); addDockWidget(Qt::RightDockWidgetArea, tempTimelineDock); } void MainWindow::makeLogDock() { logWidget = new LogWidget(new QTemporaryFile(QDir::tempPath() + QStringLiteral("/AtCore_"))); logDock = new QDockWidget(tr("Session Log"), this); logDock->setWidget(logWidget); menuView->insertAction(nullptr, logDock->toggleViewAction()); addDockWidget(Qt::RightDockWidgetArea, logDock); } void MainWindow::makeConnectDock() { auto *mainLayout = new QVBoxLayout; auto *newLabel = new QLabel(tr("Port:")); comboPort = new QComboBox; comboPort->setEditable(true); auto *hBoxLayout = new QHBoxLayout; hBoxLayout->addWidget(newLabel); hBoxLayout->addWidget(comboPort, 75); mainLayout->addLayout(hBoxLayout); comboProfile = new QComboBox(); comboProfile->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); comboProfile->addItems(MachineInfo::instance()->profileNames()); connect(MachineInfo::instance(), &MachineInfo::profilesChanged, this, [this] { int index = comboProfile->currentIndex(); comboProfile->clear(); comboProfile->addItems(MachineInfo::instance()->profileNames()); comboProfile->setCurrentIndex(std::min(index, comboProfile->count() - 1)); }); newLabel = new QLabel(tr("Profile:")); auto profileLayout = new QHBoxLayout(); profileLayout->addWidget(newLabel); profileLayout->addWidget(comboProfile); mainLayout->addLayout(profileLayout); cbReset = new QCheckBox(tr("Attempt to stop Reset on connect")); if (MachineInfo::instance()->profileNames().isEmpty()) { cbReset->setHidden(true); } else { - cbReset->setHidden(MachineInfo::instance()->readKey( - comboProfile->currentText(), MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); + cbReset->setHidden(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); } mainLayout->addWidget(cbReset); - connect(comboProfile, &QComboBox::currentTextChanged, this, [this](const QString & currentText) { - cbReset->setHidden(MachineInfo::instance()->readKey( - currentText, MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); + connect(comboProfile, &QComboBox::currentTextChanged, this, [this](const QString ¤tText) { + cbReset->setHidden(MachineInfo::instance()->readKey(currentText, MachineInfo::KEY::FIRMWARE).toString().contains(QStringLiteral("Auto-Detect"))); }); buttonConnect = new QPushButton(tr("Connect")); connect(buttonConnect, &QPushButton::clicked, this, &MainWindow::connectPBClicked); connectionTimer = new QTimer(this); connectionTimer->setInterval(20000); connectionTimer->setSingleShot(true); connect(connectionTimer, &QTimer::timeout, this, [this] { buttonConnect->clicked(); 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.")); }); mainLayout->addWidget(buttonConnect); auto *dockContents = new QWidget; dockContents->setLayout(mainLayout); connectDock = new QDockWidget(tr("Connect"), this); connectDock->setWidget(dockContents); menuView->insertAction(nullptr, connectDock->toggleViewAction()); addDockWidget(Qt::LeftDockWidgetArea, connectDock); } void MainWindow::makeMoveDock() { movementWidget = new MovementWidget(true, this); connect(movementWidget, &MovementWidget::homeAllPressed, this, [this] { logWidget->appendLog(tr("Home All")); core->home(); }); connect(movementWidget, &MovementWidget::homeXPressed, this, [this] { logWidget->appendLog(tr("Home X")); core->home(AtCore::X); }); connect(movementWidget, &MovementWidget::homeYPressed, this, [this] { logWidget->appendLog(tr("Home Y")); core->home(AtCore::Y); }); connect(movementWidget, &MovementWidget::homeZPressed, this, [this] { logWidget->appendLog(tr("Home Z")); core->home(AtCore::Z); }); - connect(movementWidget, &MovementWidget::absoluteMove, this, [this](const QLatin1Char & axis, const double & value) { + connect(movementWidget, &MovementWidget::absoluteMove, this, [this](const QLatin1Char &axis, const double &value) { logWidget->appendLog(GCode::description(GCode::G1)); core->move(axis, value); }); - connect(movementWidget, &MovementWidget::disableMotorsPressed, this, [this] { - core->disableMotors(0); - }); + connect(movementWidget, &MovementWidget::disableMotorsPressed, this, [this] { core->disableMotors(0); }); - connect(movementWidget, &MovementWidget::relativeMove, this, [this](const QLatin1Char & axis, const double & value) { + connect(movementWidget, &MovementWidget::relativeMove, this, [this](const QLatin1Char &axis, const double &value) { core->setRelativePosition(); core->move(axis, value); core->setAbsolutePosition(); }); connect(movementWidget, &MovementWidget::unitsChanged, this, [this](int units) { auto selection = static_cast(units); core->setUnits(selection); }); moveDock = new QDockWidget(tr("Movement"), this); moveDock->setWidget(movementWidget); menuView->insertAction(nullptr, moveDock->toggleViewAction()); addDockWidget(Qt::LeftDockWidgetArea, moveDock); } void MainWindow::makeTempControlsDock() { temperatureWidget = new TemperatureWidget; connect(temperatureWidget, &TemperatureWidget::bedTempChanged, core, &AtCore::setBedTemp); connect(temperatureWidget, &TemperatureWidget::extTempChanged, core, &AtCore::setExtruderTemp); tempControlsDock = new QDockWidget(tr("Temperatures"), this); tempControlsDock->setWidget(temperatureWidget); menuView->insertAction(nullptr, tempControlsDock->toggleViewAction()); addDockWidget(Qt::LeftDockWidgetArea, tempControlsDock); } void MainWindow::makeSdDock() { - sdWidget = new SdWidget; connect(sdWidget, &SdWidget::requestSdList, core, &AtCore::sdFileList); - connect(sdWidget, &SdWidget::printSdFile, this, [this](const QString & fileName) { + connect(sdWidget, &SdWidget::printSdFile, this, [this](const QString &fileName) { if (fileName.isEmpty()) { QMessageBox::information(this, tr("Print Error"), tr("You must Select a file from the list")); - } else { + } else { core->print(fileName, true); } }); - connect(sdWidget, &SdWidget::deleteSdFile, this, [this](const QString & fileName) { + connect(sdWidget, &SdWidget::deleteSdFile, this, [this](const QString &fileName) { if (fileName.isEmpty()) { QMessageBox::information(this, tr("Delete Error"), tr("You must Select a file from the list")); - } else { + } else { core->sdDelete(fileName); } }); sdDock = new QDockWidget(tr("Sd Card"), this); sdDock->setWidget(sdWidget); menuView->insertAction(nullptr, sdDock->toggleViewAction()); addDockWidget(Qt::LeftDockWidgetArea, sdDock); } void MainWindow::makeProfileDock() { profileManager = new ProfileManager(); profileDock = new QDockWidget(tr("Profile Manager"), this); profileDock->setWidget(profileManager); menuView->insertAction(nullptr, profileDock->toggleViewAction()); addDockWidget(Qt::RightDockWidgetArea, profileDock); profileDock->setFloating(true); profileDock->setVisible(false); } void MainWindow::closeEvent(QCloseEvent *event) { core->close(); event->accept(); } void MainWindow::checkTemperature(uint sensorType, uint number, float temp) { QString msg; switch (sensorType) { case 0x00: // bed msg = QString::fromLatin1("Bed Temperature"); break; case 0x01: // bed target msg = QString::fromLatin1("Bed Target Temperature"); break; case 0x02: // extruder msg = QString::fromLatin1("Extruder[%1] Temperature").arg(QString::number(number)); break; case 0x03: // extruder target msg = QString::fromLatin1("Extruder[%1] Target Temperature").arg(QString::number(number)); break; case 0x04: // enclosure msg = QString::fromLatin1("Enclosure Temperature"); break; case 0x05: // enclosure target msg = QString::fromLatin1("Enclosure Target Temperature"); break; } msg.append(QString::fromLatin1(": %1").arg(QString::number(double(temp), 'f', 2))); logWidget->appendLog(msg); } /** * @brief MainWindow::locateSerialPort * Locate all active serial ports on the computer and add to the list * of serial ports */ void MainWindow::locateSerialPort(const QStringList &ports) { comboPort->clear(); if (!ports.isEmpty()) { comboPort->addItems(ports); logWidget->appendLog(tr("Found %1 Ports").arg(QString::number(ports.count()))); } else { QString portError(tr("No available ports! Please connect a serial device to continue!")); - if (! logWidget->endsWith(portError)) { + if (!logWidget->endsWith(portError)) { logWidget->appendLog(portError); } } } void MainWindow::connectPBClicked() { if (core->state() == AtCore::DISCONNECTED) { int baud = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::BAUDRATE).toInt(); QString plugin = MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::FIRMWARE).toString(); if (core->newConnection(comboPort->currentText(), baud, plugin, cbReset->isChecked())) { connect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); connect(core, &AtCore::pushedCommand, logWidget, &LogWidget::appendSLog); logWidget->appendLog(tr("Serial connected")); if ((!plugin.contains(QStringLiteral("Auto-Detect"))) && cbReset->isChecked()) { - //Wait a few seconds after connect to avoid the normal errors + // Wait a few seconds after connect to avoid the normal errors QTimer::singleShot(5000, core, &AtCore::sdCardPrintStatus); } } } else { disconnect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); disconnect(core, &AtCore::pushedCommand, logWidget, &LogWidget::appendSLog); core->closeConnection(); core->setState(AtCore::DISCONNECTED); logWidget->appendLog(tr("Disconnected")); } } void MainWindow::printPBClicked() { QString fileName; switch (core->state()) { - case AtCore::DISCONNECTED: QMessageBox::information(this, tr("Error"), tr("Not Connected To a Printer")); break; case AtCore::CONNECTING: - QMessageBox::information(this, tr("Error"), 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.")); + QMessageBox::information( + this, + tr("Error"), + 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.")); break; case AtCore::IDLE: fileName = QFileDialog::getOpenFileName(this, tr("Select a file to print"), QDir::homePath(), tr("*.gcode")); if (fileName.isNull()) { logWidget->appendLog(tr("No File Selected")); } else { logWidget->appendLog(tr("Print: %1").arg(fileName)); core->print(fileName); } break; case AtCore::BUSY: core->pause(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::POSTPAUSE).toString()); break; case AtCore::PAUSE: core->resume(); break; default: qCDebug(TESTCLIENT_MAINWINDOW) << "ERROR / STOP unhandled."; } } void MainWindow::printerStateChanged(AtCore::STATES state) { QString stateString; switch (state) { case AtCore::IDLE: if (connectionTimer->isActive()) { core->setAutoTemperatureReport(MachineInfo::instance()->readKey(comboProfile->currentText(), MachineInfo::KEY::AUTOTEMPREPORT).toBool()); connectionTimer->stop(); } buttonConnect->setText(tr("Disconnect")); printWidget->setPrintText(tr("Print File")); stateString = tr("Connected to ") + core->connectedPort(); sdDock->setVisible(core->firmwarePlugin()->isSdSupported()); break; case AtCore::STARTPRINT: stateString = tr("START PRINT"); printWidget->setPrintText(tr("Pause Print")); statusWidget->showPrintArea(true); break; case AtCore::FINISHEDPRINT: stateString = tr("Finished Print"); printWidget->setPrintText(tr("Print File")); statusWidget->showPrintArea(false); break; case AtCore::PAUSE: stateString = tr("Paused"); printWidget->setPrintText(tr("Resume Print")); break; case AtCore::BUSY: stateString = tr("Printing"); printWidget->setPrintText(tr("Pause Print")); break; case AtCore::DISCONNECTED: if (connectionTimer->isActive()) { connectionTimer->stop(); } sbTemperatureTimer->setValue(0); stateString = QStringLiteral("Not Connected"); buttonConnect->setText(tr("Connect")); setConnectionWidgetsEnabled(true); setDangeriousDocksDisabled(true); break; case AtCore::CONNECTING: stateString = QStringLiteral("Connecting"); buttonConnect->setText(tr("Abort")); connectionTimer->start(); setConnectionWidgetsEnabled(false); setDangeriousDocksDisabled(false); break; case AtCore::STOP: stateString = tr("Stopping Print"); break; case AtCore::ERRORSTATE: stateString = tr("Command ERROR"); break; } statusWidget->setState(stateString); } void MainWindow::toggleDockTitles(bool checked) { if (checked) { delete connectDock->titleBarWidget(); connectDock->setTitleBarWidget(nullptr); delete logDock->titleBarWidget(); logDock->setTitleBarWidget(nullptr); delete tempTimelineDock->titleBarWidget(); tempTimelineDock->setTitleBarWidget(nullptr); delete commandDock->titleBarWidget(); commandDock->setTitleBarWidget(nullptr); delete moveDock->titleBarWidget(); moveDock->setTitleBarWidget(nullptr); delete tempControlsDock->titleBarWidget(); tempControlsDock->setTitleBarWidget(nullptr); delete printDock->titleBarWidget(); printDock->setTitleBarWidget(nullptr); delete sdDock->titleBarWidget(); sdDock->setTitleBarWidget(nullptr); delete profileDock->titleBarWidget(); profileDock->setTitleBarWidget(nullptr); } else { if (!connectDock->isFloating()) { connectDock->setTitleBarWidget(new QWidget()); } if (!logDock->isFloating()) { logDock->setTitleBarWidget(new QWidget()); } if (!tempTimelineDock->isFloating()) { tempTimelineDock->setTitleBarWidget(new QWidget()); } if (!commandDock->isFloating()) { commandDock->setTitleBarWidget(new QWidget()); } if (!moveDock->isFloating()) { moveDock->setTitleBarWidget(new QWidget()); } if (!tempControlsDock->isFloating()) { tempControlsDock->setTitleBarWidget(new QWidget()); } if (!printDock->isFloating()) { printDock->setTitleBarWidget(new QWidget()); } if (!sdDock->isFloating()) { sdDock->setTitleBarWidget(new QWidget()); } if (!profileDock->isFloating()) { profileDock->setTitleBarWidget(new QWidget()); } } } void MainWindow::setDangeriousDocksDisabled(bool disabled) { commandDock->widget()->setDisabled(disabled); moveDock->widget()->setDisabled(disabled); tempControlsDock->widget()->setDisabled(disabled); printDock->widget()->setDisabled(disabled); sdDock->widget()->setDisabled(disabled); if (!disabled) { temperatureWidget->updateExtruderCount(core->extruderCount()); printWidget->updateFanCount(fanCount); } else { printWidget->setPrintText(tr("Print File")); statusWidget->showPrintArea(false); } } void MainWindow::setConnectionWidgetsEnabled(bool enabled) { comboProfile->setEnabled(enabled); comboPort->setEnabled(enabled); } void MainWindow::updateAutoTemperatureReport(bool autoReport) { disconnect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, {}); disconnect(core, &AtCore::temperatureTimerIntervalChanged, this, {}); disconnect(core, &AtCore::autoCheckTemperatureIntervalChanged, this, {}); if (autoReport) { - connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - core->setAutoCheckTemperatureInterval(value); - }); + connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { core->setAutoCheckTemperatureInterval(value); }); connect(core, &AtCore::autoCheckTemperatureIntervalChanged, this, [this](int value) { if (value != sbTemperatureTimer->value()) { sbTemperatureTimer->blockSignals(true); sbTemperatureTimer->setValue(value); sbTemperatureTimer->blockSignals(false); } }); } else { - connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { - core->setTemperatureTimerInterval(value * 1000); - }); + connect(sbTemperatureTimer, QOverload::of(&QSpinBox::valueChanged), this, [this](int value) { core->setTemperatureTimerInterval(value * 1000); }); connect(core, &AtCore::temperatureTimerIntervalChanged, this, [this](int value) { if (value != sbTemperatureTimer->value()) { sbTemperatureTimer->blockSignals(true); sbTemperatureTimer->setValue(value / 1000); sbTemperatureTimer->blockSignals(false); } }); } } diff --git a/testclient/mainwindow.h b/testclient/mainwindow.h index 43310a9..a559c7a 100644 --- a/testclient/mainwindow.h +++ b/testclient/mainwindow.h @@ -1,188 +1,189 @@ /* AtCore Test Client Copyright (C) <2016 - 2019> Authors: Patrick José Pereira Lays Rodrigues Chris Rizzitello Tomaz Canabrava 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 . */ #pragma once #include #include "atcore.h" #include "commandwidget.h" #include "logwidget.h" #include "movementwidget.h" #include "plotwidget.h" #include "printwidget.h" #include "profilemanager.h" #include "sdwidget.h" #include "statuswidget.h" #include "temperaturewidget.h" class SerialLayer; -class MainWindow: public QMainWindow +class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow() override = default; public slots: /** * @brief Check temperature * * @param sensorType : type of sensor * @param number : index of sensor * @param temp : temperature */ void checkTemperature(uint sensorType, uint number, float temp); private slots: - //ButtonEvents + // ButtonEvents /** * @brief Connect Button Clicked will connect or disconnect based on printer state */ void connectPBClicked(); /** * @brief Print Button Clicked, can also pause /resue print based on printer state */ void printPBClicked(); /** * @brief printerStateChanged Catch and proccess printer state commands * @param state: new printer state */ void printerStateChanged(AtCore::STATES state); /** * @brief show/hide dock titlebars * @param checked: True if shown */ void toggleDockTitles(bool checked); /** * @brief set enabled for connection option widgets (port, baud and fw selector) * @param enabled: true if enabled. */ void setConnectionWidgetsEnabled(bool enabled); /** * @brief Toggle disable state of dangerous docks * Command, Sd Card, Movement, Temperature Controls and Printing docks * @param disabled: True if items are disabled. */ void setDangeriousDocksDisabled(bool disabled); /** * @brief Called when atcore changes it temperature reporting mode * @param autoReport: True if using temperature auto reporting */ void updateAutoTemperatureReport(bool autoReport); + private: AtCore *core; // Define max number of fans static int fanCount; void closeEvent(QCloseEvent *event) override; /** * @brief Locate serial port * */ void locateSerialPort(const QStringList &ports); /** * @brief setupActions for KXMLGui */ void setupActions(); /** * @brief Populate comboboxes */ void populateCBs(); /** * @brief Gui Changes for when sd card mount status has changed. */ void sdChanged(bool mounted); - //UI Functions + // UI Functions /** * @brief Create The Menubar */ void initMenu(); /** * @brief Create StatusBar */ void initStatusBar(); /** * @brief Create Main Widgets. */ void initWidgets(); -//Private GUI Items - //menuView is global to allow for docks to be added / removed. + // Private GUI Items + // menuView is global to allow for docks to be added / removed. QMenu *menuView = nullptr; - //Status Bar Items + // Status Bar Items StatusWidget *statusWidget = nullptr; - //Docks + // Docks void makeLogDock(); QDockWidget *logDock = nullptr; LogWidget *logWidget = nullptr; void makeTempTimelineDock(); QDockWidget *tempTimelineDock = nullptr; PlotWidget *plotWidget = nullptr; void makeCommandDock(); QDockWidget *commandDock = nullptr; CommandWidget *commandWidget = nullptr; void makePrintDock(); QDockWidget *printDock = nullptr; PrintWidget *printWidget = nullptr; void makeConnectDock(); QDockWidget *connectDock = nullptr; QComboBox *comboPort = nullptr; QComboBox *comboProfile = nullptr; QPushButton *buttonConnect = nullptr; QCheckBox *cbReset = nullptr; QTimer *connectionTimer = nullptr; QSpinBox *sbTemperatureTimer = nullptr; void makeMoveDock(); QDockWidget *moveDock = nullptr; MovementWidget *movementWidget = nullptr; void makeTempControlsDock(); QDockWidget *tempControlsDock = nullptr; TemperatureWidget *temperatureWidget = nullptr; void makeSdDock(); QDockWidget *sdDock = nullptr; SdWidget *sdWidget = nullptr; void makeProfileDock(); QDockWidget *profileDock = nullptr; ProfileManager *profileManager = nullptr; }; diff --git a/unittests/atcoretests.cpp b/unittests/atcoretests.cpp index cf01c88..7a359ae 100644 --- a/unittests/atcoretests.cpp +++ b/unittests/atcoretests.cpp @@ -1,290 +1,275 @@ /* This file is part of the KDE project Copyright (C) 2017 - 2019 Chris Rizzitello 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 "atcoretests.h" void AtCoreTests::initTestCase() { core = new AtCore(); } void AtCoreTests::cleanupTestCase() { - } void AtCoreTests::testInitState() { QVERIFY(core->state() == AtCore::DISCONNECTED); } void AtCoreTests::testPluginDetect() { QStringList fwPluginsFound = core->availableFirmwarePlugins(); - QStringList fwPluginsActual = { - QStringLiteral("aprinter"), - QStringLiteral("grbl"), - QStringLiteral("marlin"), - QStringLiteral("repetier"), - QStringLiteral("smoothie"), - QStringLiteral("sprinter"), - QStringLiteral("teacup") - }; + QStringList fwPluginsActual = {QStringLiteral("aprinter"), QStringLiteral("grbl"), QStringLiteral("marlin"), QStringLiteral("repetier"), QStringLiteral("smoothie"), QStringLiteral("sprinter"), QStringLiteral("teacup")}; std::sort(fwPluginsFound.begin(), fwPluginsFound.end()); std::sort(fwPluginsActual.begin(), fwPluginsActual.end()); QVERIFY(fwPluginsFound == fwPluginsActual); } void AtCoreTests::testConnectInvalidDevice() { QEXPECT_FAIL("", "Invalid Device Attempt", Continue); QVERIFY(core->newConnection(QStringLiteral("/dev/ptyp5"), 9600, QStringLiteral("FirmwareNAME"))); } void AtCoreTests::testStateChange() { QList args; QSignalSpy sSpy(core, SIGNAL(stateChanged(AtCore::STATES))); QVERIFY(sSpy.isValid()); core->setState(AtCore::CONNECTING); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::CONNECTING); core->setState(AtCore::IDLE); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::IDLE); core->setState(AtCore::BUSY); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::BUSY); core->setState(AtCore::PAUSE); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::PAUSE); core->setState(AtCore::STOP); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::STOP); core->setState(AtCore::ERRORSTATE); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::ERRORSTATE); core->setState(AtCore::STARTPRINT); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::STARTPRINT); core->setState(AtCore::FINISHEDPRINT); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::FINISHEDPRINT); core->setState(AtCore::DISCONNECTED); args = sSpy.takeFirst(); QVERIFY(args.at(0).toInt() == AtCore::DISCONNECTED); } void AtCoreTests::testSdMountChanged() { QList args; QSignalSpy sSpy(core, SIGNAL(sdMountChanged(bool))); QVERIFY(sSpy.isValid()); core->setSdMounted(true); args = sSpy.takeFirst(); QVERIFY(args.at(0).toBool() == true); core->setSdMounted(false); args = sSpy.takeFirst(); QVERIFY(args.at(0).toBool() == false); } void AtCoreTests::testSdFileList() { QSignalSpy sSpy(core, SIGNAL(sdCardFileListChanged(QStringList))); QVERIFY(sSpy.isValid()); core->appendSdCardFileList(QStringLiteral("FILE1")); core->appendSdCardFileList(QStringLiteral("FILE2")); core->appendSdCardFileList(QStringLiteral("FILE3")); core->appendSdCardFileList(QStringLiteral("FILE4")); core->appendSdCardFileList(QStringLiteral("FILE5")); QList args = sSpy.takeLast(); - QStringList fileList = { - QStringLiteral("FILE1"), - QStringLiteral("FILE2"), - QStringLiteral("FILE3"), - QStringLiteral("FILE4"), - QStringLiteral("FILE5") - }; + QStringList fileList = {QStringLiteral("FILE1"), QStringLiteral("FILE2"), QStringLiteral("FILE3"), QStringLiteral("FILE4"), QStringLiteral("FILE5")}; QVERIFY(args.at(0).toStringList() == fileList); core->clearSdCardFileList(); args = sSpy.takeLast(); QVERIFY(args.at(0).toStringList().isEmpty()); } void AtCoreTests::testSerialTimerIntervalChanged() { QSignalSpy sSpy(core, SIGNAL(serialTimerIntervalChanged(int))); QVERIFY(sSpy.isValid()); core->setSerialTimerInterval(1000); core->setSerialTimerInterval(1000); core->setSerialTimerInterval(2000); core->setSerialTimerInterval(0); QVERIFY(sSpy.count() == 3); } void AtCoreTests::testExtruderCountChanged() { QSignalSpy sSpy(core, SIGNAL(extruderCountChanged(int))); QVERIFY(sSpy.isValid()); core->setExtruderCount(1); core->setExtruderCount(2); core->setExtruderCount(1); QVERIFY(sSpy.count() == 2); } void AtCoreTests::testPluginAprinter_load() { core->loadFirmwarePlugin(QStringLiteral("aprinter")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Aprinter")); } void AtCoreTests::testPluginAprinter_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginGrbl_load() { core->loadFirmwarePlugin(QStringLiteral("grbl")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Grbl")); } void AtCoreTests::testPluginGrbl_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginGrbl_translate() { QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("G28")) == "G28"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("M104 S50 G28 X")) == "M104 S50\r\nG28 X"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("G00 G43 H0 Z0.1")) == "G00\r\nG43 H0 Z0.1"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("M6 T0")) == "M6 T0"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("G0 G49 G40 G17 G80 G50 G90")) == "G0\r\nG49\r\nG40\r\nG17\r\nG80\r\nG50\r\nG90"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("G0 S49 XY G40")) == "G0 S49 XY\r\nG40"); } void AtCoreTests::testPluginMarlin_load() { core->loadFirmwarePlugin(QStringLiteral("marlin")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Marlin")); } void AtCoreTests::testPluginMarlin_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginRepetier_load() { core->loadFirmwarePlugin(QStringLiteral("repetier")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Repetier")); } void AtCoreTests::testPluginRepetier_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginSmoothie_load() { core->loadFirmwarePlugin(QStringLiteral("smoothie")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Smoothie")); } void AtCoreTests::testPluginSmoothie_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginSprinter_load() { core->loadFirmwarePlugin(QStringLiteral("sprinter")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Sprinter")); } void AtCoreTests::testPluginSprinter_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginTeacup_load() { core->loadFirmwarePlugin(QStringLiteral("teacup")); QVERIFY(core->firmwarePlugin()->name() == QStringLiteral("Teacup")); } void AtCoreTests::testPluginTeacup_validate() { QSignalSpy sSpy(core->firmwarePlugin(), SIGNAL(readyForCommand())); QVERIFY(sSpy.isValid() == true); core->firmwarePlugin()->validateCommand(QStringLiteral("ok")); core->firmwarePlugin()->validateCommand(QStringLiteral("other text")); QVERIFY(sSpy.count() == 1); } void AtCoreTests::testPluginTeacup_translate() { QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("G28")) == "G28"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("M109 S50")) == "M104 S50\r\nM116"); QVERIFY(core->firmwarePlugin()->translate(QStringLiteral("M190 S50")) == "M140 S50\r\nM116"); } QTEST_MAIN(AtCoreTests) diff --git a/unittests/atcoretests.h b/unittests/atcoretests.h index a8eabda..26b8ad4 100644 --- a/unittests/atcoretests.h +++ b/unittests/atcoretests.h @@ -1,56 +1,57 @@ /* This file is part of the KDE project Copyright (C) 2017 Chris Rizzitello 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 "../src/core/atcore.h" #include "../src/core/seriallayer.h" -class AtCoreTests: public QObject +class AtCoreTests : public QObject { Q_OBJECT private slots: void initTestCase(); void testInitState(); void testPluginDetect(); void testConnectInvalidDevice(); void cleanupTestCase(); void testStateChange(); void testSdMountChanged(); void testSdFileList(); void testSerialTimerIntervalChanged(); void testExtruderCountChanged(); void testPluginAprinter_load(); void testPluginAprinter_validate(); void testPluginGrbl_load(); void testPluginGrbl_validate(); void testPluginGrbl_translate(); void testPluginMarlin_load(); void testPluginMarlin_validate(); void testPluginRepetier_load(); void testPluginRepetier_validate(); void testPluginSmoothie_load(); void testPluginSmoothie_validate(); void testPluginSprinter_load(); void testPluginSprinter_validate(); void testPluginTeacup_load(); void testPluginTeacup_validate(); void testPluginTeacup_translate(); + private: AtCore *core = nullptr; }; diff --git a/unittests/beddeformtests.cpp b/unittests/beddeformtests.cpp index a31e76b..a4d3d25 100644 --- a/unittests/beddeformtests.cpp +++ b/unittests/beddeformtests.cpp @@ -1,63 +1,61 @@ /* This file is part of the KDE project Copyright (C) 2019 Chris Rizzitello 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 "beddeformtests.h" +#include void BedDeformTests::initTestCase() { bedDeform = new BedDeform(this); } void BedDeformTests::testDecode() { - QStringList temp = { - QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("echo:busy: processing") - , QStringLiteral("Bilinear Leveling Grid:") - , QStringLiteral("0 1 2") - , QStringLiteral("0 +0.255 +0.225 -0.038") - , QStringLiteral("1 +0.060 +0.008 -0.255") - , QStringLiteral("2 -0.153 -0.245 -0.528") - , QString() - , QStringLiteral("X:155.00 Y:185.00 Z:12.23 E:0.00 Count X:12400 Y:14800 Z:4720") - , QStringLiteral("ok") - }; + QStringList temp = {QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("echo:busy: processing"), + QStringLiteral("Bilinear Leveling Grid:"), + QStringLiteral("0 1 2"), + QStringLiteral("0 +0.255 +0.225 -0.038"), + QStringLiteral("1 +0.060 +0.008 -0.255"), + QStringLiteral("2 -0.153 -0.245 -0.528"), + QString(), + QStringLiteral("X:155.00 Y:185.00 Z:12.23 E:0.00 Count X:12400 Y:14800 Z:4720"), + QStringLiteral("ok")}; bedDeform->decodeDeform(temp); QVERIFY(bedDeform->bedDeformationGrid().at(0).toList().at(0).toDouble() == 0.255); QVERIFY(bedDeform->bedDeformationGrid().at(0).toList().at(1).toDouble() == 0.225); QVERIFY(bedDeform->bedDeformationGrid().at(0).toList().at(2).toDouble() == -0.038); QVERIFY(bedDeform->bedDeformationGrid().at(1).toList().at(0).toDouble() == 0.060); QVERIFY(bedDeform->bedDeformationGrid().at(1).toList().at(1).toDouble() == 0.008); QVERIFY(bedDeform->bedDeformationGrid().at(1).toList().at(2).toDouble() == -0.255); QVERIFY(bedDeform->bedDeformationGrid().at(2).toList().at(0).toDouble() == -0.153); QVERIFY(bedDeform->bedDeformationGrid().at(2).toList().at(1).toDouble() == -0.245); QVERIFY(bedDeform->bedDeformationGrid().at(2).toList().at(2).toDouble() == -0.528); } QTEST_MAIN(BedDeformTests) diff --git a/unittests/beddeformtests.h b/unittests/beddeformtests.h index d3741f9..e5fc8eb 100644 --- a/unittests/beddeformtests.h +++ b/unittests/beddeformtests.h @@ -1,31 +1,32 @@ /* This file is part of the KDE project Copyright (C) 2019 Chris Rizzitello 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 "../src/core/beddeform.h" -class BedDeformTests: public QObject +class BedDeformTests : public QObject { Q_OBJECT private slots: void initTestCase(); void testDecode(); + private: BedDeform *bedDeform; }; diff --git a/unittests/gcodetests.cpp b/unittests/gcodetests.cpp index ae36e12..15a9e31 100644 --- a/unittests/gcodetests.cpp +++ b/unittests/gcodetests.cpp @@ -1,239 +1,240 @@ /* This file is part of the KDE project Copyright (C) 2017 Chris Rizzitello 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 "gcodetests.h" bool GCodeTests::testGCodeNeedsArg(GCode::GCommands code) { return GCode::toCommand(code) == GCode::commandRequiresArgument.arg(QStringLiteral("G"), QString::number(code)); } void GCodeTests::command_G0() { QVERIFY(GCode::toCommand(GCode::G0) == QStringLiteral("G0")); QVERIFY(GCode::toCommand(GCode::G0, QStringLiteral("50")) == QStringLiteral("G0 50")); } void GCodeTests::command_G1() { QVERIFY(GCode::toCommand(GCode::G1) == QStringLiteral("G1")); QVERIFY(GCode::toCommand(GCode::G1, QStringLiteral("50")) == QStringLiteral("G1 50")); } void GCodeTests::command_G28() { QVERIFY(GCode::toCommand(GCode::G28) == QStringLiteral("G28")); QVERIFY(GCode::toCommand(GCode::G28, QStringLiteral("Y")) == QStringLiteral("G28 Y")); } void GCodeTests::command_G32() { QVERIFY(GCode::toCommand(GCode::G32) == QStringLiteral("G32 S1")); } void GCodeTests::command_G90() { QVERIFY(GCode::toCommand(GCode::G90) == QStringLiteral("G90")); } void GCodeTests::command_G91() { QVERIFY(GCode::toCommand(GCode::G91) == QStringLiteral("G91")); } void GCodeTests::command_unsupportedG() { QVERIFY(GCode::toCommand(GCode::G2) == GCode::commandNotSupported); } bool GCodeTests::testMCodeNeedsArg(GCode::MCommands code) { return GCode::toCommand(code) == GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(code)); } void GCodeTests::command_M20() { QVERIFY(GCode::toCommand(GCode::M20) == QStringLiteral("M20")); } void GCodeTests::command_M21() { QVERIFY(GCode::toCommand(GCode::M21) == QStringLiteral("M21")); QVERIFY(GCode::toCommand(GCode::M21, QStringLiteral("2")) == QStringLiteral("M21 P2")); } void GCodeTests::command_M22() { QVERIFY(GCode::toCommand(GCode::M22) == QStringLiteral("M22")); QVERIFY(GCode::toCommand(GCode::M22, QStringLiteral("5")) == QStringLiteral("M22 P5")); } void GCodeTests::command_M23() { QVERIFY(testMCodeNeedsArg(GCode::M23)); QVERIFY(GCode::toCommand(GCode::M23, QStringLiteral("FileName")) == QStringLiteral("M23 FileName")); } void GCodeTests::command_M24() { QVERIFY(GCode::toCommand(GCode::M24) == QStringLiteral("M24")); } void GCodeTests::command_M25() { QVERIFY(GCode::toCommand(GCode::M25) == QStringLiteral("M25")); } void GCodeTests::command_M26() { QVERIFY(testMCodeNeedsArg(GCode::M26)); QVERIFY(GCode::toCommand(GCode::M26, QStringLiteral("15%")) == QStringLiteral("M26 P0.15")); QVERIFY(GCode::toCommand(GCode::M26, QStringLiteral("15")) == QStringLiteral("M26 S15")); - } void GCodeTests::command_M27() { QVERIFY(GCode::toCommand(GCode::M27) == QStringLiteral("M27")); } void GCodeTests::command_M28() { QVERIFY(testMCodeNeedsArg(GCode::M28)); QVERIFY(GCode::toCommand(GCode::M28, QStringLiteral("FileName")) == QStringLiteral("M28 FileName")); } void GCodeTests::command_M29() { QVERIFY(testMCodeNeedsArg(GCode::M29)); QVERIFY(GCode::toCommand(GCode::M29, QStringLiteral("FileName")) == QStringLiteral("M29 FileName")); } void GCodeTests::command_M30() { QVERIFY(testMCodeNeedsArg(GCode::M30)); QVERIFY(GCode::toCommand(GCode::M30, QStringLiteral("FileName")) == QStringLiteral("M30 FileName")); } void GCodeTests::command_M84() { QVERIFY(GCode::toCommand(GCode::M84) == QStringLiteral("M84")); QVERIFY(GCode::toCommand(GCode::M84, QStringLiteral("10")) == QStringLiteral("M84 S10")); } void GCodeTests::command_M104() { QVERIFY(testMCodeNeedsArg(GCode::M104)); QVERIFY(GCode::toCommand(GCode::M104, QStringLiteral("100")) == QStringLiteral("M104 S100")); QVERIFY(GCode::toCommand(GCode::M104, QStringLiteral("3"), QStringLiteral("100")) == QStringLiteral("M104 P3 S100")); } void GCodeTests::command_M105() { QVERIFY(GCode::toCommand(GCode::M105) == QStringLiteral("M105")); } void GCodeTests::command_M106() { QVERIFY(GCode::toCommand(GCode::M106) == QStringLiteral("M106")); QVERIFY(GCode::toCommand(GCode::M106, QStringLiteral("100")) == QStringLiteral("M106 S100")); QVERIFY(GCode::toCommand(GCode::M106, QStringLiteral("3"), QStringLiteral("100")) == QStringLiteral("M106 P3 S100")); } void GCodeTests::command_M107() { QVERIFY(GCode::toCommand(GCode::M107) == QStringLiteral("M107")); } void GCodeTests::command_M109() { QVERIFY(testMCodeNeedsArg(GCode::M109)); QVERIFY(GCode::toCommand(GCode::M109, QStringLiteral("100")) == QStringLiteral("M109 S100")); } void GCodeTests::command_M112() { QVERIFY(GCode::toCommand(GCode::M112) == QStringLiteral("M112")); } void GCodeTests::command_M114() { QVERIFY(GCode::toCommand(GCode::M114) == QStringLiteral("M114")); } void GCodeTests::command_M115() { QVERIFY(GCode::toCommand(GCode::M115) == QStringLiteral("M115")); } void GCodeTests::command_M116() { QVERIFY(GCode::toCommand(GCode::M116) == QStringLiteral("M116")); } void GCodeTests::command_M117() { QVERIFY(testMCodeNeedsArg(GCode::M117)); QVERIFY(GCode::toCommand(GCode::M117, QStringLiteral("100")) == QStringLiteral("M117 100")); } void GCodeTests::command_M119() { QVERIFY(GCode::toCommand(GCode::M119) == QStringLiteral("M119")); } void GCodeTests::command_M140() { QVERIFY(testMCodeNeedsArg(GCode::M140)); QVERIFY(GCode::toCommand(GCode::M140, QStringLiteral("100")) == QStringLiteral("M140 S100")); } void GCodeTests::command_M155() { QVERIFY(testMCodeNeedsArg(GCode::M155)); QVERIFY(GCode::toCommand(GCode::M155, QStringLiteral("1")) == QStringLiteral("M155 S1")); } void GCodeTests::command_M190() { QVERIFY(testMCodeNeedsArg(GCode::M190)); QVERIFY(GCode::toCommand(GCode::M190, QStringLiteral("100")) == QStringLiteral("M190 S100")); } void GCodeTests::command_M220() { - QVERIFY(testMCodeNeedsArg(GCode::M220));; + QVERIFY(testMCodeNeedsArg(GCode::M220)); + ; QVERIFY(GCode::toCommand(GCode::M220, QStringLiteral("100")) == QStringLiteral("M220 S100")); } void GCodeTests::command_M221() { - QVERIFY(testMCodeNeedsArg(GCode::M221));; + QVERIFY(testMCodeNeedsArg(GCode::M221)); + ; QVERIFY(GCode::toCommand(GCode::M221, QStringLiteral("100")) == QStringLiteral("M221 S100")); } void GCodeTests::command_unsupportedM() { QVERIFY(GCode::toCommand(GCode::M999) == GCode::commandNotSupported); } QTEST_MAIN(GCodeTests) diff --git a/unittests/gcodetests.h b/unittests/gcodetests.h index 237a117..08418bb 100644 --- a/unittests/gcodetests.h +++ b/unittests/gcodetests.h @@ -1,66 +1,66 @@ /* This file is part of the KDE project Copyright (C) 2017 Chris Rizzitello 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 "../src/core/gcodecommands.h" -class GCodeTests: public QObject +class GCodeTests : public QObject { Q_OBJECT private slots: bool testGCodeNeedsArg(GCode::GCommands code); void command_G0(); void command_G1(); void command_G28(); void command_G32(); void command_G90(); void command_G91(); void command_unsupportedG(); bool testMCodeNeedsArg(GCode::MCommands code); void command_M20(); void command_M21(); void command_M22(); void command_M23(); void command_M24(); void command_M25(); void command_M26(); void command_M27(); void command_M28(); void command_M29(); void command_M30(); void command_M84(); void command_M104(); void command_M105(); void command_M106(); void command_M107(); void command_M109(); void command_M112(); void command_M114(); void command_M115(); void command_M116(); void command_M117(); void command_M119(); void command_M140(); void command_M155(); void command_M190(); void command_M220(); void command_M221(); void command_unsupportedM(); }; diff --git a/unittests/temperaturetests.cpp b/unittests/temperaturetests.cpp index e7a3af7..9c5b07a 100644 --- a/unittests/temperaturetests.cpp +++ b/unittests/temperaturetests.cpp @@ -1,95 +1,94 @@ /* This file is part of the KDE project Copyright (C) 2017 Chris Rizzitello 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 "temperaturetests.h" void TemperatureTests::initTestCase() { temperature = new Temperature(this); } void TemperatureTests::cleanup() { temperature->resetData(); } void TemperatureTests::testDecodeAprinter() { temperature->decodeTemp(QByteArray("ok B:49.06 /55 T:64.78 /215")); QVERIFY(temperature->extruderTemperature() == float(64.78)); QVERIFY(temperature->extruderTargetTemperature() == 215); QVERIFY(temperature->bedTemperature() == float(49.06)); QVERIFY(temperature->bedTargetTemperature() == 55); } void TemperatureTests::testDecodeMarlin() { temperature->decodeTemp(QByteArray("ok T:49.74 /60.00 B:36.23 /50.00 @:0 B@:0")); QVERIFY(temperature->extruderTemperature() == float(49.74)); QVERIFY(temperature->extruderTargetTemperature() == 60); QVERIFY(temperature->bedTemperature() == float(36.23)); QVERIFY(temperature->bedTargetTemperature() == 50); } void TemperatureTests::testDecodeMarlinCreality() { temperature->decodeTemp(QByteArray("ok T:48.8 /215.0 B:57.5 /70.0 T0:48.8 /0.0 @:0 B@:0")); QVERIFY(temperature->extruderTemperature() == float(48.8)); QVERIFY(temperature->extruderTargetTemperature() == 215); QVERIFY(temperature->bedTemperature() == float(57.5)); QVERIFY(temperature->bedTargetTemperature() == 70); } void TemperatureTests::testDecodeRepetier() { temperature->decodeTemp(QByteArray("T:25.47 /230 B:69.42 /80 B@:255 @:0")); QVERIFY(temperature->extruderTemperature() == float(25.47)); QVERIFY(temperature->extruderTargetTemperature() == 230); QVERIFY(temperature->bedTemperature() == float(69.42)); QVERIFY(temperature->bedTargetTemperature() == 80); } void TemperatureTests::testDecodeSmoothie() { temperature->decodeTemp(QByteArray("ok T:76.36 /220.0 @0 B:24.1 /60.0 @")); QVERIFY(temperature->extruderTemperature() == float(76.36)); QVERIFY(temperature->extruderTargetTemperature() == 220); QVERIFY(temperature->bedTemperature() == float(24.1)); QVERIFY(temperature->bedTargetTemperature() == 60); - } void TemperatureTests::testDecodeSprinter() { temperature->decodeTemp(QByteArray("ok T:154 @:0 B:150")); QVERIFY(temperature->extruderTemperature() == 154); QVERIFY(temperature->bedTemperature() == 150); } void TemperatureTests::testDecodeTeacup() { temperature->decodeTemp(QByteArray("T:15.50/210.0 B:46.80/82.0")); QVERIFY(temperature->extruderTemperature() == float(15.50)); QVERIFY(temperature->extruderTargetTemperature() == 210); QVERIFY(temperature->bedTemperature() == float(46.80)); QVERIFY(temperature->bedTargetTemperature() == 82); } QTEST_MAIN(TemperatureTests) diff --git a/unittests/temperaturetests.h b/unittests/temperaturetests.h index c843477..91ede92 100644 --- a/unittests/temperaturetests.h +++ b/unittests/temperaturetests.h @@ -1,38 +1,39 @@ /* This file is part of the KDE project Copyright (C) 2017 Chris Rizzitello 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 "../src/core/temperature.h" -class TemperatureTests: public QObject +class TemperatureTests : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanup(); void testDecodeAprinter(); void testDecodeMarlin(); void testDecodeMarlinCreality(); void testDecodeRepetier(); void testDecodeSmoothie(); void testDecodeSprinter(); void testDecodeTeacup(); + private: Temperature *temperature; };