diff --git a/src/atcore.h b/src/atcore.h
--- a/src/atcore.h
+++ b/src/atcore.h
@@ -59,6 +59,8 @@
Q_PROPERTY(QStringList portSpeeds READ portSpeeds)
Q_PROPERTY(QString connectedPort READ connectedPort)
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)
public:
/**
* @brief STATES enum Possible states the printer can be in
@@ -200,6 +202,59 @@
*/
quint16 serialTimerInterval() const;
+ /**
+ * @brief Attempt to Mount an sd card
+ * @param slot: Sd card Slot on machine (0 is default)
+ */
+ void mountSd(uint slot = 0);
+
+ /**
+ * @brief Attempt to Unmount an sd card
+ * @param slot: Sd card Slot on machine (0 is default)
+ */
+ void umountSd(uint slot = 0);
+
+ /**
+ * @brief sdFileList
+ * @return List of files on the sd card.
+ */
+ QStringList sdFileList();
+
+ /**
+ * @brief Append a file to AtCorePrivate::sdCardFileList.
+ * @param fileName: new FileName
+ */
+ void appendSdCardFileList(const QString &fileName);
+
+ /**
+ * @brief Clear AtCorePrivate::sdCardFileList.
+ */
+ void clearSdCardFileList();
+
+ /**
+ * @brief Check if an sd card is mounted on the printer
+ * @return True if card mounted
+ */
+ bool isSdMounted() const;
+
+ /**
+ * @brief Set if the sd card is mounted by the printer
+ * @param mounted: True is mounted
+ */
+ void setSdMounted(const bool mounted);
+
+ /**
+ * @brief returns AtCorePrivate::sdCardReadingFileList
+ * @return True if printer is returning sd card file list
+ */
+ bool isReadingSdCardList() const;
+
+ /**
+ * @brief set AtCorePrivate::sdCardReadingFileList
+ * @param readingList set true if reading file list
+ */
+ void setReadingSdCardList(bool readingList);
+
signals:
/**
@@ -225,7 +280,17 @@
/**
* @brief Available serialports Changed
*/
- void portsChanged(QStringList);
+ 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);
public slots:
@@ -246,8 +311,9 @@
/**
* @brief Public Interface for printing a file
* @param fileName: the gcode file to print.
+ * @param sdPrint: set true to print fileName from Sd card
*/
- void print(const QString &fileName);
+ void print(const QString &fileName, bool sdPrint);
/**
* @brief Stop the Printer by empting the queue and aborting the print job (if running)
@@ -378,6 +444,16 @@
*/
void setSerialTimerInterval(const quint16 &newTime);
+ /**
+ * @brief delete file from sd card
+ */
+ 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.
@@ -407,6 +483,11 @@
*/
void locateSerialPort();
+ /**
+ * @brief Send request to the printer for the sd card file list.
+ */
+ void getSDFileList();
+
private:
/**
* @brief True if a firmware plugin is loaded
@@ -428,6 +509,12 @@
*/
void findFirmwarePlugins();
+ /**
+ * @brief stops print just for sd prints used internally
+ * @sa stop(),emergencyStop()
+ */
+ void stopSdPrint();
+
/**
* @brief Hold private data of AtCore.
*/
diff --git a/src/atcore.cpp b/src/atcore.cpp
--- a/src/atcore.cpp
+++ b/src/atcore.cpp
@@ -61,6 +61,11 @@
AtCore::STATES printerState; //!< @param printerState: State of the Printer
QStringList serialPorts; //!< @param seralPorts: Detected serial Ports
QTimer *serialTimer = nullptr; //!< @param serialTimer: Timer connected to locateSerialPorts
+ bool sdCardMounted = false; //!< @param sdCardMounted: True if Sd Card is mounted.
+ bool sdCardReadingFileList = false; //!< @param sdCardReadingFileList: True while getting file names from sd card
+ bool sdCardPrinting = false; //!< @param sdCardPrinting: True if currently printing from sd card.
+ QString sdCardFileName; //!< @param sdCardFileName: name of file being used from sd card.
+ QStringList sdCardFileList; //!< @param sdCardFileList: List of files on sd card.
};
AtCore::AtCore(QObject *parent) :
@@ -325,14 +330,23 @@
return d->percentage;
}
-void AtCore::print(const QString &fileName)
+void AtCore::print(const QString &fileName, bool sdPrint)
{
if (state() == AtCore::CONNECTING) {
qCDebug(ATCORE_CORE) << "Load a firmware plugin to print.";
return;
}
- //START A THREAD AND CONNECT TO IT
setState(AtCore::STARTPRINT);
+ if (sdPrint) {
+ pushCommand(GCode::toCommand(GCode::M23, fileName));
+ d->sdCardFileName = fileName;
+ pushCommand(GCode::toCommand(GCode::M24));
+ setState(AtCore::BUSY);
+ d->sdCardPrinting = true;
+ connect(d->tempTimer, &QTimer::timeout, this, &AtCore::sdCardPrintStatus);
+ return;
+ }
+ //START A THREAD AND CONNECT TO IT
QThread *thread = new QThread();
PrintThread *printThread = new PrintThread(this, fileName);
printThread->moveToThread(thread);
@@ -357,8 +371,9 @@
void AtCore::closeConnection()
{
if (serialInitialized()) {
- if (state() == AtCore::BUSY) {
- //we have to clean print if printing.
+ if (AtCore::state() == AtCore::BUSY && !d->sdCardPrinting) {
+ //we have to clean print if printing from the host.
+ //disconnecting from a printer printing via sd card should not affect its print.
setState(AtCore::STOP);
}
if (firmwarePluginLoaded()) {
@@ -373,6 +388,7 @@
QString msg = d->pluginLoader.unload() ? QStringLiteral("success") : QStringLiteral("FAIL");
qCDebug(ATCORE_PLUGIN) << QStringLiteral("Firmware plugin %1 unload: %2").arg(name, msg);
serial()->close();
+ clearSdCardFileList();
setState(AtCore::DISCONNECTED);
}
}
@@ -388,28 +404,47 @@
qCDebug(ATCORE_CORE) << "Atcore state changed from [" \
<< d->printerState << "] to [" << state << "]";
d->printerState = state;
+ if (state == AtCore::FINISHEDPRINT && d->sdCardPrinting) {
+ d->sdCardPrinting = false;
+ disconnect(d->tempTimer, &QTimer::timeout, this, &AtCore::sdCardPrintStatus);
+ }
emit(stateChanged(d->printerState));
}
}
void AtCore::stop()
{
setState(AtCore::STOP);
d->commandQueue.clear();
+ if (d->sdCardPrinting) {
+ stopSdPrint();
+ }
setExtruderTemp(0, 0);
setBedTemp(0);
home(AtCore::X);
}
void AtCore::emergencyStop()
{
- if (state() == AtCore::BUSY) {
- setState(AtCore::STOP);
- }
d->commandQueue.clear();
+ if (AtCore::state() == AtCore::BUSY) {
+ if (!d->sdCardPrinting) {
+ //Stop our running print thread
+ setState(AtCore::STOP);
+ }
+ }
serial()->pushCommand(GCode::toCommand(GCode::M112).toLocal8Bit());
}
+void AtCore::stopSdPrint()
+{
+ pushCommand(GCode::toCommand(GCode::M25));
+ d->sdCardFileName = QString();
+ pushCommand(GCode::toCommand(GCode::M23, d->sdCardFileName));
+ AtCore::setState(AtCore::FINISHEDPRINT);
+ AtCore::setState(AtCore::IDLE);
+}
+
void AtCore::requestFirmware()
{
if (serialInitialized()) {
@@ -472,19 +507,26 @@
void AtCore::pause(const QString &pauseActions)
{
+ if (d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M25));
+ }
pushCommand(GCode::toCommand(GCode::M114));
- setState(AtCore::PAUSE);
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()
{
- pushCommand(GCode::toCommand(GCode::G0, QString::fromLatin1(d->posString)));
+ if (d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M24));
+ } else {
+ pushCommand(GCode::toCommand(GCode::G0, QString::fromLatin1(d->posString)));
+ }
setState(AtCore::BUSY);
}
@@ -622,9 +664,80 @@
void AtCore::setIdleHold(uint delay)
{
- if (delay != 0) {
+ if (delay) {
pushCommand(GCode::toCommand(GCode::M84, QString::number(delay)));
} else {
pushCommand(GCode::toCommand(GCode::M84));
}
}
+
+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::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::M30, fileName));
+ getSDFileList();
+ }
+}
+
+void AtCore::mountSd(uint slot)
+{
+ pushCommand(GCode::toCommand(GCode::M21, QString::number(slot)));
+}
+
+void AtCore::umountSd(uint slot)
+{
+ pushCommand(GCode::toCommand(GCode::M22, QString::number(slot)));
+}
+
+bool AtCore::isReadingSdCardList() const
+{
+ return d->sdCardReadingFileList;
+}
+
+void AtCore::setReadingSdCardList(bool readingList)
+{
+ d->sdCardReadingFileList = readingList;
+}
+
+void AtCore::sdCardPrintStatus()
+{
+ pushCommand(GCode::toCommand(GCode::M27));
+}
diff --git a/src/gcodecommands.cpp b/src/gcodecommands.cpp
--- a/src/gcodecommands.cpp
+++ b/src/gcodecommands.cpp
@@ -96,13 +96,15 @@
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.toUpper()));
return code;
+
default:
return commandNotSupported;
}
@@ -129,7 +131,7 @@
return QObject::tr("M21: Initialize SDCard");
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
return QObject::tr("M24: Start/resume SD print");
@@ -289,7 +291,7 @@
return QObject::tr("M231: Set OPS parameter");
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
return QObject::tr("M250: Set LCD contrast");
@@ -494,35 +496,68 @@
{
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)) : QStringLiteral("M117 %1").arg(value1);
+ code = value1.isEmpty() ? GCode::commandRequiresArgument.arg(QStringLiteral("M"), QString::number(gcode)) : code.append(QStringLiteral(" %1").arg(value1));
return code;
+
case M109:
case M140:
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).arg(value2));
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).arg(value2));
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/plugins/marlinplugin.h b/src/plugins/marlinplugin.h
--- a/src/plugins/marlinplugin.h
+++ b/src/plugins/marlinplugin.h
@@ -48,4 +48,10 @@
* @return Marlin
*/
QString name() const override;
+
+ /**
+ * @brief validateCommand to filter commands from messages
+ * @param lastMessage: last Message from printer
+ */
+ void validateCommand(const QString &lastMessage) override;
};
diff --git a/src/plugins/marlinplugin.cpp b/src/plugins/marlinplugin.cpp
--- a/src/plugins/marlinplugin.cpp
+++ b/src/plugins/marlinplugin.cpp
@@ -39,3 +39,47 @@
{
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"))) {
+ QString temp = lastMessage;
+ temp.replace(QStringLiteral("SD printing byte"), QString());
+ qlonglong total = temp.mid(temp.lastIndexOf(QChar::fromLatin1('/')) + 1, temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))).toLongLong();
+ if (total) {
+ temp.chop(temp.length() - temp.lastIndexOf(QChar::fromLatin1('/')));
+ qlonglong remaining = total - temp.toLongLong();
+ float progress = float(total - remaining) * 100 / float(total);
+ core()->printProgressChanged(progress);
+ 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.h b/src/plugins/repetierplugin.h
--- a/src/plugins/repetierplugin.h
+++ b/src/plugins/repetierplugin.h
@@ -48,4 +48,10 @@
* @return Repetier
*/
QString name() const override;
+
+ /**
+ * @brief validateCommand to filter commands from messages
+ * @param lastMessage: last Message from printer
+ */
+ void validateCommand(const QString &lastMessage) override;
};
diff --git a/src/plugins/repetierplugin.cpp b/src/plugins/repetierplugin.cpp
--- a/src/plugins/repetierplugin.cpp
+++ b/src/plugins/repetierplugin.cpp
@@ -39,3 +39,49 @@
{
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"))) {
+ QString temp = lastMessage;
+ temp.replace(QStringLiteral("SD printing byte"), QString());
+ qlonglong total = temp.mid(temp.lastIndexOf(QChar::fromLatin1('/')) + 1, temp.length() - temp.lastIndexOf(QChar::fromLatin1('/'))).toLongLong();
+ if (total) {
+ temp.chop(temp.length() - temp.lastIndexOf(QChar::fromLatin1('/')));
+ qlonglong remaining = total - temp.toLongLong();
+ float progress = float(total - remaining) * 100 / float(total);
+ core()->printProgressChanged(progress);
+ 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/testclient/mainwindow.h b/testclient/mainwindow.h
--- a/testclient/mainwindow.h
+++ b/testclient/mainwindow.h
@@ -131,6 +131,10 @@
*/
void printPBClicked();
+ /**
+ * @brief Print Button for Sd Prints clicked.
+ */
+ void sdPrintPBClicked();
/**
* @brief Save the log file.
*/
@@ -176,12 +180,24 @@
* @brief Show the about dialog
*/
void about();
+
+ /**
+ * @brief List Files on the sd card.
+ */
+ void getSdList();
+
+ /**
+ * @brief Sd Card Delete file clicked
+ */
+ void sdDelPBClicked();
+
signals:
/**
* @brief printFile emit ready to print a file to atcore
* @param fileName : the file to print
+ * @param sdPrint : True if file is on printers Sd Card
*/
- void printFile(const QString &fileName);
+ void printFile(const QString &fileName, bool sdPrint = false);
private:
Ui::MainWindow *ui;
@@ -269,4 +285,9 @@
* @brief Populate comboboxes
*/
void populateCBs();
+
+ /**
+ * @brief Gui Changes for when sd card mount status has changed.
+ */
+ void sdChanged(bool mounted);
};
diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp
--- a/testclient/mainwindow.cpp
+++ b/testclient/mainwindow.cpp
@@ -90,18 +90,27 @@
connect(ui->mvAxisPB, &QPushButton::clicked, this, &MainWindow::mvAxisPBClicked);
connect(ui->fanSpeedPB, &QPushButton::clicked, this, &MainWindow::fanSpeedPBClicked);
connect(ui->printPB, &QPushButton::clicked, this, &MainWindow::printPBClicked);
+ connect(ui->sdPrintPB, &QPushButton::clicked, this, &MainWindow::sdPrintPBClicked);
+ connect(ui->sdDelPB, &QPushButton::clicked, this, &MainWindow::sdDelPBClicked);
connect(ui->printerSpeedPB, &QPushButton::clicked, this, &MainWindow::printerSpeedPBClicked);
connect(ui->flowRatePB, &QPushButton::clicked, this, &MainWindow::flowRatePBClicked);
connect(ui->showMessagePB, &QPushButton::clicked, this, &MainWindow::showMessage);
connect(ui->pluginCB, &QComboBox::currentTextChanged, this, &MainWindow::pluginCBChanged);
connect(ui->disableMotorsPB, &QPushButton::clicked, this, &MainWindow::disableMotorsPBClicked);
+ connect(ui->sdListPB, &QPushButton::clicked, this, &MainWindow::getSdList);
connect(core, &AtCore::stateChanged, this, &MainWindow::printerStateChanged);
connect(this, &MainWindow::printFile, core, &AtCore::print);
connect(ui->stopPB, &QPushButton::clicked, core, &AtCore::stop);
connect(ui->emergencyStopPB, &QPushButton::clicked, core, &AtCore::emergencyStop);
connect(axisControl, &AxisControl::clicked, this, &MainWindow::axisControlClicked);
connect(core, &AtCore::portsChanged, this, &MainWindow::locateSerialPort);
connect(core, &AtCore::printProgressChanged, this, &MainWindow::printProgressChanged);
+ connect(core, &AtCore::sdMountChanged, this, &MainWindow::sdChanged);
+
+ connect(core, &AtCore::sdCardFileListChanged, [this](QStringList fileList) {
+ ui->sdFileListView->clear();
+ ui->sdFileListView->addItems(fileList);
+ });
connect(&core->temperature(), &Temperature::bedTemperatureChanged, [ this ](float temp) {
checkTemperature(0x00, 0, temp);
@@ -135,11 +144,13 @@
ui->menuView->insertAction(nullptr, ui->moveDock->toggleViewAction());
ui->menuView->insertAction(nullptr, ui->tempTimelineDock->toggleViewAction());
ui->menuView->insertAction(nullptr, ui->logDock->toggleViewAction());
+ ui->menuView->insertAction(nullptr, ui->sdDock->toggleViewAction());
//more dock stuff.
setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North);
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North);
tabifyDockWidget(ui->moveDock, ui->tempControlsDock);
+ tabifyDockWidget(ui->moveDock, ui->sdDock);
ui->moveDock->raise();
tabifyDockWidget(ui->connectDock, ui->printDock);
@@ -488,14 +499,16 @@
ui->moveDock->setDisabled(true);
ui->tempControlsDock->setDisabled(true);
ui->printDock->setDisabled(true);
+ ui->sdDock->setDisabled(true);
break;
case AtCore::CONNECTING:
stateString = QStringLiteral("Connecting");
ui->commandDock->setDisabled(false);
ui->moveDock->setDisabled(false);
ui->tempControlsDock->setDisabled(false);
ui->printDock->setDisabled(false);
+ ui->sdDock->setDisabled(false);
break;
case AtCore::STOP:
@@ -553,14 +566,16 @@
delete ui->moveDock->titleBarWidget();
delete ui->tempControlsDock->titleBarWidget();
delete ui->printDock->titleBarWidget();
+ delete ui->sdDock->titleBarWidget();
} else {
ui->connectDock->setTitleBarWidget(new QWidget());
ui->logDock->setTitleBarWidget(new QWidget());
ui->tempTimelineDock->setTitleBarWidget(new QWidget());
ui->commandDock->setTitleBarWidget(new QWidget());
ui->moveDock->setTitleBarWidget(new QWidget());
ui->tempControlsDock->setTitleBarWidget(new QWidget());
ui->printDock->setTitleBarWidget(new QWidget());
+ ui->sdDock->setTitleBarWidget(new QWidget());
}
}
@@ -581,3 +596,33 @@
{
core->setIdleHold(0);
}
+
+void MainWindow::sdChanged(bool mounted)
+{
+ QString labelText = mounted ? QStringLiteral("SD") : QString();
+ ui->lbl_sd->setText(labelText);
+}
+
+void MainWindow::getSdList()
+{
+ core->sdFileList();
+}
+
+void MainWindow::sdPrintPBClicked()
+{
+ if (ui->sdFileListView->currentRow() < 0) {
+ QMessageBox::information(this, QStringLiteral("Print Error"), QStringLiteral("You must Select a file from the list"));
+ } else {
+ core->print(ui->sdFileListView->currentItem()->text(), true);
+ }
+}
+
+void MainWindow::sdDelPBClicked()
+{
+ if (ui->sdFileListView->currentRow() < 0) {
+ QMessageBox::information(this, QStringLiteral("Delete Error"), QStringLiteral("You must Select a file from the list"));
+ } else {
+ core->sdDelete(ui->sdFileListView->currentItem()->text());
+ ui->sdFileListView->setCurrentRow(-1);
+ }
+}
diff --git a/testclient/mainwindow.ui b/testclient/mainwindow.ui
--- a/testclient/mainwindow.ui
+++ b/testclient/mainwindow.ui
@@ -56,6 +56,41 @@
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+
+
+
+
+
+
-
@@ -380,6 +415,71 @@
+
+
+ false
+
+
+
+ 0
+ 42
+ 515
+ 317
+
+
+
+ S&d Card
+
+
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Get List
+
+
+
+ -
+
+
+ Print Selected
+
+
+
+ -
+
+
+ Delete Selected
+
+
+
+
+
+
+ -
+
+
+ Files On Sd Card.
+
+
+
-
+
+
+
+
+
+
+
+
diff --git a/unittests/gcodetests.h b/unittests/gcodetests.h
--- a/unittests/gcodetests.h
+++ b/unittests/gcodetests.h
@@ -35,6 +35,17 @@
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();
diff --git a/unittests/gcodetests.cpp b/unittests/gcodetests.cpp
--- a/unittests/gcodetests.cpp
+++ b/unittests/gcodetests.cpp
@@ -68,6 +68,70 @@
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"));