main.cpp 14.8 KB
Newer Older
Leander Schulten's avatar
Leander Schulten committed
1
#include <QCoreApplication>
Leander Schulten's avatar
Leander Schulten committed
2
#include <QDebug>
3
#include <id.h>
4
5
#include "dmx/device.h"
#include "dmx/channel.h"
6
#include "applicationdata.h"
7
#include "dmx/programm.h"
Leander Schulten's avatar
Leander Schulten committed
8
#include <QMetaProperty>
9
#include "dmx/dmxchannelfilter.h"
Leander Schulten's avatar
Leander Schulten committed
10
11
12
13
14
15
16
#include <chrono>
#include <QEasingCurve>
#include <cmath>
#include <QCryptographicHash>
#include "usermanagment.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
17
#include "dmx/device.h"
Leander Schulten's avatar
Leander Schulten committed
18
19
#include <QQmlContext>
#include <QFileInfo>
20
21
#include <limits>
#include "modelmanager.h"
22
23
24
25
26
#include "gui/channelprogrammeditor.h"
#include "gui/mapview.h"
#include "gui/mapeditor.h"
#include "gui/controlitem.h"
#include "gui/controlpanel.h"
27
#include "errornotifier.h"
Leander Schulten's avatar
Leander Schulten committed
28
#include <QQuickView>
29
#include <QLibrary>
30
#include "dmx/HardwareInterface.h"
31
#include "settings.h"
32
#include <QDir>
33
#include "dmx/driver.h"
Leander Schulten's avatar
Leander Schulten committed
34
#include "test/testloopprogramm.h"
Leander Schulten's avatar
Leander Schulten committed
35
#include "test/testmodulsystem.h"
36
#include "codeeditorhelper.h"
37
#include "modules/programblock.h"
38
39
#include "gui/programblockeditor.h"
#include "gui/graph.h"
40
#include <QTimer>
41
42
#include "gui/oscillogram.h"
#include "gui/colorplot.h"
43
44
#include "audio/audiocapturemanager.h"
#include "test/testsampleclass.h"
45
#include "spotify/spotify.h"
46
#include "modules/dmxconsumer.h"
47
#include "sortedmodelview.h"
48
#include "updater.h"
49
#include <QSslSocket>
50
51

#ifdef DrMinGW
52
53
#include "exchndl.h"
#include <QNetworkReply>
54
#endif
55

Leander Schulten's avatar
Leander Schulten committed
56
57
int main(int argc, char *argv[])
{
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#ifdef DrMinGW
    ExcHndlInit();
    auto path = QStandardPaths::writableLocation(QStandardPaths::QStandardPaths::AppDataLocation);
    path += QLatin1String("/Lichtsteuerung");
    QDir dir(path);
    if(!dir.mkpath(path)){
        qWarning() << "Error creating dirs : " << path;
    }
    path += QLatin1String("/crash_dump_");
    path += QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yyyy HH.mm.ss"));
    path += QLatin1String(".txt");
    qDebug() << "The crash report file is : " << path;
    ExcHndlSetLogFileNameA(path.toStdString().c_str());
#endif

73
    if (!QSslSocket::supportsSsl()) {
74
75
76
        ErrorNotifier::showError("No OpenSSL library found!\nUpdates are not possible and the Spotify support does not work.");
    }

77
78
79
80
    Updater updater;
    QObject::connect(&updater,&Updater::needUpdate,[&](){
        updater.update();
    });
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifdef DrMinGW
    // send crash reports
    auto files = dir.entryInfoList(QDir::Filter::Files);
    for(auto & file : files){
        if(file.fileName().startsWith(QLatin1String("crash_dump"))){
            auto newFileName = file.absolutePath() + "/sended_" +file.fileName();
            if(!QFile::rename(file.absoluteFilePath(),newFileName)){
                qWarning() << "Failed to rename file from " << file.absoluteFilePath() << " to " << newFileName;
                continue;
            }
            auto upload = [newFileName,&updater](){
                // we only want to report Bugs for new versions
                if(updater.getState() == Updater::UpdaterState::NoUpdateAvailible){
                    QFile file(newFileName);
                    if(!file.open(QIODevice::ReadOnly)){
                        qWarning() <<  "Failed to open file " << newFileName;
                        return;
                    }
                    auto request = QNetworkRequest(QUrl(QStringLiteral("https://orga.symposion.hilton.rwth-aachen.de/send_crash_report")));
                    request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader,"text/plain");
                    auto response = updater.getQNetworkAccessManager()->post(request,file.readAll());
                    QObject::connect(response,&QNetworkReply::finished,[=](){
                        if(response->error() == QNetworkReply::NoError){
                            qDebug() << "crash report erfolgreich hochlgeladen";
                        }else{
                            qWarning() << "Fehler beim hochladen des crash reports : " << response->errorString();
                        }
                        response->deleteLater();
                    });
                }
            };
            if(updater.getState() == Updater::UpdaterState::NotChecked){
                QObject::connect(&updater,&Updater::stateChanged,upload);
            }else{
                upload();
            }
        }
    }
#endif
120
    /*Test::TestModulSystem testModulSystem;
Leander Schulten's avatar
Leander Schulten committed
121
    testModulSystem.runTest();
122
    return 0;*/
123
124
    // init the rand function for different random numbers each startup
    srand(static_cast<unsigned int>(time(nullptr)));
125

126
    Test::testSampleClass();
Leander Schulten's avatar
Leander Schulten committed
127

128
129
130
131
132
133
134
135
136
137
138
139
    class CatchingErrorApplication : public QGuiApplication{
    public:
        CatchingErrorApplication(int &argc, char **argv):QGuiApplication(argc,argv){}
        virtual ~CatchingErrorApplication(){}
        virtual bool notify(QObject* receiver, QEvent* event)
        {
            try {
                return QGuiApplication::notify(receiver, event);
            } catch (std::exception &e) {
                qCritical("Error %s sending event %s to object %s (%s)",
                    e.what(), typeid(*event).name(), qPrintable(receiver->objectName()),
                    receiver->metaObject()->className());
140
141
                QString error = QString("Error ") +e.what()+"sending event "+typeid(*event).name()+" to object "+ qPrintable(receiver->objectName())+" "+ receiver->metaObject()->className();
                ErrorNotifier::get()->newError(error);
142
143
144
145
            } catch (...) {
                qCritical("Error <unknown> sending event %s to object %s (%s)",
                    typeid(*event).name(), qPrintable(receiver->objectName()),
                    receiver->metaObject()->className());
146
147
                QString error = QString("Error ") + "<unknown> sending event "+typeid(*event).name()+" to object "+ qPrintable(receiver->objectName())+" "+ receiver->metaObject()->className();
                ErrorNotifier::get()->newError(error);
148
149
150
151
152
153
            }

            return false;
        }
    };

154
    using namespace GUI;
155
    using namespace DMX;
156

Leander Schulten's avatar
Leander Schulten committed
157
158
159
160
//    auto defaultFormat = QSurfaceFormat::defaultFormat();
//    defaultFormat.setSamples(8);
//    QSurfaceFormat::setDefaultFormat(defaultFormat);
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
161
    CatchingErrorApplication app(argc, argv);
Leander Schulten's avatar
Leander Schulten committed
162
163
    QQmlApplicationEngine engine;
    ControlPanel::setQmlEngine(&engine);
164
    ProgramBlockEditor::engine = &engine;
165
    Driver::dmxValueModel.setQMLEngineThread(engine.thread());
166
167
168
    // normally this should be done automatically
    qRegisterMetaType<QAbstractListModel*>("QAbstractListModel*");
    qRegisterMetaType<PropertyInformationModel*>("PropertyInformationModel*");
169
170
    //qmlRegisterType<const ChannelVector*>("my.models",1,0,"ChannelVector");
    qmlRegisterType<ChannelProgrammEditor>("custom.licht",1,0,"ChannelProgrammEditor");
171
172
    qmlRegisterType<GUI::MapView>("custom.licht",1,0,"MapView");
    qmlRegisterType<GUI::MapEditor>("custom.licht",1,0,"MapEditor");
Leander Schulten's avatar
Leander Schulten committed
173
    qmlRegisterType<ControlPanel>("custom.licht",1,0,"ControlPanel");
174
175
176
    qmlRegisterType<Graph>("custom.licht",1,0,"Graph");
    qmlRegisterType<Oscillogram>("custom.licht",1,0,"Oscillogram");
    qmlRegisterType<Colorplot>("custom.licht",1,0,"Colorplot");
177
    //qmlRegisterType<ErrorNotifier>("custom.licht",1,0,"ErrorNotifier");
Leander Schulten's avatar
Leander Schulten committed
178
    qmlRegisterType<ControlItem>("custom.licht.template",1,0,"ControlItemTemplate");
Leander Schulten's avatar
Leander Schulten committed
179
    qmlRegisterType<ControlItemData>("custom.licht.template",1,0,"ControlItemData");
Leander Schulten's avatar
Leander Schulten committed
180
181
    qmlRegisterType<DimmerGroupControlItemData>("custom.licht",1,0,"DimmerGroupControlItemData");
    qmlRegisterType<DMXChannelFilter>("custom.licht",1,0,"DMXChannelFilter");
182
    qmlRegisterType<CodeEditorHelper>("custom.licht",1,0,"CodeEditorHelper");
183
    qmlRegisterType<ProgramBlockEditor>("custom.licht",1,0,"ProgramBlockEditor");
184
    qmlRegisterType<SortedModelVectorView>("custom.licht",1,0,"SortedModelVectorView");
Leander Schulten's avatar
Leander Schulten committed
185
    qRegisterMetaType<DMXChannelFilter::Operation>("Operation");
Leander Schulten's avatar
Leander Schulten committed
186
    qmlRegisterUncreatableType<UserManagment>("custom.licht",1,0,"Permission","Singletone in c++");
Leander Schulten's avatar
Leander Schulten committed
187
    qRegisterMetaType<UserManagment::Permission>("Permission");
188
    qRegisterMetaType<Modules::detail::PropertyInformation::Type>("Type");
189
    qRegisterMetaType<Modules::ValueType>("ValueType");
190
    qRegisterMetaType<Modules::ProgramBlock::Status>("Status");
191
    qRegisterMetaType<Modules::PropertiesVector*>("PropertiesVector*");
192
    qRegisterMetaType<Driver::DMXQMLValue*>("DMXQMLValue*");
Leander Schulten's avatar
Leander Schulten committed
193
    qRegisterMetaType<DMX::DMXChannelFilter*>("DMXChannelFilter*");
194

195
196
197

    updater.checkForUpdate();

198
    // Load Settings and ApplicationData
199
200
    Settings::setLocalSettingFile(QFileInfo("settings.ini"));
    Settings settings;
201
202
203
204
205
206
207
208
    QFile file("QTJSONFile.json");
    if(!file.exists()){
        file.setFileName(settings.getJsonSettingsFilePath());
    }
    if(file.exists()){
        file.copy(file.fileName()+"_"+QDateTime::currentDateTime().toString("dd.MM.yyyy HH.mm.ss"));
    }
    auto after = ApplicationData::loadData(file);
209
210
    // nachdem die Benutzer geladen wurden, auto login durchführen
    UserManagment::get()->autoLoginUser();
Leander Schulten's avatar
Leander Schulten committed
211

Leander Schulten's avatar
Leander Schulten committed
212
//#warning Dont use IDBase<xxxxx>::getAllIDBases() in this file. It will crash the aplication when its closing
Leander Schulten's avatar
Leander Schulten committed
213

214
    std::thread t(Test::testLoopProgramm);
215
    t.join();
Leander Schulten's avatar
Leander Schulten committed
216

217
218
    auto & spotify = Spotify::get();
    Modules::ModuleManager::singletone()->setSpotify(&spotify);
Leander Schulten's avatar
Leander Schulten committed
219
220


221
222
223
224
225
226
    QStringList dataList;
    const QMetaObject &mo = QEasingCurve::staticMetaObject;
    QMetaEnum metaEnum = mo.enumerator(mo.indexOfEnumerator("Type"));
    for (int i = 0; i < QEasingCurve::NCurveTypes - 1; ++i) {
        dataList.append(metaEnum.key(i));
    }
Leander Schulten's avatar
Leander Schulten committed
227
228
    QStringList moduleTypeList;
    const QMetaObject &_mom = Modules::Module::staticMetaObject;
229
    QMetaEnum _metaEnum =_mom.enumerator(_mom.indexOfEnumerator("Type"));
Leander Schulten's avatar
Leander Schulten committed
230
231
232
    for (int i = 0; i < _metaEnum.keyCount(); ++i) {
        moduleTypeList.append(_metaEnum.key(i));
    }
233
234
    QStringList valueTypeList;
    valueTypeList << "Brightness" << "RGB" ;
Leander Schulten's avatar
Leander Schulten committed
235

236
237
238
239
240
241
242
243
244
245
    QStringList modolePropertyTypeList;
    modolePropertyTypeList << "Int" << "Long" << "Float" << "Double" << "Bool" << "String";
    // Does not work: do it manually
    /*const QMetaObject &_momProp = Modules::detail::PropertyInformation::staticMetaObject;
    qDebug() << "Enum count" <<_momProp.enumeratorCount();
    QMetaEnum _metaEnumP =_momProp.enumerator(mo.indexOfEnumerator("Type"));
    for (int i = 0; i < _metaEnumP.keyCount(); ++i) {
        modolePropertyTypeList.append(_metaEnumP.key(i));
    }*/

246
247
248
    app.connect(&app,&QGuiApplication::lastWindowClosed,[&](){
        QFile savePath(settings.getJsonSettingsFilePath());
        ApplicationData::saveData(savePath);
249
        Driver::stopAndUnloadDriver();
250
        updater.runUpdateInstaller();
251
252
253
    });
    settings.connect(&settings,&Settings::driverFilePathChanged,[&](){
        Driver::loadAndStartDriver(settings.getDriverFilePath());
254
    });
Leander Schulten's avatar
Leander Schulten committed
255
256
257
258
259
    settings.connect(&settings,&Settings::audioCaptureFilePathChanged,[&](){
        if(Audio::AudioCaptureManager::get().startCapturing(settings.getAudioCaptureFilePath())==false){
            ErrorNotifier::get()->newError("Failed to load Audio Capture Library");
        }
    });
Leander Schulten's avatar
Leander Schulten committed
260
261
262
263
264
    settings.connect(&settings,&Settings::updatePauseInMsChanged,[&](){
        if(Driver::getCurrentDriver()){
            Driver::getCurrentDriver()->setWaitTime(std::chrono::milliseconds(settings.getUpdatePauseInMs()));
        }
    });
265
    Modules::ModuleManager::singletone()->loadAllModulesInDir(settings.getModuleDirPath());
266
267
268
    settings.connect(&settings,&Settings::moduleDirPathChanged,[&](){
        Modules::ModuleManager::singletone()->loadAllModulesInDir(settings.getModuleDirPath());
    });
Leander Schulten's avatar
Leander Schulten committed
269

270
271
    ModelManager::get().setSettings(&settings);
    engine.rootContext()->setContextProperty("ModelManager",&ModelManager::get());
272
    engine.rootContext()->setContextProperty("easingModel",dataList);
273
274
    engine.rootContext()->setContextProperty("ErrorNotifier",ErrorNotifier::get());
    engine.setObjectOwnership(ErrorNotifier::get(),QQmlEngine::CppOwnership);
275
    engine.rootContext()->setContextProperty("devicePrototypeModel",ModelManager::get().getDevicePrototypeModel());
Leander Schulten's avatar
Leander Schulten committed
276
277
    engine.rootContext()->setContextProperty("modulesModel",Modules::ModuleManager::singletone()->getModules());
    engine.rootContext()->setContextProperty("moduleTypeModel",moduleTypeList);
278
    engine.rootContext()->setContextProperty("valueTypeList",valueTypeList);
279
    engine.rootContext()->setContextProperty("modolePropertyTypeList",modolePropertyTypeList);
280
281
282
    engine.rootContext()->setContextProperty("deviceModel",ModelManager::get().getDeviceModel());
    engine.rootContext()->setContextProperty("programmModel",ModelManager::get().getProgramModel());
    engine.rootContext()->setContextProperty("programmPrototypeModel",ModelManager::get().getProgramPrototypeModel());
283
    engine.rootContext()->setContextProperty("programBlocksModel",&Modules::ProgramBlockManager::model);
284
    engine.rootContext()->setContextProperty("userModel",UserManagment::get()->getUserModel());
Leander Schulten's avatar
Leander Schulten committed
285
    engine.rootContext()->setContextProperty("UserManagment",UserManagment::get());
286
    engine.rootContext()->setContextProperty("Settings",&settings);
287
    engine.rootContext()->setContextProperty("spotify",&spotify);
288
    engine.rootContext()->setContextProperty("updater",&updater);
289
290
    QQmlEngine::setObjectOwnership(&Driver::dmxValueModel,QQmlEngine::CppOwnership);
    engine.rootContext()->setContextProperty("dmxOutputValues",&Driver::dmxValueModel);
Leander Schulten's avatar
Leander Schulten committed
291
    engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
Leander Schulten's avatar
Leander Schulten committed
292

293

Leander Schulten's avatar
Leander Schulten committed
294
295
    // laden erst nach dem laden des qml ausführen
    after();
296
297
298


    // Treiber laden
Leander Schulten's avatar
Leander Schulten committed
299
#define USE_DUMMY_DRIVER
300
#ifndef USE_DUMMY_DRIVER
301
    if(!Driver::loadAndStartDriver(settings.getDriverFilePath())){
302
        ErrorNotifier::showError("Cant start driver.");
303
304
    }else {
        Driver::getCurrentDriver()->setWaitTime(std::chrono::milliseconds(40));
305
    }
306

307
308
309
#else
#include "test/DriverDummy.h"

310
    DriverDummy driver;
311
    driver.setSetValuesCallback([](unsigned char* values, int size, double time){
312
        std::memset(values,0,size);
313
        DMXChannelFilter::initValues(values,size);
314
        DMX::Programm::fill(values,size,time);
315
        Modules::DMXConsumer::fillWithDMXConsumer(values,size);
316
        DMXChannelFilter::filterValues(values,size);
317
        Driver::dmxValueModel.setValues(values,size);
318
    });
319
    driver.setWaitTime(std::chrono::milliseconds(40));
320
    driver.init();
321
    driver.start();
322
#endif
323

324
325
326
    QTimer timer;
    timer.setInterval(15);
    QObject::connect(&timer,&QTimer::timeout,[&](){
327
328
329
330
331
332
333
334
        if(Audio::AudioCaptureManager::get().isCapturing()){
            if(Graph::getLast())
                Graph::getLast()->update();
            if(Oscillogram::getLast())
                Oscillogram::getLast()->update();
            if(Colorplot::getLast())
                Colorplot::getLast()->update();
        }
335
336
    });
    timer.start();
337

338
339
    qDebug() << "start capturing : " << Audio::AudioCaptureManager::get().startCapturing(settings.getAudioCaptureFilePath());

340
    Modules::ModuleManager::singletone()->controller().start();
Leander Schulten's avatar
Leander Schulten committed
341
    //ControlPanel::getLastCreated()->addDimmerGroupControl();
Leander Schulten's avatar
Leander Schulten committed
342
    return app.exec();
Leander Schulten's avatar
Leander Schulten committed
343
}