From 1326d7ba193c9a58b3b3c5c9d4b499a740000ee9 Mon Sep 17 00:00:00 2001 From: Ray Pulsipher Date: Wed, 30 Aug 2023 21:07:21 -0700 Subject: [PATCH] - Update canvas code that pulls files from canvas. Clear read-only flag on files before downloading, then set read-only flag on files after downloading. This prevents students from saving a file under the original cached location. https://github.com/operepo/ope/issues/143 --- .gitignore | 2 + client_tools/lms/src/OPE_LMS/OPE_LMS.pro | 37 +--- client_tools/lms/src/OPE_LMS/appmodule.cpp | 181 ++++++++++++++++-- client_tools/lms/src/OPE_LMS/appmodule.h | 71 ++++++- .../lms/src/OPE_LMS/external/ex_canvas.cpp | 46 ++++- .../lms/src/OPE_LMS/external/ex_canvas.h | 4 +- client_tools/lms/src/OPE_LMS/main.cpp | 56 ++---- .../lms/src/OPE_LMS/not_credentialed.qml | 2 +- 8 files changed, 305 insertions(+), 94 deletions(-) diff --git a/.gitignore b/.gitignore index e5fd7711..1e30f889 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,5 @@ exported_gpo /media_files_tool/media_files/media /media_files_tool/ssh.log /client_tools/svc/mgmt.dist +/media_files_tool/sync_media_files.build +/media_files_tool/sync_media_files.dist diff --git a/client_tools/lms/src/OPE_LMS/OPE_LMS.pro b/client_tools/lms/src/OPE_LMS/OPE_LMS.pro index dc3adcee..cf759f76 100644 --- a/client_tools/lms/src/OPE_LMS/OPE_LMS.pro +++ b/client_tools/lms/src/OPE_LMS/OPE_LMS.pro @@ -1,5 +1,5 @@ QT += qml quick sql network quickcontrols2 webview networkauth webchannel webenginequick webenginecore webenginewidgets core5compat -# +#graphicaleffects #webengine webenginewidgets # networkauth # webengine webenginewidgets quick-private webview-private webview @@ -90,7 +90,7 @@ QMAKE_LFLAGS += /ignore:4042 # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00 +# DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00 #QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. @@ -132,34 +132,6 @@ HEADERS += \ appmodule.h \ db.h \ openetworkaccessmanagerfactory.h \ -# cm/file/cm_fileinfo.h \ -# cm/file/cm_syncfile.h \ -# cm/file/cm_syncfilechunk.h \ -# cm/file/cm_syncfileversion.h \ -# cm/school/sc_classes.h \ -# cm/school/sc_classmodel.h \ -# cm/school/sc_lessonitem.h \ -# cm/school/sc_lessonitemmodel.h \ -# cm/school/sc_modulemodel.h \ -# cm/school/sc_modules.h \ -# cm/school/sc_programmodel.h \ -# cm/school/sc_programs.h \ -# cm/cm_classroom.h \ -# cm/cm_database.h \ -# cm/cm_httpserver.h \ -# cm/cm_machine.h \ -# cm/cm_mimetypes.h \ -# cm/cm_persistentobject.h \ -# cm/cm_persistentobjectmodel.h \ -# cm/cm_screengrab.h \ -# cm/cm_sequentialguid.h \ -# cm/cm_users.h \ -# cm/cm_webrequest.h \ -# external/ex_canvas.h \ -# external/ex_ldap.h \ -# appmodule.h \ -# db.h \ -# openetworkaccessmanagerfactory.h \ cm/cm_javascripthandler.h \ cm/cm_websockettransport.h \ customlogger.h @@ -168,6 +140,8 @@ HEADERS += \ RC_ICONS = logo_icon.ico DISTFILES += \ + WebEngineMP4Build_6.5.1.cmd \ + WebEngineMP4Build_6.5.2.cmd \ qt.conf \ blue-folder.png \ Scratch.txt \ @@ -193,7 +167,8 @@ DISTFILES += \ new_message.png \ StyledButton.qml \ ReplyPopup.qml \ - NewMessagePopup.qml + NewMessagePopup.qml \ + win_deploy_6.5.2.cmd diff --git a/client_tools/lms/src/OPE_LMS/appmodule.cpp b/client_tools/lms/src/OPE_LMS/appmodule.cpp index 197d41f6..becb0ab6 100644 --- a/client_tools/lms/src/OPE_LMS/appmodule.cpp +++ b/client_tools/lms/src/OPE_LMS/appmodule.cpp @@ -1,15 +1,45 @@ #include "appmodule.h" -AppModule::AppModule(QQmlApplicationEngine *parent) : QObject(parent) +AppModule::AppModule(QQmlApplicationEngine *parent, QString program_data_path) : QObject(parent) { HTTP_SERVER_PORT = 65525; exit_early = false; engine = parent; + + //registerOPEAccessibilityComponents(); + + // Show SSL info + qDebug() << "SSL Library Info: " << QSslSocket::supportsSsl() << QSslSocket::sslLibraryBuildVersionString() << QSslSocket::sslLibraryVersionString(); + // Relax ssl config as we will be running through test certs + QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration(); + QList cert_list = sslconf.caCertificates(); + QList cert_new = QSslCertificate::fromData("CaCertificates"); + cert_list += cert_new; + sslconf.setCaCertificates(cert_list); + sslconf.setProtocol(QSsl::AnyProtocol); + sslconf.setPeerVerifyMode(QSslSocket::VerifyNone); + sslconf.setSslOption(QSsl::SslOptionDisableServerNameIndication,true); + QSslConfiguration::setDefaultConfiguration(sslconf); + + nam_factory = new OPENetworkAccessManagerFactory; + if (program_data_path == "") { + // Get the standard program data folder to store things in. + program_data_path = QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation).at(1); // grab 2nd item + // Remove app name (c:/programdata/ope/opelms -> c:/programdata/ope) + program_data_path = program_data_path.replace("/OPELMS", ""); + } + this->data_path = program_data_path; parent->setNetworkAccessManagerFactory(nam_factory); parent->rootContext()->engine()->setNetworkAccessManagerFactory(nam_factory); + // Expose this object to the QML engine + parent->rootContext()->setContextProperty("mainWidget", this); + + // Add our websocket transport so we can communicate with web pages in a webview + qmlRegisterType("cm.WebSocketTransport", 1, 0, "WebSocketTransport"); + //QObject *root = engine->rootObjects().first(); //root->setParent("networkAccess", parent->networkAccessManager()); @@ -37,17 +67,38 @@ AppModule::AppModule(QQmlApplicationEngine *parent) : QObject(parent) _app_settings->sync(); //qDebug() << "App Settings: " << _app_settings->fileName(); + // Prevent app from running twice + QString tmp_dir = this->appStudentDataFolder(); //QDir::tempPath(); + qDebug() << tmp_dir; + if (tmp_dir.endsWith("/student_data") == true) { + // Should end with the current student (e.g. c:\programdata\ope\student_data\s77777) - if not, then not credentialed? + qDebug() << "Invalid student folder! Run credential and retry." << Qt::endl; +// QMessageBox msgbox; +// msgbox.setText("Invalid Student Folder!"); +// msgbox.setInformativeText("Student username not detected - you must run the credential app to link this app to the student's Canvas account."); +// msgbox.setStandardButtons(QMessageBox::Ok); +// msgbox.exec(); + + QApplication::exit(-1); + return; + } - // Expose this object to the QML engine - //qmlRegisterType("com.openprisoneducation.ope", 1, 0, "Canvas"); - parent->rootContext()->setContextProperty("mainWidget", this); - - // Add our websocket transport so we can communicate with web pages in a webview - qmlRegisterType("cm.WebSocketTransport", 1, 0, "WebSocketTransport"); + _lf = new QLockFile(tmp_dir + "/ope_lms.lock"); + if (!_lf->tryLock(100)) + { + qDebug() << "=====================================================\n" << + "WARNING - App already running, exiting...\n" << + "only one instance allowed to run. If this is an " << + " error, remove the temp/ope_lms.lock file and try again" << + "=====================================================\n"; + out << "App already running..." << Qt::endl; + QApplication::exit(-1); + return; + } // Figure out the database path QDir d; - d.setPath(this->appDataFolder()); + d.setPath(this->appStudentDataFolder()); d.mkpath(d.path()); QString db_file = d.path() + "/lms.db"; @@ -104,6 +155,10 @@ AppModule::~AppModule() _app_settings->deleteLater(); } + if (_lf) { + _lf->unlock(); + } + } void AppModule::debugPrint(QString msg) @@ -165,14 +220,36 @@ bool AppModule::desktopLaunch(QString url) return ret; } -QString AppModule::appDataFolder() +QString AppModule::appStudentDataFolder() { + + QString path = this->appDataFolder(); + QString curr_student = this->get_current_student_user(); + + path += "/student_data"; + + if (curr_student == "") { + return path; + } + + path += "/" + curr_student; + + QDir d; + d.setPath(path); + if (!d.exists()) { + d.mkpath(d.path()); + } + + return path; + + /* // Find the appdata folder // NOTE - if no user set in registry (not credentialed?), then grab dir for current user. QString curr_student = this->get_current_student_user(); if (curr_student == "") { // Return the standard path for the current logged in user. - QString p = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + //QString p = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + QString p = this->data_path; QDir d; d.setPath(p); d.mkpath(d.path()); @@ -206,6 +283,21 @@ QString AppModule::appDataFolder() d.mkpath(d.path()); return app_data_path; + */ +} + +QString AppModule::appDataFolder() +{ + // Should return something like c:/programdata/ope + + // Make sure folder exists + QDir d; + d.setPath(data_path); + if (!d.exists()) { + d.mkpath(d.path()); + } + + return this->data_path; } QString AppModule::dataFolder() @@ -228,10 +320,12 @@ QString AppModule::dataFolder() d.setPath(dataAbsPath); #else //d.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/content"); - d.setPath(this->appDataFolder() + "/content"); + d.setPath(this->appStudentDataFolder() + "/content"); #endif - d.mkpath(d.path()); + if (!d.exists()) { + d.mkpath(d.path()); + } return d.path(); } @@ -240,8 +334,10 @@ QString AppModule::fileCacheFolder() { QDir base_dir; //base_dir.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/content/www_root/canvas_file_cache/"); - base_dir.setPath(this->appDataFolder() + "/content/www_root/canvas_file_cache/"); - base_dir.mkpath(base_dir.path()); + base_dir.setPath(this->appStudentDataFolder() + "/content/www_root/canvas_file_cache/"); + if (!base_dir.exists()) { + base_dir.mkpath(base_dir.path()); + } return base_dir.path(); } @@ -684,3 +780,60 @@ QString AppModule::get_current_student_user() return _app_settings->value("student/user_name", "").toString(); } +void AppModule::sendAccessibilityEvent(QQuickItem *item, QAccessible::Event event_reason) +{ + QAccessibleEvent event(item, event_reason); // event(this, QAccessible::TextUpdated); + + //event.accessibleInterface()-(QAccessible::TextUpdated); + //event.accessibleInterface()->setText(QAccessible::Description, QLatin1String("Hello WOrld!")); + QAccessible::updateAccessibility(&event); + + + // Find the root window so we can get the accessibility tree +// for (QObject *o: this->engine->rootObjects()) { +// qDebug() << "... > " << o; +// } +// QObject *rootObject = this->engine->rootObjects().first(); +// QQuickItem *accessible_root = nullptr; +// //qDebug() << "RootObject: " << rootObject; +// if (rootObject->objectName() == "appPage") { +// // Root object IS the main window +// accessible_root = qobject_cast(rootObject); +// qDebug() << "Casting: " << accessible_root; +// } else { +// accessible_root = rootObject->findChild("appPage"); +// } + +// if (accessible_root == nullptr) { +// qDebug() << "No QML object found with object_name: appPage"; +// return; +// } + +// // Setup the update handler +// //QAccessible::installUpdateHandler(new OPECustomAccessibleItem(item)); + +// QAccessibleEvent event(this, QAccessible::Event::SoundPlayed); +// QObject *accessible_iface = dynamic_cast(QAccessible::queryAccessibleInterface(item)); +// qDebug() << "Accessible Iface: " << accessible_iface; + +// QAccessibleInterface *iface = event.accessibleInterface(); +// qDebug() << "IFACe: " << iface; +// iface->setText(QAccessible::Text::Name, QStringLiteral("Hey WOrld")); +// QCoreApplication::sendEvent(accessible_iface, dynamic_cast(&event)); +// accessible_iface->deleteLater(); + +// // Send an accessibilty event from the QML system. +// QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(item); +// //iface->item() + +// iface->setText(QAccessible::Name, "TEst 1235"); + +// QString accessibleName = iface->text(QAccessible::Name); +// qDebug() << "A Name"; +// //QAccessibleEvent event(iface, QAccessible::Focus); +// //qDebug() << "Accessibility Event " << event; +// QAccessibleEvent event(iface, QAccessible::NameChanged); +// QAccessible::updateAccessibility(&event.object()); + +} + diff --git a/client_tools/lms/src/OPE_LMS/appmodule.h b/client_tools/lms/src/OPE_LMS/appmodule.h index 60645fcc..177307c0 100644 --- a/client_tools/lms/src/OPE_LMS/appmodule.h +++ b/client_tools/lms/src/OPE_LMS/appmodule.h @@ -19,12 +19,24 @@ #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include +#include #ifdef ANDROID #include @@ -44,6 +56,54 @@ #include "external/ex_canvas.h" +/** + * Custom accessible interface - plugin for creating accessible interface, then Accessible object returned if matching + */ +//class OPECustomAccessibleItem: public QAccessibleWidget +//{ +//public: +// explicit OPECustomAccessibleItem(QQuickItem* item): QAccessibleWidget(item) +// { + +// } +//}; + +//class OPECustomAccessibleFactory: public QAccessibleFac +//{ +//public: +// QAccessibleInterface *create(const QString& key, QObject* object) override +// { +// Q_UNUSED(key); + +// QQuickItem* item = qobject_cast(object); +// if (item && item->objectName() == "CustomItem") { +// return new OPECustomAccessibleItem(item); +// } + +// return nullptr; +// } +//}; + +//QAccessibleInterface *OPEAccessibleItemFactory(const QString &classname, QObject *object) { +// QAccessibleInterface *interface = nullptr; + +// if (classname == QLatin1String("CUSTOMOBJ") && object && object->isQuickItemType()) { +// interface = qobject_cast(new OPECustomAccessibleItem(static_cast(object))); +// } +// return interface; +//} + +//void registerOPEAccessibilityComponents() { +// QAccessible::installFactory(OPEAccessibleItemFactory); +//// QAccessible::registerAccessibleInterface([](QObject* object) { +//// QQuickItem* item = qobject_cast(object); +//// if (item && item->objectName() == "CustomItem") { +//// return new QAccessibleQuickItem(item); +//// } + +//// return nullptr; +//// }); +//} /** * @brief The AppModule class is the main class that runs the app. @@ -58,6 +118,12 @@ class AppModule : public QObject // Main qml engine object QQmlApplicationEngine *engine; + // Lock file - to keep app from running multiple times + QLockFile *_lf; + + // Where to store files + QString data_path; + // NAM Factory OPENetworkAccessManagerFactory *nam_factory; @@ -84,7 +150,7 @@ class AppModule : public QObject public: - explicit AppModule(QQmlApplicationEngine *parent = nullptr); + explicit AppModule(QQmlApplicationEngine *parent = nullptr, QString program_data_path = ""); ~AppModule(); Q_PROPERTY(QString wwwRoot READ wwwRoot WRITE setwwwRoot NOTIFY wwwRootChanged) @@ -110,6 +176,7 @@ public slots: bool desktopLaunch(QString url); // User folder where data can be stored + QString appStudentDataFolder(); QString appDataFolder(); QString dataFolder(); QString fileCacheFolder(); @@ -166,6 +233,8 @@ public slots: QString get_current_student_user(); + void sendAccessibilityEvent(QQuickItem *item, QAccessible::Event event_reason); + }; #endif // APPMODULE_H diff --git a/client_tools/lms/src/OPE_LMS/external/ex_canvas.cpp b/client_tools/lms/src/OPE_LMS/external/ex_canvas.cpp index 37029899..efba21b9 100644 --- a/client_tools/lms/src/OPE_LMS/external/ex_canvas.cpp +++ b/client_tools/lms/src/OPE_LMS/external/ex_canvas.cpp @@ -1963,7 +1963,7 @@ bool EX_Canvas::pullCourseFilesBinaries() // Get the local cache folder QDir base_dir; - base_dir.setPath(this->appDataFolder() + + base_dir.setPath(this->appStudentDataFolder() + "/content/www_root/canvas_file_cache/"); base_dir.mkpath(base_dir.path()); @@ -2010,6 +2010,21 @@ bool EX_Canvas::pullCourseFilesBinaries() // Download the file qDebug() << "Downloading file " << local_path; progressCurrentItem = f_filename; + + // https://github.com/operepo/ope/issues/144 + // Have to clear readonly flag or new download will fail. + QString fname = base_dir.path() + local_path; + DWORD fAttrs; + fAttrs = GetFileAttributes(fname.toStdWString().c_str()); + if (fAttrs == INVALID_FILE_ATTRIBUTES) { + qDebug() << "Error getting file attributes: " << fname << " -> " << GetLastError(); + } else { + if (SetFileAttributes(fname.toStdWString().c_str(), fAttrs ^ FILE_ATTRIBUTE_READONLY) == 0) { + // Error setting the attribute + qDebug() << "Error setting file attributes: " << fname << " " << int(fAttrs ^ FILE_ATTRIBUTE_READONLY) << " -> " << GetLastError(); + } + } + bool r = DownloadFile(f_url, base_dir.path() + local_path, "Canvas File: " + f_filename); if (!r) { @@ -2018,6 +2033,23 @@ bool EX_Canvas::pullCourseFilesBinaries() // Makre the file as present f.setValue("local_copy_present", "1"); + // https://github.com/operepo/ope/issues/144 + // Files that are downloaded in windows need to be marked as readonly so that word/excel/etc... + // require a save as rather then letting them open and save files in the cache folder which will be overwritten + // Mark file as readonly + QString fname = base_dir.path() + local_path; + DWORD fAttrs; + fAttrs = GetFileAttributes(fname.toStdWString().c_str()); + if (fAttrs == INVALID_FILE_ATTRIBUTES) { + qDebug() << "Error getting file attributes: " << fname << " -> " << GetLastError(); + } else { + if (SetFileAttributes(fname.toStdWString().c_str(), fAttrs | FILE_ATTRIBUTE_READONLY) == 0) { + // Error setting the attribute + qDebug() << "Error setting file attributes: " << fname << " " << int(fAttrs | FILE_ATTRIBUTE_READONLY) << " -> " << GetLastError(); + } + } + + // Make sure we save the content header /*QHash headers = web_request->GetAllDownloadHeaders(); if (headers.contains("Content-Type")) { @@ -2077,7 +2109,7 @@ bool EX_Canvas::pullCourseFilesBinaries() // Clear old file cache folder QDir old_cache_path; - old_cache_path.setPath(this->appDataFolder() + "/file_cache"); + old_cache_path.setPath(this->appStudentDataFolder() + "/file_cache"); foreach(QString f_name, old_cache_path.entryList()) { if (f_name == "." || f_name == ".." || f_name == "assignment_files") { // Skip these @@ -3016,7 +3048,7 @@ bool EX_Canvas::queueAssignmentFile(QString course_id, QString assignment_id, QS // Get the temp path for saving assignments QDir cache_path; - cache_path.setPath(this->appDataFolder() + "/file_cache/assignment_files"); + cache_path.setPath(this->appStudentDataFolder() + "/file_cache/assignment_files"); // Make sure the base folder exists cache_path.mkpath(cache_path.path()); @@ -3836,7 +3868,7 @@ bool EX_Canvas::pullSMCVideos() // Make sure our cache path exists // Get the local cache folder QDir base_dir; - base_dir.setPath(this->appDataFolder() + "/content/www_root/smc_video_cache/"); + base_dir.setPath(this->appStudentDataFolder() + "/content/www_root/smc_video_cache/"); base_dir.mkpath(base_dir.path()); // Get list of video IDs @@ -3933,7 +3965,7 @@ bool EX_Canvas::pullSMCDocuments() // Make sure our cache path exists QDir base_dir; - base_dir.setPath(this->appDataFolder() + "/content/www_root/smc_document_cache/"); + base_dir.setPath(this->appStudentDataFolder() + "/content/www_root/smc_document_cache/"); base_dir.mkpath(base_dir.path()); // Get the list of document ids @@ -4104,12 +4136,12 @@ bool EX_Canvas::setCurrentItem(QString item_text) return true; } -QString EX_Canvas::appDataFolder() +QString EX_Canvas::appStudentDataFolder() { // Cast appmodule back to its class AppModule *app_module = qobject_cast(this->parent()); - return app_module->appDataFolder(); + return app_module->appStudentDataFolder(); } QSqlRecord EX_Canvas::pullSinglePage(QString course_id, QString page_url) diff --git a/client_tools/lms/src/OPE_LMS/external/ex_canvas.h b/client_tools/lms/src/OPE_LMS/external/ex_canvas.h index 8cde6c67..3eceb66b 100644 --- a/client_tools/lms/src/OPE_LMS/external/ex_canvas.h +++ b/client_tools/lms/src/OPE_LMS/external/ex_canvas.h @@ -1,6 +1,8 @@ #ifndef EX_CANVAS_H #define EX_CANVAS_H +#include + #include #include #include @@ -141,7 +143,7 @@ public slots: bool setCurrentItem(QString item_text); // Get the appdata folder where we should put stuff - QString appDataFolder(); + QString appStudentDataFolder(); private: // ?? Still needed?? Only if using full OAUTH cycle diff --git a/client_tools/lms/src/OPE_LMS/main.cpp b/client_tools/lms/src/OPE_LMS/main.cpp index 93a206df..fb74c801 100644 --- a/client_tools/lms/src/OPE_LMS/main.cpp +++ b/client_tools/lms/src/OPE_LMS/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include // #include @@ -17,15 +18,13 @@ #include #include #include -#include #include -#include -#include +//#include #include -#include "openetworkaccessmanagerfactory.h" +//#include "openetworkaccessmanagerfactory.h" #include "appmodule.h" #include "customlogger.h" @@ -39,7 +38,7 @@ QString pgdata_path = ""; int main(int argc, char *argv[]) { // Dummy variable to force rebuild -#define rebuilding 5; +#define rebuilding 19; // Hide the console window #if defined( Q_OS_WIN ) @@ -112,35 +111,6 @@ int main(int argc, char *argv[]) log_to_file = false; } - // Prevent app from running twice - QString tmp_dir = QDir::tempPath(); - QLockFile lf(tmp_dir + "/ope_lms.lock"); - - if (!lf.tryLock(100)) - { - qDebug() << "=====================================================\n" << - "WARNING - App already running, exiting...\n" << - "only one instance allowed to run. If this is an " << - " error, remove the temp/ope_lms.lock file and try again" << - "=====================================================\n"; - out << "App already running..." << Qt::endl; - return 1; - } - - - // Show SSL info - qDebug() << "SSL Library Info: " << QSslSocket::supportsSsl() << QSslSocket::sslLibraryBuildVersionString() << QSslSocket::sslLibraryVersionString(); - - // Relax ssl config as we will be running through test certs - QSslConfiguration sslconf = QSslConfiguration::defaultConfiguration(); - QList cert_list = sslconf.caCertificates(); - QList cert_new = QSslCertificate::fromData("CaCertificates"); - cert_list += cert_new; - sslconf.setCaCertificates(cert_list); - sslconf.setProtocol(QSsl::AnyProtocol); - sslconf.setPeerVerifyMode(QSslSocket::VerifyNone); - sslconf.setSslOption(QSsl::SslOptionDisableServerNameIndication,true); - QSslConfiguration::setDefaultConfiguration(sslconf); QString last_arg = ""; //QCoreApplication::arguments().last(); last_arg = argv[argc-1]; @@ -177,10 +147,11 @@ int main(int argc, char *argv[]) return cmd_app.exec(); } - QGuiApplication app(argc, argv); - QTranslator translator; - bool translator_ret = translator.load(":/translations_en.qm"); - app.installTranslator(&translator); + //QGuiApplication app(argc, argv); + QApplication app(argc, argv); +// QTranslator translator; +// bool translator_ret = translator.load(":/translations_en.qm"); +// app.installTranslator(&translator); // Put our local folders as first path to look at for dlls QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + "/lib"); @@ -206,6 +177,14 @@ int main(int argc, char *argv[]) QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::AllowWindowActivationFromJavaScript, true); QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::PdfViewerEnabled, true); QWebEngineProfile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true); + // Disable accessibility in debug mode to prevent crash +/*#if defined( QT_DEBUG ) + qDebug() << "Disabling accessibility in debug mode..."; + QWebEngineProfile::defaultProfile()->setHttpUserAgent( + QWebEngineProfile::defaultProfile()->httpUserAgent() + " QTWEBENGINE_DISABLE_ACCESSIBILITY/1.0" + ); + QWebEngineProfile::defaultProfile()->setSpellCheckEnabled(false); +#endif*/ QQmlApplicationEngine engine; @@ -223,7 +202,6 @@ int main(int argc, char *argv[]) loadPage = "qrc:/not_credentialed.qml"; } - bool need_sync = false; if (last_arg == "sync" || appModule->hasAppSycnedWithCanvas() != true) { diff --git a/client_tools/lms/src/OPE_LMS/not_credentialed.qml b/client_tools/lms/src/OPE_LMS/not_credentialed.qml index f30cb2d5..dedb7eb0 100644 --- a/client_tools/lms/src/OPE_LMS/not_credentialed.qml +++ b/client_tools/lms/src/OPE_LMS/not_credentialed.qml @@ -8,7 +8,7 @@ import QtQuick.Layouts 1.15 import QtWebView 1.1 -import com.openprisoneducation.ope 1.0 +//import com.openprisoneducation.ope 1.0 import "App.js" as App ApplicationWindow {