File indexing completed on 2024-05-12 04:41:11
0001 /* AtCore KDE Libary for 3D Printers 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2016-2020 Chris Rizzitello <rizzitello@kde.org> 0004 SPDX-FileCopyrightText: 2018 Patrick José Pereira <patrickjp@kde.org> 0005 */ 0006 0007 #include "logwidget.h" 0008 0009 #include <QFileDialog> 0010 #include <QPlainTextEdit> 0011 #include <QPushButton> 0012 #include <QStackedWidget> 0013 #include <QStyle> 0014 #include <QTemporaryFile> 0015 #include <QTime> 0016 #include <QToolButton> 0017 #include <QVBoxLayout> 0018 0019 namespace 0020 { 0021 static constexpr QChar _newLine = QChar::fromLatin1('\n'); 0022 static constexpr QChar _return = QChar::fromLatin1('\r'); 0023 } 0024 0025 LogWidget::LogWidget(QWidget *parent) 0026 : QWidget(parent) 0027 { 0028 logFile = new QTemporaryFile(); 0029 0030 initialize(); 0031 } 0032 0033 LogWidget::LogWidget(QTemporaryFile *tempFile, QWidget *parent) 0034 : QWidget(parent) 0035 , logFile(tempFile) 0036 { 0037 if (!logFile) { 0038 logFile = new QTemporaryFile(); 0039 } 0040 0041 initialize(); 0042 } 0043 0044 void LogWidget::initialize() 0045 { 0046 QSize iconSize = QSize(fontMetrics().height(), fontMetrics().height()); 0047 auto page = new QWidget(this); 0048 textLog = new QPlainTextEdit(this); 0049 textLog->setReadOnly(true); 0050 textLog->setMaximumBlockCount(1000); 0051 auto pageLayout = new QVBoxLayout; 0052 pageLayout->addWidget(textLog); 0053 page->setLayout(pageLayout); 0054 0055 auto mainStack = new QStackedWidget(this); 0056 mainStack->insertWidget(0, page); 0057 0058 page = new QWidget(this); 0059 auto textbox = new QTextEdit(this); 0060 textbox->setReadOnly(true); 0061 textbox->setHtml( 0062 tr("\ 0063 <h4>Special Log Entries</h4> \ 0064 <p><strong>Failed to open device in read/write mode.</strong></p> \ 0065 <p> The Device was not able to be opened.</p> \ 0066 <p> Check the device is not opened by another program.</p> \ 0067 <p> Check you have the correct permissions to open the device.</p> \ 0068 <p><strong>No plugin found for <Detected Firmware></strong></p> \ 0069 <p> Firmware plugins are missing or your firmware is not currently supported.</p> \ 0070 <p> Manually select the Marlin or Repetier plugin.</p> \ 0071 <p> If your firmware does not have a plugin please let us know.</p> \ 0072 <p><strong>Lots of “Waiting for firmware detect”</strong></p> \ 0073 <p> Unable to send the firmware detect waiting for printer to restart</p> \ 0074 <p> Push the restart button on your printer or turn it on and off. </p> \ 0075 <p> Select a firmware plugin in place of auto detect.</p>")); 0076 pageLayout = new QVBoxLayout; 0077 pageLayout->addWidget(textbox); 0078 page->setLayout(pageLayout); 0079 mainStack->insertWidget(1, page); 0080 0081 auto saveButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-save"), style()->standardIcon(QStyle::SP_DialogSaveButton)), tr("Save Session Log"), this); 0082 saveButton->setIconSize(iconSize); 0083 connect(saveButton, &QPushButton::clicked, this, &LogWidget::savePressed); 0084 0085 auto helpButton = new QToolButton(this); 0086 helpButton->setCheckable(true); 0087 helpButton->setChecked(false); 0088 helpButton->setIconSize(iconSize); 0089 helpButton->setIcon(QIcon::fromTheme(QStringLiteral("help-about"), style()->standardIcon(QStyle::SP_DialogHelpButton))); 0090 connect(helpButton, &QToolButton::clicked, this, [mainStack](bool checked) { mainStack->setCurrentIndex(checked); }); 0091 0092 auto buttonLayout = new QHBoxLayout; 0093 buttonLayout->addWidget(saveButton); 0094 buttonLayout->addWidget(helpButton); 0095 0096 auto mainLayout = new QVBoxLayout; 0097 mainLayout->addWidget(mainStack); 0098 mainLayout->addLayout(buttonLayout); 0099 setLayout(mainLayout); 0100 } 0101 0102 QString LogWidget::getTime() 0103 { 0104 return QTime::currentTime().toString(QStringLiteral("hh:mm:ss:zzz")); 0105 } 0106 0107 void LogWidget::appendLog(const QString &msg) 0108 { 0109 QString message(QStringLiteral("[%1] %2").arg(getTime(), msg)); 0110 textLog->appendPlainText(message); 0111 writeTempFile(message); 0112 } 0113 0114 void LogWidget::appendRLog(const QByteArray &bmsg) 0115 { 0116 QString message(QStringLiteral("[%1]< %2").arg(getTime(), QString::fromUtf8(bmsg))); 0117 textLog->appendPlainText(message); 0118 writeTempFile(message); 0119 } 0120 0121 void LogWidget::appendSLog(const QByteArray &bmsg) 0122 { 0123 QString msg = QString::fromUtf8(bmsg); 0124 msg.replace(_newLine, QStringLiteral("\\n")); 0125 msg.replace(_return, QStringLiteral("\\r")); 0126 QString message(QStringLiteral("[%1]> %2").arg(getTime(), msg)); 0127 textLog->appendPlainText(message); 0128 writeTempFile(message); 0129 } 0130 0131 void LogWidget::writeTempFile(const QString &text) 0132 { 0133 // Add text to our unsynced string list when that hits 100 sync to the temp file. 0134 unsyncedStrings.append(text); 0135 if (unsyncedStrings.count() > 100) { 0136 flushTemp(); 0137 } 0138 } 0139 0140 void LogWidget::flushTemp() 0141 { 0142 /* 0143 A QTemporaryFile will always be opened in QIODevice::ReadWrite mode, 0144 this allows easy access to the data in the file. This function will 0145 return true upon success and will set the fileName() to the unique 0146 filename used. 0147 */ 0148 logFile->open(); 0149 logFile->seek(logFile->size()); 0150 for (const auto &string : qAsConst(unsyncedStrings)) { 0151 logFile->write(string.toLatin1()); 0152 logFile->putChar('\n'); 0153 } 0154 logFile->close(); 0155 unsyncedStrings.clear(); 0156 } 0157 0158 void LogWidget::savePressed() 0159 { 0160 // If saving be sure we have flushed to temp. 0161 flushTemp(); 0162 // Note that if a file with the name newName already exists, copy() returns false (i.e. QFile will not overwrite it). 0163 QString fileName = QDir::homePath() + QChar::fromLatin1('/') + QFileInfo(logFile->fileName()).fileName() + QStringLiteral(".txt"); 0164 QString saveFileName = QFileDialog::getSaveFileName(this, tr("Save Log to file"), fileName); 0165 QFile::copy(logFile->fileName(), saveFileName); 0166 logFile->close(); 0167 } 0168 0169 bool LogWidget::endsWith(const QString &string) 0170 { 0171 return textLog->toPlainText().endsWith(string); 0172 }