diff --git a/src/dialogs/tdialogloaderobject.cpp b/src/dialogs/tdialogloaderobject.cpp index 2da66e935f5309ef163fc308b87c59abc228a330..3e77995bdc292f7007dd9b7474d2a90962ae1401 100644 --- a/src/dialogs/tdialogloaderobject.cpp +++ b/src/dialogs/tdialogloaderobject.cpp @@ -25,8 +25,10 @@ #include "main/ttiphandler.h" #include "main/texamsummary.h" #include "main/tstartexamitem.h" -#include "qtr.h" +#include <qtr.h> +#include <exam/texam.h> +#include <QtCore/qdir.h> #include <QtWidgets/qdialogbuttonbox.h> #include <QtCore/qdebug.h> @@ -93,3 +95,22 @@ QString TdialogLoaderObject::buttonRoleIcon(int role) { } } + +void TdialogLoaderObject::openFile(const QString& fileName) { + QFile file(fileName); + quint32 hdr = 0; + if (file.open(QIODevice::ReadOnly)) { + QDataStream in(&file); + in >> hdr; // check what file type + auto fullPath = QDir(file.fileName()).absolutePath(); + file.close(); + if (Texam::couldBeExam(hdr)) { + if (Texam::isExamVersion(hdr)) + emit continueExam(fullPath); + } else if (Tlevel::couldBeLevel(hdr)) { + if (Tlevel::isLevelVersion(hdr)) + emit openLevel(fullPath); + } else + qDebug() << "[TdialogLoaderObject] file" << fileName << "is not supported by Nootka"; + } +} diff --git a/src/dialogs/tdialogloaderobject.h b/src/dialogs/tdialogloaderobject.h index bc875e6c5d4c447d0379866f3068a68a04a23129..03939f5a8f86140857cea369cda5cd55b001d7c3 100644 --- a/src/dialogs/tdialogloaderobject.h +++ b/src/dialogs/tdialogloaderobject.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2017 by Tomasz Bojczuk * + * Copyright (C) 2017-2018 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -50,6 +50,12 @@ public: */ Q_INVOKABLE QString buttonRoleIcon(int role); + Q_INVOKABLE void openFile(const QString& fileName); + +signals: + void continueExam(const QString& examFile); + void openLevel(const QString& levelFile); + private: static bool m_firstTime; diff --git a/src/dialogs/tlevelcreatoritem.cpp b/src/dialogs/tlevelcreatoritem.cpp index 20f3c459240339c0a24c80e5574c9d2c0e92c0a5..bb280db93515d9176abe1ec72f2efd94131e31e2 100644 --- a/src/dialogs/tlevelcreatoritem.cpp +++ b/src/dialogs/tlevelcreatoritem.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2017 by Tomasz Bojczuk * + * Copyright (C) 2017-2018 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -25,6 +25,7 @@ #include <tglobals.h> #include <texamparams.h> +#include <QtCore/qtimer.h> #include <QtCore/qfileinfo.h> #include <QtCore/qdatetime.h> #include <QtWidgets/qmessagebox.h> @@ -498,6 +499,19 @@ QStringList TlevelCreatorItem::keyComboModel() { } +void TlevelCreatorItem::openLevel(const QString& levelFile) { + if (selector()) + selector()->loadFromFile(levelFile); + else // delay is necessary because selector is created when level creator component is completed + QTimer::singleShot(200, [=]{ + if (selector()) + selector()->loadFromFile(levelFile); + else + qDebug() << "[TlevelCreatorItem] device too slow to open file as command line argument."; + }); +} + + //################################################################################################# //################### PROTECTED ############################################ //################################################################################################# diff --git a/src/dialogs/tlevelcreatoritem.h b/src/dialogs/tlevelcreatoritem.h index 050ce73c8246c78a7775d52491bbb8bfe28132d4..a7008a8479666fcee8806a862d43fd910423896a 100644 --- a/src/dialogs/tlevelcreatoritem.h +++ b/src/dialogs/tlevelcreatoritem.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2017 by Tomasz Bojczuk * + * Copyright (C) 2017-2018 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -220,6 +220,8 @@ public: Q_INVOKABLE QStringList keyComboModel(); + Q_INVOKABLE void openLevel(const QString& levelFile); + signals: void updateLevel(); void updateNotesList(); diff --git a/src/libs/core/tglobals.h b/src/libs/core/tglobals.h index bc9fe09c6806cc7a7b244d5e7cd876e0b5687643..58cdf233505bdab5ee34fb01388217dde6304feb 100644 --- a/src/libs/core/tglobals.h +++ b/src/libs/core/tglobals.h @@ -411,6 +411,7 @@ signals: void notBadColorChanged(); void wrongColorChanged(); /**< To silence warning about non-NOTIFYable properties */ void fakeSignal(); + void wantOpenFile(const QString& fileName); /**< Emitted when Nootka starts with an argument which is exam or level file */ private: static Tglobals *m_instance; diff --git a/src/libs/core/tnootkaqml.cpp b/src/libs/core/tnootkaqml.cpp index d916e62158564c51b5001950722a1002347152b5..83218195e4a8e0a0da211b2b34a20d484f59da05 100755 --- a/src/libs/core/tnootkaqml.cpp +++ b/src/libs/core/tnootkaqml.cpp @@ -39,9 +39,7 @@ #include "tcolor.h" #include <QtQml/qqmlengine.h> -#include <QtCore/qfile.h> -#include <QtCore/qdir.h> -#include <QtCore/qdir.h> +#include <QtCore/qfileinfo.h> #include <QtCore/qdatetime.h> #include <QtCore/qbuffer.h> #include <QtWidgets/qapplication.h> @@ -436,6 +434,33 @@ void TnootkaQML::setQmlEngine(QQmlEngine* e) { } +/** + * Opening files from command line argument starts here, but it is a bit clumsy: + * - for Music XML is fine, we have @p TscoreObject here so just call @p openMusicXml() + * - but for exam and level files only @p wantOpenFile() signal is emitted + * - then @p MainWindow.qml handles it and creates @p DialogLoader.qml + * - 'dialog loader' invokes @p TdialogLoaderObject::openFile() of its object + * - and there the file is distinguished (exam or level) and appropriate signal is emitted + * - again, 'dialog loader' handles those signals and creates 'exam executor' or 'level creator' apparently + */ +void TnootkaQML::openFile(const QString& runArg) { + if (GLOB->isExam()) { + qDebug() << "--- Exam or exercise is running. File cannot be opened! ---"; + return; + } + if (QFile::exists(runArg)) { + QFile file(runArg); + auto ext = QFileInfo(file).suffix(); + if (ext == QLatin1String("xml")) { // TODO mxl - compressed format + auto fullPath = QDir(file.fileName()).absolutePath(); + m_scoreObject->openMusicXml(fullPath); + } else { + emit GLOB->wantOpenFile(runArg); + } + } +} + + //################################################################################################# //################### CONNECTIONS NODE ############################################ //################################################################################################# diff --git a/src/libs/core/tnootkaqml.h b/src/libs/core/tnootkaqml.h index 7b7a6517c40bf76fc4577a8d56b2635e53c38965..28235f19196185703dda6890dbdc209c8214efd4 100644 --- a/src/libs/core/tnootkaqml.h +++ b/src/libs/core/tnootkaqml.h @@ -62,9 +62,10 @@ public: /** * Dialogues recognized by main QML Dialog instance of main window + * @p NoDialog only creates 'dialog loader' instance but does nothing */ enum Edialogs { - Settings = 1, About = 2, LevelCreator = 3, ExamStart = 4, ExamSummary = 5, Charts = 6, QuickAudio = 7 + NoDialog = 0, Settings = 1, About = 2, LevelCreator = 3, ExamStart = 4, ExamSummary = 5, Charts = 6, QuickAudio = 7 }; Q_ENUM(Edialogs) @@ -142,6 +143,8 @@ public: QQmlEngine* qmlEngine() { return m_qmlEngine; } void setQmlEngine(QQmlEngine* e); + void openFile(const QString& runArg); + /** * All stuff below is responsible for handling note changes in score, instrument and sound in/out. * @p TnootkaQML has score and instrument pointers to handle theirs signals when note is changed, diff --git a/src/main.cpp b/src/main.cpp index 1c9dc2c387c7d9b8e09b8805ba3398099a732849..6f3c29d15e702368b427fe4d39eaa6c07c5e5688 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -150,18 +150,14 @@ int main(int argc, char *argv[]) qmlRegisterType<TdialogLoaderObject>("Nootka.Dialogs", 1, 0, "TdialogObject"); e->load(QUrl(QStringLiteral("qrc:/MainWindow.qml"))); -// #if defined (Q_OS_ANDROID) -// w->showFullScreen(); // TODO seems to be not necessary -// #endif - if (firstTime) { #if defined (Q_OS_ANDROID) -// QString androidArg = Tandroid::getRunArgument(); -// if (!androidArg.isEmpty()) -// w->openFile(androidArg); -#else // TODO -// if (argc > 1) -// w->openFile(QString::fromLocal8Bit(argv[argc - 1])); + QString androidArg = Tandroid::getRunArgument(); + if (!androidArg.isEmpty()) + nooObj.openFile(androidArg); +#else + if (argc > 1) + nooObj.openFile(QString::fromLocal8Bit(argv[argc - 1])); #endif } if (firstTime) { diff --git a/src/main/texamexecutor.h b/src/main/texamexecutor.h index f39aa50002144e37e5a111794d54dbb0539730ca..e292d96a397afe7fd2e955b122d0f94198db199d 100644 --- a/src/main/texamexecutor.h +++ b/src/main/texamexecutor.h @@ -75,7 +75,7 @@ public: * Describes reason of starting executor */ enum EexecOrigin { - NoExam = 0, ContinueExam, NewExam, LevelCreator, StartExercise + NoExam = 0, ContinueExam = 1, NewExam = 2, LevelCreator = 3, StartExercise = 4 }; Q_ENUM(EexecOrigin) diff --git a/src/qml/DialogLoader.qml b/src/qml/DialogLoader.qml index ab52863e50c65903d76d48aec54c658dd8d9cf38..3ba503a1da0b755403ca75e042929ea65f9b4829 100644 --- a/src/qml/DialogLoader.qml +++ b/src/qml/DialogLoader.qml @@ -25,7 +25,21 @@ Old.Dialog { property var dialogDrawer: null property var buttons: [] - TdialogObject { id: dialogObj } + TdialogObject { + id: dialogObj + onContinueExam: { + GLOB.isExam = true + if (!nootkaWindow.executor.init(1, examFile)) { + console.log("Executor discarded, deleting it") + nootkaWindow.executor.destroy() + GLOB.isExam = false + } + } + onOpenLevel: { + page = Nootka.LevelCreator + currentDialog.openLevel(levelFile) + } + } contentItem: Column { width: dialLoader.width; height: dialLoader.height @@ -114,4 +128,8 @@ Old.Dialog { onReset: if (currentDialog) currentDialog.reset() onAccepted: if (currentDialog) currentDialog.accepted() onHelp: if (currentDialog) currentDialog.help() + + function openFile(file) { + dialogObj.openFile(file) + } } diff --git a/src/qml/MainWindow.qml b/src/qml/MainWindow.qml index f05817e5c2850ae8449af03f539ce7ddaacfc96a..58bc0dc059b48cacf519f4c7f7d84a391b853790 100644 --- a/src/qml/MainWindow.qml +++ b/src/qml/MainWindow.qml @@ -104,6 +104,10 @@ ApplicationWindow { examResults.destroy() } } + onWantOpenFile: { + showDialog(Nootka.NoDialog) + dialogLoader.openFile(fileName) + } } Component.onCompleted: {