From 6ad57a46615227aa8f1af63818744da9719a9c2d Mon Sep 17 00:00:00 2001 From: dorian Date: Tue, 25 Dec 2018 00:15:25 +0100 Subject: [PATCH] - commented code - added settingsForm basic grade filter for the events --- headers/serverconn.h | 2 +- qml/Forms/HomeForm.qml | 10 +- qml/Forms/SettingsForm.qml | 75 +++++++++ qml/Pages/LoginPage.qml | 53 ++++--- qml/Pages/MainPage.qml | 5 + qml/main.qml | 7 +- qml/qml.qrc | 1 + sources/appsettings.cpp | 3 + sources/serverconn.cpp | 310 ++++++++++++++++++++++--------------- 9 files changed, 309 insertions(+), 157 deletions(-) create mode 100644 qml/Forms/SettingsForm.qml diff --git a/headers/serverconn.h b/headers/serverconn.h index 1d4f812..ecd7ba2 100644 --- a/headers/serverconn.h +++ b/headers/serverconn.h @@ -36,7 +36,7 @@ public: public: explicit ServerConn(QObject *parent = nullptr); ~ServerConn(); - Q_INVOKABLE QString login(QString username, QString password, bool permanent); + Q_INVOKABLE int login(QString username, QString password, bool permanent); Q_INVOKABLE int logout(); Q_INVOKABLE QString getDay(QString day); Q_INVOKABLE int checkConn(); diff --git a/qml/Forms/HomeForm.qml b/qml/Forms/HomeForm.qml index 83dddfb..2377c76 100644 --- a/qml/Forms/HomeForm.qml +++ b/qml/Forms/HomeForm.qml @@ -21,9 +21,6 @@ Page { verticalCenter: parent.verticalCenter } -// width: childrenRect.width -// height: childrenRect.height - property int buttonHeight: app.landscape() ? root.height * (0.5*0.8):buttonWidth property int buttonWidth: app.landscape() ? buttonHeight:root.width * (0.5*0.8) @@ -144,6 +141,10 @@ Page { width: smallMenu.buttonWidth height: smallMenu.buttonHeight + + onClicked: { + formStack.push(settingsForm) + } } FancyButton { @@ -177,11 +178,10 @@ Page { } onAccepted: { _cppServerConn.logout() - app.state = "notLoggedInu" + app.state = "notLoggedIn" } } } } } - } diff --git a/qml/Forms/SettingsForm.qml b/qml/Forms/SettingsForm.qml new file mode 100644 index 0000000..34974c7 --- /dev/null +++ b/qml/Forms/SettingsForm.qml @@ -0,0 +1,75 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.4 + +Page { + id: root + + title: "Einstellungen" + + signal opened() + + onOpened: { + console.log("Home Form opened") + } + + Column { + id: settingsCol + + anchors.fill: parent + + ItemDelegate { + width: parent.width + height: 10 + shortDescription.height + 2 + longDescription.height + 10 + + Label { + id: shortDescription + + anchors { + top: parent.top + left: parent.left + margins: 10 + } + + font.pixelSize: longDescription.font.pixelSize * 1.4 + + text: "Klassenstufe" + + } + + Label { + id: longDescription + + anchors { + top: shortDescription.bottom + topMargin: 2 + left: parent.left + leftMargin: 10 + } + + width: parent.width - 10 - gradeSelect.width + + wrapMode: Label.Wrap + + text: "Wähle deine Klassenstufe aus, um den Vertretungsplan zu sortieren" + } + + SpinBox { + id: gradeSelect + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + + from: 5 + to: 12 + stepSize: 1 + value: _cppAppSettings.loadSetting("grade") + + onValueChanged: { + _cppAppSettings.writeSetting("grade", value) + } + } + } + } +} diff --git a/qml/Pages/LoginPage.qml b/qml/Pages/LoginPage.qml index fbd1663..e1b1637 100644 --- a/qml/Pages/LoginPage.qml +++ b/qml/Pages/LoginPage.qml @@ -7,10 +7,6 @@ Page { id: root objectName: "LoginPage"; - onHeightChanged: { - console.log(height) - } - header: AppToolBar { Label { text: "Anmeldung" @@ -210,31 +206,43 @@ Page { } function login(username, password, permanent){ + // hide the keyboard Qt.inputMethod.hide(); + // open the busy dialog busyDialog.open() + // disable the login button loginButton.enabled = false - loginButton.text = "Loggin in.." + // change the text to "Anmelden.." + loginButton.text = "Anmelden.." + console.log(username, password, permanent) + + // trigger the login fucntion of the cpp backend and store the return code var ret = _cppServerConn.login(username, password, permanent); + + // the request has finished + // close the busy dialog busyDialog.close() + // enable the button loginButton.enabled = true - loginButton.text = "Login" - if(ret === "OK"){ + // change the text of the login button back to "Anmelden" + loginButton.text = "Anmelden" + + // chekc if the login was successfull + if(ret === 200){ + // if it was -> set the app to inited and set the state of the app to loggedIn _cppAppSettings.writeSetting("init", 1); app.is_error = false; app.state = "loggedIn" } else{ - if(_cppAppSettings.loadSetting("permanent") === "1"){ - tiuname.text = _cppAppSettings.loadSetting("username") - tipasswd.text = _cppAppSettings.loadSetting("password") - _cppAppSettings.writeSetting("permanent", "0") - _cppAppSettings.writeSetting("username", "") - _cppAppSettings.writeSetting("password", "") - } - laStatus.text = ret + // if it wasn't -> reset the stored credentinals + _cppAppSettings.writeSetting("permanent", "0") + _cppAppSettings.writeSetting("username", "") + _cppAppSettings.writeSetting("password", "") + // and set the error label to the error short description of the retuned error code + laStatus.text = app.getErrorInfo(ret)[1] } - //root.qmlSignal(tiuname.text, tipasswd.text) } Dialog { @@ -242,14 +250,14 @@ Page { modal: true closePolicy: "NoAutoClose" focus: true - title: "Please wait..." + title: "Bitte warten..." x: (app.width - width) / 2 - y: window.height / 6 + y: (app.height - height) / 2 width: Math.min(window.width, window.height) / 3 * 2 height: 150 - contentHeight: aboutColumn.height + contentHeight: contentColumn.height Column { - id: aboutColumn + id: contentColumn spacing: 20 RowLayout { width: parent.width @@ -262,14 +270,11 @@ Page { Label { width: busyDialog.availableWidth - text: "logging in..." + text: "Anmelden..." wrapMode: Label.Wrap font.pixelSize: 12 } } } } - - - } diff --git a/qml/Pages/MainPage.qml b/qml/Pages/MainPage.qml index 2d6d285..7c521c7 100644 --- a/qml/Pages/MainPage.qml +++ b/qml/Pages/MainPage.qml @@ -56,6 +56,11 @@ Page { } } + Component { + id: settingsForm + SettingsForm {} + } + popEnter: Transition { XAnimator { from: (formStack.mirrored ? -1 : 1) * -formStack.width diff --git a/qml/main.qml b/qml/main.qml index dee4499..e0d55aa 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -88,7 +88,7 @@ ApplicationWindow { else { ret = _cppServerConn.checkConn() - handleError(ret) + app.handleError(ret) } } else { @@ -187,6 +187,11 @@ ApplicationWindow { errorString = "Keine Verbindung zum Server" errorDescription = "Bitte überprüfe deine Internetverbindung und versuche es erneut." break + case 401: + infoLevel = 2 + errorString = "Ungültige Zugangsdaten" + errorDescription = "Der Server hat den Zugang verweigert, bitte überprüfe deine Zugangsdaten und versuche es erneut" + break case 500: infoLevel = 2 errorString = "Interner Server Fehler" diff --git a/qml/qml.qrc b/qml/qml.qrc index a500861..3f68976 100644 --- a/qml/qml.qrc +++ b/qml/qml.qrc @@ -13,5 +13,6 @@ Forms/LoadingForm.qml Components/EventView.qml Components/InfoArea.qml + Forms/SettingsForm.qml diff --git a/sources/appsettings.cpp b/sources/appsettings.cpp index 6e75da1..5a5c7a8 100644 --- a/sources/appsettings.cpp +++ b/sources/appsettings.cpp @@ -13,6 +13,9 @@ AppSettings::AppSettings(QObject* parent) if(loadSetting("init") == "false"){ this->writeSetting("init", 0); } + if(loadSetting("grade") == "false"){ + this->writeSetting("grade", 5); + } } QString AppSettings::loadSetting(const QString &key) diff --git a/sources/serverconn.cpp b/sources/serverconn.cpp index 0a4b91e..e5f0882 100644 --- a/sources/serverconn.cpp +++ b/sources/serverconn.cpp @@ -21,63 +21,81 @@ ServerConn::~ServerConn() dir.removeRecursively(); } -QString ServerConn::login(QString username, QString password, bool permanent) +int ServerConn::login(QString username, QString password, bool permanent) { // QUrlQuery pdata; // ReturnData_t ret = this->senddata(QUrl("http://www.fanny-leicht.de/static15/http.intern/sheute.pdf"), pdata); // qDebug() << ret.text; - // Create request + // Create network request QNetworkRequest request; - request.setUrl( QUrl( "http://www.fanny-leicht.de/static15/http.intern/sheute.pdf" ) ); + // call a non-existent file to be fast + request.setUrl( QUrl( "http://www.fanny-leicht.de/static15/http.intern/logintest" ) ); - // Pack in credentials - QString concatenatedCredentials = username + ":" + password; - QByteArray data = concatenatedCredentials.toLocal8Bit().toBase64(); + // pack the credentials into a string + QString credentialsString = username + ":" + password; + // convert it to a byte array + QByteArray data = credentialsString.toLocal8Bit().toBase64(); + // put it into a string QString headerData = "Basic " + data; + // and finally write it into the request header request.setRawHeader( "Authorization", headerData.toLocal8Bit() ); - QUrlQuery pdata; + //QUrlQuery pdata; // Send request and connect all possible signals - QNetworkReply*reply = this->networkManager->post(request, pdata.toString(QUrl::FullyEncoded).toUtf8()); - //QNetworkReply*reply = networkManager->get( request ); + //QNetworkReply*reply = this->networkManager->post(request, pdata.toString(QUrl::FullyEncoded).toUtf8()); + QNetworkReply*reply = networkManager->get( request ); + // loop to wait until the request has finished before processing the data QEventLoop loop; + // timer to cancel the request after 3 seconds + QTimer timer; + timer.setSingleShot(true); + + // quit the loop when the request finised loop.connect(this->networkManager, SIGNAL(finished(QNetworkReply*)), SLOT(quit())); + // or the timer timed out + loop.connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + // start the timer + timer.start(2000); + // start the loop loop.exec(); + + // get the status code from the request int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if(status_code == 200){ + // 404 is a success because a non existent file was called and not 401 was returned -> user data was correct + if(status_code == 404){ + // store username and password in the class variables this->username = username; this->password = password; + if(permanent){ - qDebug() << "permanent"; + // if the user wants to say logged in, store the username and password to the settings file pGlobalAppSettings->writeSetting("permanent", "1"); pGlobalAppSettings->writeSetting("username", username); pGlobalAppSettings->writeSetting("password", password); } - return("OK"); - } - else if(status_code == 401){ - return("Ungültige Benutzerdaten."); - } - else if(status_code == 0){ - return("Keine Verbindung zum Server."); + + // return success + return(200); } else { - QString ret = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toChar(); - ret = ret + reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toChar(); - return(ret); + // if not 404 was returned -> error -> return the return code + return(status_code); } } int ServerConn::logout() { + // reset the data stored in the class this->username = ""; this->password = ""; + // reset the data stored in the settings pGlobalAppSettings->writeSetting("permanent", "0"); pGlobalAppSettings->writeSetting("username", ""); pGlobalAppSettings->writeSetting("password", ""); + // return success return(200); } @@ -143,8 +161,7 @@ int ServerConn::checkConn() request.setUrl( QUrl( "http://www.fanny-leicht.de/static15/http.intern/" ) ); // Pack in credentials - // Pack in credentials - //ZedlerDo:LxyJQB + // e.g. ZedlerDo:LxyJQB (yes, these do actually work ;) QString concatenatedCredentials = this->username + ":" + this->password; QByteArray data = concatenatedCredentials.toLocal8Bit().toBase64(); QString headerData = "Basic " + data; @@ -161,16 +178,15 @@ int ServerConn::checkConn() int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); return(status_code); - } void ServerConn::updateProgress(qint64 read, qint64 total) { - int read_int = read; - int total_int = total; - float percent = ((float)read_int / (float)total_int); + int read_int = int(read); + int total_int = int(total); + float percent = (float(read_int) / float(total_int)); this->progress = percent; - percent = (int)percent; + percent = int(percent); // qDebug() << read << total << percent << "%"; } @@ -222,70 +238,117 @@ int ServerConn::getEvents(QString day){ } QString eventString = textFile->readAll(); + + // separate all lines into a list QStringList events = eventString.split("\n"); + // a line (one element of the list) looks like this: + // class hour replace subject room to text + // 8a 1-2 Ei Ch --- Entfall KEINE KA + // [ ] <-- at least two spaces + // to OR text can be blank + + // temporary list to store the events for the given day QList tmpEvents; - // 8a 1-2 Ei Ch --- Entfall KEINE KA - + // go through the list and process every single row foreach(QString event, events){ + // value to count spaces between text int spaceCount = 0; + + // temporary list to store the data of one day QStringList dayList; + + // temporary dtring to store the data of one block QString tmpString; + + // processing works like: + // go through the line char by char for(int i = 0;i < event.length(); i++){ + // store the char temporarly QCharRef tmpChar = event[i]; + + // check if the char is a space if(tmpChar == " "){ + // if so, increase the spaceCount by one spaceCount ++; } else { + // if not -> new block or part of a block started + // could be : 8a 1 - 2 OR 8a 1 - 2 + // here->| OR here->| + // in the first case, the space counter is higer than one + // in the second case, the space counter is exactly one if(spaceCount == 1){ + // -> append a space to the temp string tmpString.append(" "); } + + // reset the space counter spaceCount = 0; + + // append the current character tmpString.append(tmpChar); } + // check if the soace count is 2 if(spaceCount == 2){ + // if so -> break between two blocks + // could be: 8a 1 - 2 OR 8a 1 - 2 + // here ->| + + // -> append the current tmpString to the dayList dayList.append(tmpString); + + // and clear the tmpString tmpString = ""; } qDebug() << "char= " << tmpChar << " string= " << tmpString << " list= " << dayList; } + // append the remaining tmpString to the dayList dayList.append(tmpString); + // fill up the dayList with blanks until it reaches the defined length while (dayList.length() < 7) { dayList.append(""); } - tmpEvents.append(dayList); - + // if the event matches the filter + if(dayList[0].contains(pGlobalAppSettings->loadSetting("grade"))){ + // append the dayList to the temporary event list + tmpEvents.append(dayList); + } } + // store the new events into the class variable this->m_events = tmpEvents; qDebug() << tmpEvents; -/* - qDebug() << "reading xml file"; - QFile * xmlFile = new QFile(":/samplehtml/Download File.xml"); - if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) { - qDebug() << "Load XML File Problem Couldn't open xmlfile.xml to load settings for download"; - return 900; - } - - //QXmlStreamReader * xmlReader = new QXmlStreamReader(eventString); - QXmlStreamReader * xmlReader = new QXmlStreamReader(xmlFile); - //qDebug() << xmlFile->readAll(); - QList tmpEvents; - QStringList dayList; - while (dayList.length() < 7) { - dayList.append(""); - } - - int currTop = 0; + // return success + return(200); /* + qDebug() << "reading xml file"; + QFile * xmlFile = new QFile(":/samplehtml/Download File.xml"); + if (!xmlFile->open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "Load XML File Problem Couldn't open xmlfile.xml to load settings for download"; + return 900; + } + + //QXmlStreamReader * xmlReader = new QXmlStreamReader(eventString); + QXmlStreamReader * xmlReader = new QXmlStreamReader(xmlFile); + //qDebug() << xmlFile->readAll(); + QList tmpEvents; + QStringList dayList; + while (dayList.length() < 7) { + dayList.append(""); + } + + int currTop = 0; + + 8a 1 - 2 Ei @@ -294,101 +357,96 @@ int ServerConn::getEvents(QString day){ Entfall KEINE KA -5abc 1 -We -KR ---- -Entfall + 5abc 1 + We + KR + --- + Entfall -#define eventXmlPosGrade 3 -#define eventXmlPosHour 55 -#define eventXmlPosReplace 123 -#define eventXmlPosSubject 178 -#define eventXmlPosRoom 233 -#define eventXmlPosTo 275 -#define eventXmlPosText 391 + #define eventXmlPosGrade 3 + #define eventXmlPosHour 55 + #define eventXmlPosReplace 123 + #define eventXmlPosSubject 178 + #define eventXmlPosRoom 233 + #define eventXmlPosTo 275 + #define eventXmlPosText 391 - QList eventXmlPositions = {eventXmlPosGrade,eventXmlPosHour,eventXmlPosReplace,eventXmlPosSubject,eventXmlPosRoom,eventXmlPosTo,eventXmlPosText}; - qDebug() << "start xml parsing"; - //Parse the XML until we reach end of it - while(!xmlReader->atEnd()) { - if (xmlReader->readNextStartElement()) { - // read next element + QList eventXmlPositions = {eventXmlPosGrade,eventXmlPosHour,eventXmlPosReplace,eventXmlPosSubject,eventXmlPosRoom,eventXmlPosTo,eventXmlPosText}; + qDebug() << "start xml parsing"; + //Parse the XML until we reach end of it + while(!xmlReader->atEnd()) { + if (xmlReader->readNextStartElement()) { + // read next element - if (xmlReader->name().toString() == "text"){ - // text element found - QXmlStreamAttributes attributes = xmlReader->attributes(); - QString attribute_value; - int top; + if (xmlReader->name().toString() == "text"){ + // text element found + QXmlStreamAttributes attributes = xmlReader->attributes(); + QString attribute_value; + int top; - if(attributes.hasAttribute("font")){ - attribute_value = attributes.value("font").toString(); - } - - if(attributes.hasAttribute("top")){ - // get the y-Position of the text - - top = attributes.value("top").toInt(); - - if(abs(top - currTop) > 3){ - // new line started - - if(currTop > 175){ - // if not header -> append - qDebug() << dayList; - tmpEvents.append(dayList); - } - - dayList.clear(); - while (dayList.length() < 7) { - dayList.append(""); - } - currTop = top; + if(attributes.hasAttribute("font")){ + attribute_value = attributes.value("font").toString(); } - if(attributes.hasAttribute("left")){ - int left = attributes.value("left").toInt(); - QString text = xmlReader->readElementText(QXmlStreamReader::IncludeChildElements); - qDebug() << text; - for(int i = 0;i<7;i++){ - //qDebug() << i << left << abs(left - eventXmlPositions[i]); - if(abs(left - eventXmlPositions[i]) < 30){ - dayList[i] = text; - //qDebug() << i << left << text << dayList << left << abs(left - eventXmlPositions[i]); + if(attributes.hasAttribute("top")){ + // get the y-Position of the text + + top = attributes.value("top").toInt(); + + if(abs(top - currTop) > 3){ + // new line started + + if(currTop > 175){ + // if not header -> append + qDebug() << dayList; + tmpEvents.append(dayList); + } + + dayList.clear(); + while (dayList.length() < 7) { + dayList.append(""); + } + currTop = top; + } + + if(attributes.hasAttribute("left")){ + int left = attributes.value("left").toInt(); + QString text = xmlReader->readElementText(QXmlStreamReader::IncludeChildElements); + qDebug() << text; + for(int i = 0;i<7;i++){ + //qDebug() << i << left << abs(left - eventXmlPositions[i]); + if(abs(left - eventXmlPositions[i]) < 30){ + dayList[i] = text; + //qDebug() << i << left << text << dayList << left << abs(left - eventXmlPositions[i]); + } } } - } + else { + qDebug() << " no left"; + } + + } else { - qDebug() << " no left"; + qDebug() << " no top"; } - - } - else { - qDebug() << " no top"; } } } - } - this->m_events = tmpEvents; + this->m_events = tmpEvents; - if(xmlReader->hasError()) { - qDebug() << "xmlFile.xml Parse Error" << xmlReader->errorString(); - //return(900); - } + if(xmlReader->hasError()) { + qDebug() << "xmlFile.xml Parse Error" << xmlReader->errorString(); + //return(900); + } - //close reader and flush file - xmlReader->clear(); - xmlFile->close(); - */ + //close reader and flush file + xmlReader->clear(); + xmlFile->close(); + */ - foreach(QListday, this->m_events){ - qDebug() << day; - } - - return(200); } int ServerConn::getFoodPlan()