diff --git a/CMakeLists.txt b/CMakeLists.txt index b4a398e..c95e633 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 23) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -fsanitize=address,undefined") set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address,undefined") @@ -28,7 +30,7 @@ add_executable(emailQt main.cpp KeychainClass.cpp KeychainClass.hpp) -target_link_libraries(emailQt PRIVATE Qt6::Core +target_link_libraries(emailQt PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets CURL::libcurl diff --git a/CurlHandler.cpp b/CurlHandler.cpp index 9248ed5..c056cc2 100755 --- a/CurlHandler.cpp +++ b/CurlHandler.cpp @@ -15,7 +15,7 @@ void CurlHandler::configure(const ParametersProvider::settings &sett) { url += "/INBOX?ALL"; setts = sett; - setupCurl(initialCurl, initialChunk, url); + setupCurl(initialCurl.get(), initialChunk, url); } std::vector *CurlHandler::fetch() { @@ -47,18 +47,21 @@ std::vector *CurlHandler::fetch() { decodedMessages.resize(messagesId.size()); count = 0; - for (auto i{messagesId.rbegin()}; i != messagesId.rbegin() + 10 && i != messagesId.rend(); i++) + // 10 messages max + // By default, even if the thread's function parameter specifies a reference, + // a copy is made. To specify that you want a reference, use std::ref. + for (auto i{messagesId.rbegin()}; i != messagesId.rbegin() + 10 && i != messagesId.rend(); ++i) v.emplace_back(&CurlHandler::query, this, std::ref(*i), count++); return &decodedMessages; } void CurlHandler::query(std::string &c, size_t count) { - std::shared_ptr localCurl(curl_easy_init(), curl_easy_cleanup); + std::unique_ptr localCurl(curl_easy_init(), curl_easy_cleanup); CURLcode localCode; c.erase(std::remove(c.begin(), c.end(), '\r'), c.end()); c.erase(std::remove(c.begin(), c.end(), '\n'), c.end()); - setupCurl(localCurl, decodedMessages[count], url + c); + setupCurl(localCurl.get(), decodedMessages[count], url + c); localCode = curl_easy_perform(localCurl.get()); if (localCode != CURLE_OK) { @@ -68,26 +71,26 @@ void CurlHandler::query(std::string &c, size_t count) { emit threadFinished(count, std::stoi(c)); } -void CurlHandler::setupCurl(std::shared_ptr ptr, std::string &m, std::string const &ur) const { - curl_easy_setopt(ptr.get(), CURLOPT_USERNAME, setts.userS.c_str()); - curl_easy_setopt(ptr.get(), CURLOPT_PASSWORD, setts.passS.c_str()); +void CurlHandler::setupCurl(CURL *ptr, std::string &m, std::string const &ur) const { + curl_easy_setopt(ptr, CURLOPT_USERNAME, setts.userS.c_str()); + curl_easy_setopt(ptr, CURLOPT_PASSWORD, setts.passS.c_str()); - curl_easy_setopt(ptr.get(), CURLOPT_PORT, setts.port); - curl_easy_setopt(ptr.get(), CURLOPT_TIMEOUT, curlTimeoutSeconds); + curl_easy_setopt(ptr, CURLOPT_PORT, setts.port); + curl_easy_setopt(ptr, CURLOPT_TIMEOUT, curlTimeoutSeconds); // The callback function will receive the string ref as its userdata // and therefore save the data there. - curl_easy_setopt(ptr.get(), CURLOPT_USE_SSL, (long) CURLUSESSL_ALL); - curl_easy_setopt(ptr.get(), CURLOPT_WRITEDATA, (void *) &m); - curl_easy_setopt(ptr.get(), CURLOPT_WRITEFUNCTION, cb); + curl_easy_setopt(ptr, CURLOPT_USE_SSL, (long) CURLUSESSL_ALL); + curl_easy_setopt(ptr, CURLOPT_WRITEDATA, (void *) &m); + curl_easy_setopt(ptr, CURLOPT_WRITEFUNCTION, cb); // Necessary on some servers - curl_easy_setopt(ptr.get(), CURLOPT_USERAGENT, "libcurl-agent/1.0"); + curl_easy_setopt(ptr, CURLOPT_USERAGENT, "libcurl-agent/1.0"); - curl_easy_setopt(ptr.get(), CURLOPT_URL, ur.c_str()); + curl_easy_setopt(ptr, CURLOPT_URL, ur.c_str()); #ifdef DEBUG - curl_easy_setopt(ptr.get(), CURLOPT_VERBOSE, 1L); + curl_easy_setopt(ptr, CURLOPT_VERBOSE, 1L); #else curl_easy_setopt(ptr.get(), CURLOPT_VERBOSE, 0L); #endif @@ -95,7 +98,7 @@ void CurlHandler::setupCurl(std::shared_ptr ptr, std::string &m, std::stri size_t cb(char *data, size_t size, size_t numberOfMembers, void *userdata) { size_t realSize = size * numberOfMembers; - auto *mem = (std::string *) userdata; + auto *mem = static_cast (userdata); mem->append(data, realSize); return realSize; } diff --git a/CurlHandler.hpp b/CurlHandler.hpp index 6463d90..13d7a85 100755 --- a/CurlHandler.hpp +++ b/CurlHandler.hpp @@ -30,14 +30,14 @@ public: std::vector *fetch(); void query(std::string &c, size_t count); - void setupCurl(std::shared_ptr ptr, std::string &m, const std::string &ur) const; + void setupCurl(CURL *ptr, std::string &m, const std::string &ur) const; signals: void threadFinished(size_t threadId, int uid); private: std::string url; - std::shared_ptr initialCurl; + std::unique_ptr initialCurl; CURLcode initialRes; std::string initialChunk; diff --git a/Email.cpp b/Email.cpp index a78130d..35e68e1 100644 --- a/Email.cpp +++ b/Email.cpp @@ -6,15 +6,21 @@ Email::Email(const std::string &str, size_t uid) } Email::Email(Email const &e) - : QListWidgetItem(e), uid{e.uid}, titleS(e.titleS), messageS(e.messageS) { - setString(titleS); + : QListWidgetItem(nullptr, QListWidgetItem::UserType), + uid{e.uid}, + titleS(e.titleS), + messageS(e.messageS), + rawMessageS(e.rawMessageS) { + setText(QString::fromStdString(titleS)); } void Email::setString(const std::string &str) { std::stringstream ss(str); std::string line; + rawMessageS.clear(); while (std::getline(ss, line)) { + rawMessageS.append(line); if (line.starts_with("Subject:")) titleS = line.substr(9); else if (line.starts_with("Content-Type:")) @@ -32,6 +38,10 @@ const std::string &Email::message() const { return messageS; } +const std::string &Email::raw() const { + return rawMessageS; +} + bool Email::operator<(QListWidgetItem const &other) const { auto a{dynamic_cast(other)}; return this->uid < a.uid; diff --git a/Email.hpp b/Email.hpp index 430e008..959cae7 100644 --- a/Email.hpp +++ b/Email.hpp @@ -16,13 +16,15 @@ public: void setString(const std::string &str); [[nodiscard]] const std::string &title() const; [[nodiscard]] const std::string &message() const; + [[nodiscard]] const std::string &raw() const; - bool operator<(const QListWidgetItem &other) const; + bool operator<(const QListWidgetItem &other) const override; void parseEmailBody(std::stringstream &ss, std::string &line); private: std::string titleS; std::string messageS; + std::string rawMessageS; size_t uid; }; diff --git a/EmailDetails.cpp b/EmailDetails.cpp index 7de8c0e..2bdd687 100644 --- a/EmailDetails.cpp +++ b/EmailDetails.cpp @@ -1,18 +1,34 @@ #include "EmailDetails.hpp" EmailDetails::EmailDetails(QWidget *parent) - : QWidget(parent) { + : QWidget(parent), em{} { t = new QTextEdit; + dbg = new QCheckBox("View raw message"); auto *lay = new QVBoxLayout; + lay->addWidget(dbg); lay->addWidget(t); setLayout(lay); + connect(dbg, &QCheckBox::checkStateChanged, this, &EmailDetails::checkStateChanged); + resize(800, 600); } void EmailDetails::setMail(const Email &m) { setWindowTitle(QString::fromStdString(m.title())); t->setPlainText(QString::fromStdString(m.message())); + delete em; + em = new Email(m); +} + +void EmailDetails::checkStateChanged(Qt::CheckState state) { + if(em) { + if (state == Qt::Checked) { + t->setPlainText(QString::fromStdString(em->raw())); + } else { + t->setPlainText(QString::fromStdString(em->message())); + } + } } diff --git a/EmailDetails.hpp b/EmailDetails.hpp index b84bd4e..d3ccddd 100644 --- a/EmailDetails.hpp +++ b/EmailDetails.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -14,6 +15,12 @@ public: void setMail(const Email &m); +public slots: + void checkStateChanged(Qt::CheckState state); + private: + Email *em; + QTextEdit *t; + QCheckBox *dbg; }; diff --git a/ParametersProvider.cpp b/ParametersProvider.cpp index 33eea25..518206a 100644 --- a/ParametersProvider.cpp +++ b/ParametersProvider.cpp @@ -52,7 +52,7 @@ ParametersProvider::ParametersProvider(QWidget *parent) portField->setText("993"); } -void ParametersProvider::keyRead(const QString &key, const QString &value) { +void ParametersProvider::keyRead(const QString &key, const QString &value) const { if (key == Keychain::passKey) passField->setText(value); } diff --git a/ParametersProvider.hpp b/ParametersProvider.hpp index 95858ac..b100162 100644 --- a/ParametersProvider.hpp +++ b/ParametersProvider.hpp @@ -18,7 +18,7 @@ class ParametersProvider : public QDialog { public: struct settings { std::string userS, passS, imapS; - int port; + int port = 0; }; explicit ParametersProvider(QWidget *parent = nullptr); @@ -32,7 +32,7 @@ signals: public slots: // Keychain to save password - void keyRead(const QString &key, const QString &value); + void keyRead(const QString &key, const QString &value) const; // When clicking OK void start();