diff --git a/CMakeLists.txt b/CMakeLists.txt index 406be00..5e52359 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.11) -project(qtdmm VERSION "1.0.0" HOMEPAGE_URL "https://github.com/tuxmaster/QtDMM/" LANGUAGES CXX) +project(qtdmm VERSION "0.0.0" HOMEPAGE_URL "https://github.com/tuxmaster/QtDMM/" LANGUAGES CXX) ## main settings set(CMAKE_CXX_STANDARD 17) @@ -11,6 +11,7 @@ set(APP_NAME "QtDMM") set(APP_ORGANIZATION "QtDMM") set(QT_COMPONENTS Widgets SerialPort PrintSupport Test LinguistTools Network) +include( cmake/git_version.cmake ) ## get files file(GLOB TRANSLATIONS CONFIGURE_DEPENDS assets/translations/${PROJECT_NAME}_*.ts) diff --git a/QtDMM.spec b/QtDMM.spec index 993a4dc..e49bc25 100644 --- a/QtDMM.spec +++ b/QtDMM.spec @@ -1,5 +1,5 @@ Name: qtdmm -Version: 1.0.0 +Version: 1.0.0-alpha.1+dc7490a Release: 1%{?dist} Summary: DMM Readout Software Including a Configurable Recorder. diff --git a/assets/translations/qtdmm_de.ts b/assets/translations/qtdmm_de.ts index aa6bb93..7bd3554 100644 --- a/assets/translations/qtdmm_de.ts +++ b/assets/translations/qtdmm_de.ts @@ -4,24 +4,24 @@ ConfigDlg - - - + + + QtDMM: Welcome! QtDMM: Willkommen! - + <font size=+2><b>Welcome!</b></font><p>This seems to be your first invocation of QtDMM (Or you have deleted its configuration file).<p>QtDMM has created the file %1 in your home directory to save its settings. <font size+2><b>Willkommen!</b></font><p>Dies scheint der erste Aufruf von QtDMM zu sein, bzw. die Konfigurstion wurde gelöscht.<p>QtDMM hate eine neue Datei unter dem Pfad %1 angelegt. - + <font size=+2><b>Welcome!</b></font><p>You seem to have upgraded <b>QtDMM</b> from a version prior to 0.8.4. Please check your configuration. There are some new parameters to be configured.<p>Thank you for choosing <b>QtDMM</b>.<p><i>Matthias Toussaint</i> <font size=+2><b>Willkommen!</b><p>Wie es ausschaut, wurde <b>QtDMM</b> von einer Version vor 0.8.4 aktualisiert. Bitte überprüfen Sie die Konfiguration. Es gibt einige neue Parameter.<p>Danke das Sie <b>QtDMM</b> benutzen.<p><i>Matthias Toussaint</i> - + Your config file has been converted to the new format. Please check your color settings, because they couldn't be converted automatically. Your old config ~/.qtdmmrc was renamed to ~/.qtdmmrc.old. @@ -34,8 +34,8 @@ Die Datei ~/.qtdmmtc wurden zu ~/.qtdmmrc.old umbenannt. <font size+2><b>Willkommen!</b></font><p>Dies scheint der erste Aufruf von QtDMM zu sein, bzw. die Konfigurstion wurde gelöscht.<p>QtDMM hate eine neue Datei unter dem Pfad %1 angelegt. - - + + Continue Fortsetzen @@ -488,12 +488,12 @@ Ist das DMM angeschlossen und eingeschaltet? MainWin - + QtDMM: Welcome! QtDMM: Willkommen! - + <h1>QtDMM %1</h1><hr><div align=right><i>A simple recorder for DMM's</i></div><p><div align=justify>A simple display software for a variety of digital multimeter. Currently confirmed are:<table>%2</table>Other compatible models may work also.<p>QtDMM features min/max memory and a configurable recorder with import/export and printing function. Sampling may be started manually, at a given time or triggered by a measured threshold. Additionally an external program may be started when given thresholds are reached.</div><div align=justify><b>QtDMM</b> uses the platform independent toolkit <b>Qt</b> version %3 and is licensed under <b>GPL 3</b> (Versions prior to v0.9.0 where licensed under GPL 2)</div><br>&copy; 2001-2014 Matthias Toussaint &nbsp;-&nbsp;&nbsp;<font color=blue><u><a href='mailto:qtdmm@mtoussaint.de'>qtdmm@mtoussaint.de</a></u></font><p><br>The icons (except the DMM icon) have been taken from the KDE project.<p> <h1>QtDMM %1</h1><hr><div align=right><i>Ein einfacher Datenrekorder für DMM</i></div><p><div align=justify>Ein einfaches Anzeigeprogramm für eine Vielzahl von DMM's. Aktuell bestätigt sind:<table>%2</table>Andere kompatible Modelle sollten ebenfalls funktionieren.<p>QtDMM stellt die Funktionen Min/Max Werte halten, ein konfigurierbaren Datenrekorder mit Daten im/export Funktion sowie ein Druckfunktion zur Verfügung. Die Datenaufzeichnung kann manuell, durch einen Grenzwert oder durch eine Zeitfunktion ausgelöst werden. Desweiteren kann ein externes Programm beim erreichen eines Grenzwertes gestartet werden.</div><div align=justify><b>QtDMM</b> wurde mit der Platformunabhängigen <b>Qt</b> Bibliothek in der Version %3 welche unter der <b>GPLv3</b> lizensiert ist erstellt.(Versionen vor 0.9.0 wurden unter der GPLv2 Lizenz veröffentlicht)</div><br>&copy; 2001-2014 Matthias Toussaint &nbsp;-&nbsp;&nbsp;<font color=blue><u><a href='mailto:qtdmm@mtoussaint.de'>qtdmm@mtoussaint.de</a></u></font><p><br>Die Symbole (bis auf das DMM Symbol) stammen von dem KDE Projekt.<p> @@ -527,12 +527,27 @@ Ist das DMM angeschlossen und eingeschaltet? QObject - + + protocol debugging information + Protokol debugging Informationen + + + + sets directory where config files are located + setzt das Verzeichnis wo die Konfiguration sich befindet + + + + sets <config-id> + setzt die <config-id> + + + Missing Permission Berechtigung fehlt - + The current user is not a member of the 'dialout' group. Please add the user with the following command: diff --git a/cmake/git_version.cmake b/cmake/git_version.cmake new file mode 100644 index 0000000..594f9c2 --- /dev/null +++ b/cmake/git_version.cmake @@ -0,0 +1,49 @@ +# get version +function(get_version_from_git) + find_package(Git QUIET) + if(NOT Git_FOUND) + message(WARNING "Git not found") + return() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --always + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GIT_RESULT + ) + + if(NOT GIT_RESULT EQUAL 0) + message(WARNING "Failed to get git tag") + return() + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short=7 HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_SHORT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + string(REGEX REPLACE "^v" "" CLEAN_TAG "${GIT_TAG}") + if(CLEAN_TAG MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-.*)?$") + + set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} PARENT_SCOPE) + set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_2}) + set(PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR} PARENT_SCOPE) + set(PROJECT_VERSION_PATCH "${CMAKE_MATCH_3}${CMAKE_MATCH_4}+${GIT_COMMIT_SHORT_HASH}") + set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE) + + set(FULL_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}" ) + set(FULL_VERSION "${FULL_VERSION}" PARENT_SCOPE) + set(PROJECT_VERSION "${FULL_VERSION}") + set(PROJECT_VERSION "${FULL_VERSION}" PARENT_SCOPE) + message( STATUS "QtDMM version: ${FULL_VERSION}" ) + else() + message(WARNING "Tag '${CLEAN_TAG}' does not match semver format") + endif() +endfunction() + +get_version_from_git() diff --git a/src/configdlg.cpp b/src/configdlg.cpp index d753623..a671dc6 100644 --- a/src/configdlg.cpp +++ b/src/configdlg.cpp @@ -39,14 +39,12 @@ #include -ConfigDlg::ConfigDlg(QWidget *parent) : QDialog(parent) +ConfigDlg::ConfigDlg(QString session_id, QString config_path, QWidget *parent) : QDialog(parent) { m_buttonBox_OK = false; setupUi(this); - QString path = QString("%1/.qtdmmrc").arg(QDir::homePath()); - - m_settings = new Settings(this, path); + m_settings = new Settings(this, session_id, config_path); // Check if configuration file exists. If not welcome user diff --git a/src/configdlg.h b/src/configdlg.h index 6c1bf8b..e2baae4 100644 --- a/src/configdlg.h +++ b/src/configdlg.h @@ -57,7 +57,7 @@ class ConfigDlg : public QDialog, private Ui::UIConfigDlg NumItems, }; - ConfigDlg(QWidget *parent = Q_NULLPTR); + ConfigDlg(QString session_id, QString config_path, QWidget *parent = Q_NULLPTR); Settings *getSettings() { return m_settings; } QString device() const; int speed() const; diff --git a/src/main.cpp b/src/main.cpp index 7b076f4..2e861ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,23 +28,23 @@ #include "mainwin.h" -#ifdef Q_OS_LINUX -bool userInGroup(const char* groupname) +void checkUserInDailOutGroup() { +#ifdef Q_OS_LINUX + const char* groupname = "dialout"; struct passwd* pw = getpwuid(geteuid()); - if (!pw) return false; + if (!pw) return; // check not applicable gid_t* groups; int ngroups = 0; - // Erste Abfrage, um die Anzahl der Gruppen zu bekommen getgrouplist(pw->pw_name, pw->pw_gid, nullptr, &ngroups); groups = new gid_t[ngroups]; if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) { delete[] groups; - return false; + return; // cannot get groups } for (int i = 0; i < ngroups; ++i) @@ -53,16 +53,22 @@ bool userInGroup(const char* groupname) if (gr && strcmp(gr->gr_name, groupname) == 0) { delete[] groups; - return true; + return; // ok } } delete[] groups; - return false; -} + QMessageBox::critical(nullptr, QObject::tr("Missing Permission"), + QObject::tr("The current user is not a member of the 'dialout' group.\n" + "Please add the user with the following command:\n\n" + "sudo usermod -aG dialout $USER\n\n" + "You need to log out and back in for the changes to take effect.")); + #endif +} + -void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg) +void qtdmmMessageOutput(QtMsgType type, const QMessageLogContext &, const QString &msg) { switch (type) { @@ -88,62 +94,47 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &, const QString & } } -void printHelp() + +void initTranslation(QApplication *app,QTranslator *QtTranslation, QTranslator *AppTranslation) { - std::cerr << "Usage: qtdmm [--help|--debug|--print]" << std::endl; - std::cerr << " --help : print this message" << std::endl; - std::cerr << " --debug : protocoll debugging information" << std::endl; - std::cerr << " --print : send DMM reading to standard output" << std::endl; - exit(0); -} + if (QtTranslation->load(QString("qt_%1").arg(QLocale::system().name()), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) + app->installTranslator(QtTranslation); + else + qWarning() << "Could not load Qt translation!"; + if (AppTranslation->load(QString("%1").arg(QLocale::system().name()), ":/Translations")) // + app->installTranslator(AppTranslation); + else + qWarning() << "Could not load App translation!"; +} int main(int argc, char **argv) { - qInstallMessageHandler(myMessageOutput); + qInstallMessageHandler(qtdmmMessageOutput); QApplication app(argc, argv); + QTranslator QtTranslation; + QTranslator AppTranslation; + QCommandLineParser parser; app.setApplicationName(APP_NAME); app.setApplicationVersion(APP_VERSION); app.setOrganizationName(APP_ORGANIZATION); - // translation - QTranslator QtTranslation; - if (QtTranslation.load(QString("qt_%1").arg(QLocale::system().name()), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) - app.installTranslator(&QtTranslation); - else - qWarning() << "Could not load Qt translation!"; - - QTranslator AppTranslation; - if (AppTranslation.load(QString("%1").arg(QLocale::system().name()), ":/Translations")) // - app.installTranslator(&AppTranslation); - else - qWarning() << "Could not load App translation!"; - - MainWin mainWin; + initTranslation(&app,&QtTranslation,&AppTranslation); - QCommandLineParser parser; - parser.addOption(QCommandLineOption("debug")); - parser.addOption(QCommandLineOption("help")); - parser.addOption(QCommandLineOption("print")); + parser.addOption({"debug", QObject::tr("protocol debugging information")}); + parser.addOption({"config-dir",QObject::tr("sets directory where config files are located"), "config-dir"}); + parser.addOption({"config-id",QObject::tr("sets "), "config-id"}); + parser.addHelpOption(); + parser.addVersionOption(); parser.process(app); - if (parser.isSet("debug")) - mainWin.setConsoleLogging(true); - + MainWin mainWin(parser); mainWin.show(); mainWin.move(100, 100); -#ifdef Q_OS_LINUX - if (!userInGroup("dialout")) { - QMessageBox::critical(nullptr, QObject::tr("Missing Permission"), - QObject::tr("The current user is not a member of the 'dialout' group.\n" - "Please add the user with the following command:\n\n" - "sudo usermod -aG dialout $USER\n\n" - "You need to log out and back in for the changes to take effect.")); - } -#endif + checkUserInDailOutGroup(); return app.exec(); } diff --git a/src/mainwid.cpp b/src/mainwid.cpp index b17526d..b68f8c0 100644 --- a/src/mainwid.cpp +++ b/src/mainwid.cpp @@ -32,7 +32,7 @@ #include "displaywid.h" #include "tipdlg.h" -MainWid::MainWid(QWidget *parent) : QFrame(parent), +MainWid::MainWid(QString session_id, QString config_path, QWidget *parent) : QFrame(parent), m_display(0), m_tipDlg(0) { @@ -42,7 +42,7 @@ MainWid::MainWid(QWidget *parent) : QFrame(parent), m_dmm = new DMM(this); m_external = new QProcess(this); - m_configDlg = new ConfigDlg(this); + m_configDlg = new ConfigDlg(session_id, config_path, this); m_configDlg->hide(); m_configDlg->readPrinter(&m_printer); diff --git a/src/mainwid.h b/src/mainwid.h index 4b8022b..0071018 100644 --- a/src/mainwid.h +++ b/src/mainwid.h @@ -39,7 +39,7 @@ class MainWid : public QFrame, private Ui::UIMainWid { Q_OBJECT public: - MainWid(QWidget *parent = Q_NULLPTR); + MainWid(QString session_id, QString config_path, QWidget *parent = Q_NULLPTR); bool closeWin(); QRect winRect() const; bool saveWindowPosition() const; diff --git a/src/mainwin.cpp b/src/mainwin.cpp index 032ec6a..9c0368c 100644 --- a/src/mainwin.cpp +++ b/src/mainwin.cpp @@ -30,7 +30,7 @@ #include "displaywid.h" -MainWin::MainWin(QWidget *parent) +MainWin::MainWin(QCommandLineParser &parser, QWidget *parent) : QMainWindow(parent) , m_running(false) , m_menu(Q_NULLPTR) @@ -42,9 +42,16 @@ MainWin::MainWin(QWidget *parent) spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); this->toolBarMenu->addWidget(spacer); this->toolBarMenu->addAction(this->action_Menu); + QString config_id = parser.value("config-id"); + QString version = APP_VERSION; + int plusIndex = version.indexOf('+'); + if (plusIndex != -1) + version = version.left(plusIndex); - m_wid = new MainWid(this); + + m_wid = new MainWid(config_id, parser.value("config-dir"), this); setCentralWidget(m_wid); + setConsoleLogging(parser.isSet("debug")); createActions(); @@ -52,7 +59,7 @@ MainWin::MainWin(QWidget *parent) toolBarDisplay->addWidget(m_display); m_wid->setDisplay(m_display); - setWindowTitle(QString("%1 %2").arg(APP_NAME).arg(APP_VERSION)); + setWindowTitle(QString("%1 %2 %3").arg(APP_NAME).arg(version).arg(config_id)); connect(m_wid, SIGNAL(running(bool)), this, SLOT(runningSLOT(bool))); diff --git a/src/mainwin.h b/src/mainwin.h index cc50546..8f8fd7e 100644 --- a/src/mainwin.h +++ b/src/mainwin.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "ui_uimainwin.h" @@ -36,7 +37,7 @@ class MainWin : public QMainWindow, private Ui::UIMainWin { Q_OBJECT public: - MainWin(QWidget *parent = Q_NULLPTR); + MainWin(QCommandLineParser &parser, QWidget *parent = Q_NULLPTR); void setConsoleLogging(bool); protected Q_SLOTS: diff --git a/src/settings.cpp b/src/settings.cpp index d868a85..0a8f283 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -17,6 +17,8 @@ #include "settings.h" +#include + Settings::Settings(QObject *parent) : QObject(parent) { m_fileConverted = false; @@ -26,32 +28,36 @@ Settings::Settings(QObject *parent) : QObject(parent) m_tmpConfig = new QHash; m_filename = m_qsettings->fileName(); } + Settings::~Settings() { delete m_tmpConfig; } -Settings::Settings(QObject *parent, const QString &fileName) : Settings(parent) + +Settings::Settings(QObject *parent, const QString &session_id, const QString &config_path) : Settings(parent) { - QFile file(fileName); - if (file.exists()) + if (!session_id.isEmpty()) { - QSettings *old = new QSettings(fileName, QSettings::IniFormat, this); - //migrate - for (auto name : old->allKeys()) - m_qsettings->setValue(name, old->value(name)); - old->deleteLater(); - m_fileExists = true; - //rename old config file - if (QFile::exists(QString("%1.old").arg(fileName))) - QFile::remove(QString("%1.old").arg(fileName)); - file.rename(QString("%1.old").arg(fileName)); - m_fileConverted = true; + QSettings qsettings(this); + QFileInfo fileInfo(qsettings.fileName()); + QString fileDir = config_path.isEmpty() ? fileInfo.absolutePath() : config_path; + + QString session_fileName = fileDir+"/"+fileInfo.baseName()+"_"+session_id+"."+fileInfo.suffix(); + delete m_qsettings; + m_qsettings = new QSettings(session_fileName, QSettings::IniFormat, this); + QFile file(m_qsettings->fileName()); + m_fileExists = file.exists(); + m_filename = m_qsettings->fileName(); + m_fileConverted = false; + qInfo() << "config file: " << m_qsettings->fileName(); } } + int Settings::getInt(const QString &name, const int &def) const { return m_qsettings->value(name, def).toInt(); } + void Settings::setInt(const QString &name, const int &value) { m_tmpConfig->insert(name, value); @@ -64,32 +70,39 @@ QColor Settings::getColor(const QString &name, const QColor &def) const return m_qsettings->value(name).value(); return def; } + void Settings::setColor(const QString &name, const QColor &value) { m_tmpConfig->insert(name, value); } + QString Settings::getString(const QString &name, const QString &def) const { return m_qsettings->value(name, def).toString(); } + void Settings::setString(const QString &name, const QString &value) { m_tmpConfig->insert(name, value); } + bool Settings::getBool(const QString &name, const bool &def) const { return m_qsettings->value(name, def).toBool(); } + void Settings::setBool(const QString &name, const bool &value) { m_tmpConfig->insert(name, value); } + void Settings::save() { for (auto parameter : m_tmpConfig->keys()) m_qsettings->setValue(parameter, m_tmpConfig->value(parameter)); m_tmpConfig->clear(); } + void Settings::clear() { m_tmpConfig->clear(); diff --git a/src/settings.h b/src/settings.h index 7c92cc9..9c5aea4 100644 --- a/src/settings.h +++ b/src/settings.h @@ -25,7 +25,7 @@ class Settings : public QObject Q_OBJECT public: explicit Settings(QObject *parent = Q_NULLPTR); - explicit Settings(QObject *parent, const QString &fileName); + explicit Settings(QObject *parent, const QString &session_id, const QString &config_path); ~Settings(); const bool &fileExists() const { return m_fileExists; }