diff --git a/jceGrade.pro b/jceGrade.pro index a2c9e16..3a9950b 100644 --- a/jceGrade.pro +++ b/jceGrade.pro @@ -36,7 +36,9 @@ HEADERS += \ src/jceSettings/jceLoginHtmlScripts.h \ src/jceSettings/user.h \ src/jceData/Calendar/calendarCourse.h \ - src/jceData/Calendar/calendarSchedule.h + src/jceData/Calendar/calendarSchedule.h \ + src/jceData/CSV/csv_exporter.h \ + src/appDatabase/simplecrypt.h SOURCES += \ main/CalendarTab/CalendarManager.cpp \ @@ -53,5 +55,7 @@ SOURCES += \ src/jceSettings/jcelogin.cpp \ src/jceSettings/user.cpp \ src/jceData/Calendar/calendarCourse.cpp \ - src/jceData/Calendar/calendarSchedule.cpp + src/jceData/Calendar/calendarSchedule.cpp \ + src/jceData/CSV/csv_exporter.cpp \ + src/appDatabase/simplecrypt.cpp diff --git a/main/CalendarTab/CalendarManager.cpp b/main/CalendarTab/CalendarManager.cpp index ebb9899..addeaac 100644 --- a/main/CalendarTab/CalendarManager.cpp +++ b/main/CalendarTab/CalendarManager.cpp @@ -9,3 +9,8 @@ void CalendarManager::setCalendar(std::string html) { caliSchedPtr->setPage(html); } + +calendarSchedule *CalendarManager::getSch() +{ + return this->caliSchedPtr; +} diff --git a/main/CalendarTab/CalendarManager.h b/main/CalendarTab/CalendarManager.h index 042e831..e7a9737 100644 --- a/main/CalendarTab/CalendarManager.h +++ b/main/CalendarTab/CalendarManager.h @@ -16,6 +16,7 @@ public: void setCalendar(std::string html); void resetTable() { if (caliSchedPtr != NULL) caliSchedPtr->clearTableItems(); } + calendarSchedule* getSch(); private: calendarSchedule * caliSchedPtr; }; diff --git a/main/mainscreen.cpp b/main/mainscreen.cpp index bb26fc3..b7f4d6b 100644 --- a/main/mainscreen.cpp +++ b/main/mainscreen.cpp @@ -291,3 +291,20 @@ void MainScreen::on_actionHow_To_triggered() ""); } + +void MainScreen::on_pushButton_2_clicked() +{ + if(CSV_Exporter::exportCalendar(this->calendar->getSch())) + { + QMessageBox msgBox; + msgBox.setText("
Exported Successfuly!
HaazZaA!!"); + msgBox.exec(); + }else + { + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Critical); + msgBox.setText("
Something went wrong...
Maybe:

" + "
In case of a serious problem, please file a bug report.
thank you. OpenJCE teem"); + msgBox.exec(); + } +} diff --git a/main/mainscreen.h b/main/mainscreen.h index 2ea31d2..0c68e4b 100644 --- a/main/mainscreen.h +++ b/main/mainscreen.h @@ -13,6 +13,7 @@ #include "./CourseTab/coursestablemanager.h" #include "./LoginTab/loginhandler.h" #include "./CalendarTab/CalendarManager.h" +#include "../src/jceData/CSV/csv_exporter.h" #define StatusIconHeight 35 namespace Ui { @@ -59,6 +60,8 @@ private slots: void on_checkBoxCoursesInfluence_toggled(bool checked); + void on_pushButton_2_clicked(); + private: void uiSetDisconnectMode(); diff --git a/main/mainscreen.ui b/main/mainscreen.ui index df3cece..a9c42a5 100644 --- a/main/mainscreen.ui +++ b/main/mainscreen.ui @@ -588,6 +588,13 @@ font-size: 15px; + + + + Export to CSV + + + @@ -619,7 +626,7 @@ font-size: 15px; 0 0 855 - 21 + 29 diff --git a/src/appDatabase/savedata.cpp b/src/appDatabase/savedata.cpp index edb1815..107f7fa 100644 --- a/src/appDatabase/savedata.cpp +++ b/src/appDatabase/savedata.cpp @@ -42,7 +42,7 @@ void SaveData::setUsername(QString username) void SaveData::setPassword(QString password) { - DB.insert("password", password); + DB.insert("password", encrypt(password)); save(); } @@ -65,7 +65,7 @@ QString SaveData::getUsername() QString SaveData::getPassword() { - return DB.value("password"); + return decrypte(DB.value("password")); } QString SaveData::getLocal() @@ -106,3 +106,15 @@ void SaveData::createDB() DB.insert("local", "default"); DB.insert("calendar", ""); } + +QString SaveData::encrypt(QString pass) +{ + SimpleCrypt crypto(Q_UINT64_C(0x0c2ad4a4acb9f027)); + return crypto.encryptToString(pass); +} + +QString SaveData::decrypte(QString pass) +{ + SimpleCrypt crypto(Q_UINT64_C(0x0c2ad4a4acb9f027)); + return crypto.decryptToString(pass); +} diff --git a/src/appDatabase/savedata.h b/src/appDatabase/savedata.h index 3952e22..f387282 100644 --- a/src/appDatabase/savedata.h +++ b/src/appDatabase/savedata.h @@ -29,6 +29,7 @@ #include #include #include +#include "simplecrypt.h" #define FILE_NAME "JAC_DB.dat" @@ -52,6 +53,9 @@ private: void load(); void save(); void createDB(); + QString encrypt(QString pass); + QString decrypte(QString pass); + }; #endif // SAVEDATA_H diff --git a/src/appDatabase/simplecrypt.cpp b/src/appDatabase/simplecrypt.cpp new file mode 100644 index 0000000..df882ef --- /dev/null +++ b/src/appDatabase/simplecrypt.cpp @@ -0,0 +1,255 @@ +/* +Copyright (c) 2011, Andre Somers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Rathenau Instituut, Andre Somers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* + * Fixed By Sagi Dayan + */ +#include "simplecrypt.h" +#include +#include +#include +#include +#include + +SimpleCrypt::SimpleCrypt(): + m_key(0), + m_compressionMode(CompressionAuto), + m_protectionMode(ProtectionChecksum), + m_lastError(ErrorNoError) +{ + qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); +} + +SimpleCrypt::SimpleCrypt(quint64 key): + m_key(key), + m_compressionMode(CompressionAuto), + m_protectionMode(ProtectionChecksum), + m_lastError(ErrorNoError) +{ + qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF)); + splitKey(); +} + +void SimpleCrypt::setKey(quint64 key) +{ + m_key = key; + splitKey(); +} + +void SimpleCrypt::splitKey() +{ + m_keyParts.clear(); + m_keyParts.resize(8); + for (int i=0;i<8;i++) { + quint64 part = m_key; + for (int j=i; j>0; j--) + part = part >> 8; + part = part & 0xff; + m_keyParts[i] = static_cast(part); + } +} + +QByteArray SimpleCrypt::encryptToByteArray(const QString& plaintext) +{ + QByteArray plaintextArray = plaintext.toUtf8(); + return encryptToByteArray(plaintextArray); +} + +QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) +{ + if (m_keyParts.isEmpty()) { + qWarning() << "No key set."; + m_lastError = ErrorNoKeySet; + return QByteArray(); + } + + + QByteArray ba = plaintext; + + CryptoFlags flags = CryptoFlagNone; + if (m_compressionMode == CompressionAlways) { + ba = qCompress(ba, 9); //maximum compression + flags |= CryptoFlagCompression; + } else if (m_compressionMode == CompressionAuto) { + QByteArray compressed = qCompress(ba, 9); + if (compressed.count() < ba.count()) { + ba = compressed; + flags |= CryptoFlagCompression; + } + } + + QByteArray integrityProtection; + if (m_protectionMode == ProtectionChecksum) { + flags |= CryptoFlagChecksum; + QDataStream s(&integrityProtection, QIODevice::WriteOnly); + s << qChecksum(ba.constData(), ba.length()); + } else if (m_protectionMode == ProtectionHash) { + flags |= CryptoFlagHash; + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(ba); + + integrityProtection += hash.result(); + } + + //prepend a random char to the string + char randomChar = char(qrand() & 0xFF); + ba = randomChar + integrityProtection + ba; + + int pos(0); + char lastChar(0); + + int cnt = ba.count(); + + while (pos < cnt) { + ba[pos] = ba.at(pos) ^ m_keyParts.at(pos % 8) ^ lastChar; + lastChar = ba.at(pos); + ++pos; + } + + QByteArray resultArray; + resultArray.append(char(0x03)); //version for future updates to algorithm + resultArray.append(char(flags)); //encryption flags + resultArray.append(ba); + + m_lastError = ErrorNoError; + return resultArray; +} + +QString SimpleCrypt::encryptToString(const QString& plaintext) +{ + QByteArray plaintextArray = plaintext.toUtf8(); + QByteArray cypher = encryptToByteArray(plaintextArray); + QString cypherString = QString(cypher.toBase64()); + return cypherString; +} + +QString SimpleCrypt::encryptToString(QByteArray plaintext) +{ + QByteArray cypher = encryptToByteArray(plaintext); + QString cypherString = QString(cypher.toBase64()); + return cypherString; +} + +QString SimpleCrypt::decryptToString(const QString &cyphertext) +{ + QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); + QByteArray plaintextArray = decryptToByteArray(cyphertextArray); + QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size()); + + return plaintext; +} + +QString SimpleCrypt::decryptToString(QByteArray cypher) +{ + QByteArray ba = decryptToByteArray(cypher); + QString plaintext = QString::fromUtf8(ba, ba.size()); + + return plaintext; +} + +QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext) +{ + QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); + QByteArray ba = decryptToByteArray(cyphertextArray); + + return ba; +} + +QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) +{ + if (m_keyParts.isEmpty()) { + qWarning() << "No key set."; + m_lastError = ErrorNoKeySet; + return QByteArray(); + } + + QByteArray ba = cypher; + + if( cypher.count() < 3 ) + return QByteArray(); + + char version = ba.at(0); + + if (version !=3) { //we only work with version 3 + m_lastError = ErrorUnknownVersion; + qWarning() << "Invalid version or not a cyphertext."; + return QByteArray(); + } + + CryptoFlags flags = CryptoFlags(ba.at(1)); + + ba = ba.mid(2); + int pos(0); + int cnt(ba.count()); + char lastChar = 0; + + while (pos < cnt) { + char currentChar = ba[pos]; + ba[pos] = ba.at(pos) ^ lastChar ^ m_keyParts.at(pos % 8); + lastChar = currentChar; + ++pos; + } + + ba = ba.mid(1); //chop off the random number at the start + + bool integrityOk(true); + if (flags.testFlag(CryptoFlagChecksum)) { + if (ba.length() < 2) { + m_lastError = ErrorIntegrityFailed; + return QByteArray(); + } + quint16 storedChecksum; + { + QDataStream s(&ba, QIODevice::ReadOnly); + s >> storedChecksum; + } + ba = ba.mid(2); + quint16 checksum = qChecksum(ba.constData(), ba.length()); + integrityOk = (checksum == storedChecksum); + } else if (flags.testFlag(CryptoFlagHash)) { + if (ba.length() < 20) { + m_lastError = ErrorIntegrityFailed; + return QByteArray(); + } + QByteArray storedHash = ba.left(20); + ba = ba.mid(20); + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(ba); + integrityOk = (hash.result() == storedHash); + } + + if (!integrityOk) { + m_lastError = ErrorIntegrityFailed; + return QByteArray(); + } + + if (flags.testFlag(CryptoFlagCompression)) + ba = qUncompress(ba); + + m_lastError = ErrorNoError; + return ba; +} diff --git a/src/appDatabase/simplecrypt.h b/src/appDatabase/simplecrypt.h new file mode 100644 index 0000000..7f1e80a --- /dev/null +++ b/src/appDatabase/simplecrypt.h @@ -0,0 +1,229 @@ +/* +Copyright (c) 2011, Andre Somers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Rathenau Instituut, Andre Somers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SIMPLECRYPT_H +#define SIMPLECRYPT_H +#include +#include +#include + +/** + @short Simple encryption and decryption of strings and byte arrays + + This class provides a simple implementation of encryption and decryption + of strings and byte arrays. + + @warning The encryption provided by this class is NOT strong encryption. It may + help to shield things from curious eyes, but it will NOT stand up to someone + determined to break the encryption. Don't say you were not warned. + + The class uses a 64 bit key. Simply create an instance of the class, set the key, + and use the encryptToString() method to calculate an encrypted version of the input string. + To decrypt that string again, use an instance of SimpleCrypt initialized with + the same key, and call the decryptToString() method with the encrypted string. If the key + matches, the decrypted version of the string will be returned again. + + If you do not provide a key, or if something else is wrong, the encryption and + decryption function will return an empty string or will return a string containing nonsense. + lastError() will return a value indicating if the method was succesful, and if not, why not. + + SimpleCrypt is prepared for the case that the encryption and decryption + algorithm is changed in a later version, by prepending a version identifier to the cypertext. + */ + +/* + * Fixed By Sagi Dayan + */ +class SimpleCrypt +{ +public: + /** + CompressionMode describes if compression will be applied to the data to be + encrypted. + */ + enum CompressionMode { + CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */ + CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */ + CompressionNever /*!< Never apply compression. */ + }; + /** + IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data + or wrong decryption keys. + + Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This + increases the length of the resulting cypertext, but makes it possible to check if the plaintext + appears to be valid after decryption. + */ + enum IntegrityProtectionMode { + ProtectionNone, /*!< The integerity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */ + ProtectionChecksum,/*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */ + ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */ + }; + /** + Error describes the type of error that occured. + */ + enum Error { + ErrorNoError, /*!< No error occurred. */ + ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */ + ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */ + ErrorIntegrityFailed, /*!< The integrity check of the data failed. Perhaps the wrong key was used. */ + }; + + /** + Constructor. + + Constructs a SimpleCrypt instance without a valid key set on it. + */ + SimpleCrypt(); + /** + Constructor. + + Constructs a SimpleCrypt instance and initializes it with the given @arg key. + */ + explicit SimpleCrypt(quint64 key); + + /** + (Re-) initializes the key with the given @arg key. + */ + void setKey(quint64 key); + /** + Returns true if SimpleCrypt has been initialized with a key. + */ + bool hasKey() const {return !m_keyParts.isEmpty();} + + /** + Sets the compression mode to use when encrypting data. The default mode is Auto. + + Note that decryption is not influenced by this mode, as the decryption recognizes + what mode was used when encrypting. + */ + void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;} + /** + Returns the CompressionMode that is currently in use. + */ + CompressionMode compressionMode() const {return m_compressionMode;} + + /** + Sets the integrity mode to use when encrypting data. The default mode is Checksum. + + Note that decryption is not influenced by this mode, as the decryption recognizes + what mode was used when encrypting. + */ + void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;} + /** + Returns the IntegrityProtectionMode that is currently in use. + */ + IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;} + + /** + Returns the last error that occurred. + */ + Error lastError() const {return m_lastError;} + + /** + Encrypts the @arg plaintext string with the key the class was initialized with, and returns + a cyphertext the result. The result is a base64 encoded version of the binary array that is the + actual result of the string, so it can be stored easily in a text format. + */ + QString encryptToString(const QString& plaintext) ; + /** + Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns + a cyphertext the result. The result is a base64 encoded version of the binary array that is the + actual result of the encryption, so it can be stored easily in a text format. + */ + QString encryptToString(QByteArray plaintext) ; + /** + Encrypts the @arg plaintext string with the key the class was initialized with, and returns + a binary cyphertext in a QByteArray the result. + + This method returns a byte array, that is useable for storing a binary format. If you need + a string you can store in a text file, use encryptToString() instead. + */ + QByteArray encryptToByteArray(const QString& plaintext) ; + /** + Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns + a binary cyphertext in a QByteArray the result. + + This method returns a byte array, that is useable for storing a binary format. If you need + a string you can store in a text file, use encryptToString() instead. + */ + QByteArray encryptToByteArray(QByteArray plaintext) ; + + /** + Decrypts a cyphertext string encrypted with this class with the set key back to the + plain text version. + + If an error occured, such as non-matching keys between encryption and decryption, + an empty string or a string containing nonsense may be returned. + */ + QString decryptToString(const QString& cyphertext) ; + /** + Decrypts a cyphertext string encrypted with this class with the set key back to the + plain text version. + + If an error occured, such as non-matching keys between encryption and decryption, + an empty string or a string containing nonsense may be returned. + */ + QByteArray decryptToByteArray(const QString& cyphertext) ; + /** + Decrypts a cyphertext binary encrypted with this class with the set key back to the + plain text version. + + If an error occured, such as non-matching keys between encryption and decryption, + an empty string or a string containing nonsense may be returned. + */ + QString decryptToString(QByteArray cypher) ; + /** + Decrypts a cyphertext binary encrypted with this class with the set key back to the + plain text version. + + If an error occured, such as non-matching keys between encryption and decryption, + an empty string or a string containing nonsense may be returned. + */ + QByteArray decryptToByteArray(QByteArray cypher) ; + + //enum to describe options that have been used for the encryption. Currently only one, but + //that only leaves room for future extensions like adding a cryptographic hash... + enum CryptoFlag{CryptoFlagNone = 0, + CryptoFlagCompression = 0x01, + CryptoFlagChecksum = 0x02, + CryptoFlagHash = 0x04 + }; + Q_DECLARE_FLAGS(CryptoFlags, CryptoFlag); +private: + + void splitKey(); + + quint64 m_key; + QVector m_keyParts; + CompressionMode m_compressionMode; + IntegrityProtectionMode m_protectionMode; + Error m_lastError; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(SimpleCrypt::CryptoFlags) + +#endif // SimpleCrypt_H diff --git a/src/jceData/CSV/csv_exporter.cpp b/src/jceData/CSV/csv_exporter.cpp new file mode 100644 index 0000000..dc2159e --- /dev/null +++ b/src/jceData/CSV/csv_exporter.cpp @@ -0,0 +1,145 @@ +#include "csv_exporter.h" + +CSV_Exporter::CSV_Exporter() +{ + +} + +bool CSV_Exporter::exportCalendar(calendarSchedule *calSched) +{ + qDebug() << "Getting path for csv file from user..."; + QString filePath = getFileFath(); + if(filePath == NULL) //User canceled + { + qDebug() << "User pressed Cancel... returning false"; + return false; + } + qDebug() << "User Chose: " << filePath; + qDebug() << "Atempting to export the Schedule..."; + + QFile file(filePath); + if(!file.open(QIODevice::ReadWrite | QIODevice::Text)) + { + qDebug() << "unable to open/create the file... maybe permissions error."; + return false; + }//else + + QTextStream out(&file); + out << CSV_CALENDAR_HEADER << "\n"; + for (calendarCourse *coursePtr: *(calSched->getCourses())) + { + // Subject,Start Date,Start Time,End Date,End Time,Description,Location + int day = coursePtr->getDay(); + int startH = coursePtr->getHourBegin(); + int startM = coursePtr->getMinutesBegin(); + int endH = coursePtr->getHourEnd(); + int endM = coursePtr->getMinutesEnd(); + QString lecturer = QString(coursePtr->getLecturer().c_str()); //WHY YOU USED STD STRING?! + QString type = QString(coursePtr->getType().c_str()); + QString name = QString(coursePtr->getName().c_str()); + QString room = QString(coursePtr->getRoom().c_str()); + + QString line = makeLine(name, day, startH, startM, endH, endM, lecturer, room, type); + if(line != NULL) + out << line << char(0x0A); + } + + + out.flush(); + + + file.close(); + qDebug() << "Saved Successfuly! - HazZaA!"; + return true; + +} + +QString CSV_Exporter::getFileFath() +{ + QString fileName = QFileDialog::getSaveFileName(); + if(fileName == "") + return NULL; + fileName.append(".csv"); + return fileName; +} + +QString CSV_Exporter::makeLine(QString name, int day, int startH, int startM, int endH, int endM, QString lecturer, QString room, QString type) +{ + //Creating a CSV text line for Google Calendar/iCal/Outlook + // First day for semester 10/26/2014 + + QString CSV_line = ""; + QString subject = "\""; + subject.append(name); + subject.append(" - "); + subject.append(type); + subject.append("\""); + + QString date; + switch (day) { + case 1: + date = "10/26/2014"; + break; + case 2: + date = "10/27/2014"; + break; + case 3: + date = "10/28/2014"; + break; + case 4: + date = "10/29/2014"; + break; + case 5: + date = "10/30/2014"; + break; + case 6: + date = "10/31/2014"; + break; + default: + return NULL; + break; + } + + QString start; + start.append(QString::number(startH)); + start.append(":00"); + //start.append(QString::number(startM)); + start.append(":00"); + + QString end; + end.append(QString::number(endH)); + end.append(":"); + end.append(QString::number(endM)); + end.append(":00"); + + QString description = "\"מרצה "; + description.append(lecturer); + description.append("\n"); + description.append(" ב"); + description.append(room); + description.append("\""); + + //Create the Fucking Line + //Header: Subject,Start Date,Start Time,End Date,End Time,Description,Location + CSV_line.append(subject); + CSV_line.append(","); + + CSV_line.append(date); + CSV_line.append(","); + + CSV_line.append(start); + CSV_line.append(","); + + CSV_line.append(date); + CSV_line.append(","); + + CSV_line.append(end); + CSV_line.append(","); + + CSV_line.append(description); + CSV_line.append(","); + + CSV_line.append("\"JCE Jerusalem\""); + + return CSV_line; +} diff --git a/src/jceData/CSV/csv_exporter.h b/src/jceData/CSV/csv_exporter.h new file mode 100644 index 0000000..dec0783 --- /dev/null +++ b/src/jceData/CSV/csv_exporter.h @@ -0,0 +1,26 @@ +#ifndef CSV_EXPORTER_H +#define CSV_EXPORTER_H + +#include +#include +#include +#include +#include + +#include "../Calendar/calendarSchedule.h" + +#define CSV_CALENDAR_HEADER "Subject,Start Date,Start Time,End Date,End Time,Description,Location" + +class CSV_Exporter +{ +public: + CSV_Exporter(); + static bool exportCalendar(calendarSchedule* calSched); + + +private: + static QString getFileFath(); + static QString makeLine(QString name,int day,int startH,int startM,int endH,int endM,QString lecturer,QString room,QString type); +}; + +#endif // CSV_EXPORTER_H diff --git a/src/jceData/Calendar/calendarSchedule.h b/src/jceData/Calendar/calendarSchedule.h index df27daf..028afa1 100644 --- a/src/jceData/Calendar/calendarSchedule.h +++ b/src/jceData/Calendar/calendarSchedule.h @@ -20,7 +20,7 @@ public: calendarSchedule(); ~calendarSchedule() { clearTableItems(); } void setPage(std::string html); - void clearTableItems(); + void clearTableItems(); signals: