#include "main.h" #include "mainwindow.h" #include "deviceitem.h" #include "gutil/qnetwork.h" #include #include #include #include #include #include #include #if(QT_VERSION_MAJOR > 5) #include #endif const QString UpdVerUrl = "https://www.ledok.cn/download/LedOK Express Updates.json"; QString programsDir() { static auto rtn = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/programs"; return rtn; } #ifdef _MSC_VER //MSVC编译器 #include #include LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) { auto errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16); auto errAddr = QString::number((uint)excep->ExceptionRecord->ExceptionAddress, 16); auto hDumpFile = CreateFile(L"ledok-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hDumpFile == INVALID_HANDLE_VALUE) { qCritical()<<"CreateFile ledok-crash.dmp Failed! ExceptionCode"<程序出错!
请将安装目录下的 ledok-crash.dmp 文件发送到 gangphon@qq.com 邮箱, 研发人员会尽快处理."); return EXCEPTION_EXECUTE_HANDLER; // EXCEPTION_EXECUTE_HANDLER 已处理异常, 让 windows 正常结束 // EXCEPTION_CONTINUE_SEARCH 未处理异常, 让 windows 弹出错误框并结束 (Qt会卡死一段时间) // EXCEPTION_CONTINUE_EXECUTION 已修复错误, 让 windows 从异常发生处继续执行 } #endif int main(int argc, char *argv[]) { #if(QT_VERSION_MAJOR > 5) QImageReader::setAllocationLimit(0); #else QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif QApplication::setOrganizationName("Sysolution"); QApplication::setOrganizationDomain("ledok.cn"); QApplication::setApplicationName("LedOK Express"); QApplication::setStyle("Fusion"); QApplication a(argc, argv); QSplashScreen splash(QPixmap(":/res/splash.png")); splash.show(); splash.showMessage(QObject::tr("Setting up the LedOK Express..."), Qt::AlignRight | Qt::AlignTop, Qt::white); QFile file(":/css.css"); if(file.exists() && file.open(QFile::ReadOnly)) { a.setStyleSheet(file.readAll()); file.close(); } QFont font; font.setFamilies(QStringList{"Arial","PingFang SC","Hiragino Sans GB","STHeiti","Microsoft YaHei","WenQuanYi Micro Hei","sans-serif"}); a.setFont(font); auto plt = a.palette(); plt.setBrush(QPalette::AlternateBase, plt.brush(QPalette::Active, QPalette::Window)); plt.setBrush(QPalette::Inactive, QPalette::Highlight, plt.brush(QPalette::Active, QPalette::Highlight)); plt.setBrush(QPalette::Inactive, QPalette::HighlightedText, plt.brush(QPalette::Active, QPalette::HighlightedText)); a.setPalette(plt); QTranslator qtTrans; if(qtTrans.load(QLocale(), "qt", "_", "translations")) QCoreApplication::installTranslator(&qtTrans); gFileHome = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); #ifdef _MSC_VER SetUnhandledExceptionFilter(handleException); #endif MainWindow w; w.show(); splash.finish(&w); return a.exec(); } QString gFileHome; QList gSelCards; DeviceItem *findItem(QString id) { int cnt = gDevicePanel->mDeviceTable->topLevelItemCount(); for(int i=0; imDeviceTable->topLevelItem(i); if(item==0) continue; if(item->mCard.id==id) return item; } return 0; } QString checkReply(QNetworkReply *reply, QJsonDocument *outJson) { auto err = errStr(reply); if(! err.isEmpty()) { auto data = reply->readAll(); if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; return err; } if(outJson) { auto data = reply->readAll(); QJsonParseError jsonErr; *outJson = QJsonDocument::fromJson(data, &jsonErr); if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; } return ""; } QString errStrWithJson(QNetworkReply *reply, JValue *outJson, QByteArray *outData) { auto err = errStr(reply); auto data = reply->readAll(); if(outData) *outData = data; if(! err.isEmpty()) { if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; return err; } QString error; auto json = JFrom(data, &error); if(! error.isEmpty()) return "JSON Error: "+error+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+data; if(outJson) *outJson = json; return ""; } QString checkReplyForJson(QNetworkReply *reply, QJsonDocument *outJson, QByteArray *outData) { auto err = errStr(reply); auto data = reply->readAll(); if(outData) *outData = data; if(! err.isEmpty()) { if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; return err; } QJsonParseError jsonErr; QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+data; if(outJson) outJson->swap(json); return ""; } QString checkReplyForJson(QNetworkReply *reply, QString errField) { auto err = errStr(reply); auto data = reply->readAll(); if(! err.isEmpty()) { if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; return err; } QJsonParseError jsonErr; QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; if(! json["success"].toBool()) { auto errStr = json[errField].toString(); return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+(errStr.isEmpty() ? data : errStr); } return ""; } quint64 dirFileSize(const QString &path) { QDir dir(path); quint64 size = 0; auto infos = dir.entryInfoList(QDir::Files); foreach(QFileInfo fileInfo, infos) size += fileInfo.size(); auto subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); foreach(QString subDir, subDirs) size += dirFileSize(path + QDir::separator() + subDir); return size; } bool copyDir(const QString &source, const QString &destination, bool override) { QDir directory(source); if(!directory.exists()) return false; QString srcPath = QDir::toNativeSeparators(source); if(!srcPath.endsWith(QDir::separator())) srcPath += QDir::separator(); QString dstPath = QDir::toNativeSeparators(destination); if (!dstPath.endsWith(QDir::separator())) dstPath += QDir::separator(); bool error = false; QStringList fileNames = directory.entryList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden); for (QStringList::size_type i=0; i != fileNames.size(); ++i) { QString fileName = fileNames.at(i); QString srcFilePath = srcPath + fileName; QString dstFilePath = dstPath + fileName; QFileInfo fileInfo(srcFilePath); if (fileInfo.isFile() || fileInfo.isSymLink()) { if (override) { QFile::setPermissions(dstFilePath, QFile::WriteOwner); } QFile::copy(srcFilePath, dstFilePath); } else if (fileInfo.isDir()) { QDir dstDir(dstFilePath); dstDir.mkpath(dstFilePath); if (!copyDir(srcFilePath, dstFilePath, override)) { error = true; } } } return !error; } unsigned char GetCheckCodeIn8(unsigned char *str, unsigned int size) { unsigned char checkCode = 0; for(int i=0; itextCursor(); if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeCharFormat(fmt); } Tick::Tick(QWidget *parent) : QOpenGLWidget(parent) { setGeometry(0, 0, 1, 1); connect(this, &QOpenGLWidget::frameSwapped, this, &Tick::doFrame); } void Tick::doFrame() { auto cur = QDateTime::currentDateTime(); auto secs = cur.toSecsSinceEpoch(); if(secs != Sec) { Sec = secs; emit secChanged(cur); } update(); }