diff --git a/CMakeLists.txt b/CMakeLists.txt index 164a06f..be31e4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Find Qt components -find_package(Qt6 COMPONENTS Core Gui Widgets Network Sql WebEngineWidgets Qml REQUIRED) +find_package(Qt6 COMPONENTS Core Gui Widgets Network Sql WebEngineWidgets Qml Multimedia REQUIRED) # Find optional libraries (example: libetpan, gmime) # find_package(PkgConfig REQUIRED) @@ -15,12 +15,10 @@ find_package(Qt6 COMPONENTS Core Gui Widgets Network Sql WebEngineWidgets Qml RE # Include directories include_directories(${PROJECT_SOURCE_DIR}/src) -# Resources -qt6_add_resources(WinoMailQtResources - FILES - resources/qml/main.qml - resources/qml/Shell.qml -) +# Enable automatic moc, uic, rcc +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) # Source files set(SRC_FILES @@ -43,17 +41,21 @@ set(SRC_FILES src/db/dao/folderdao.cpp src/db/dao/mailitemdao.cpp src/db/dbchangeprocessor.cpp + src/core/eventbus.cpp + src/utils/notificationmanager.cpp + src/core/emailmanager.cpp + src/syncscheduler.cpp ) # Executable add_executable(wino-mail-qt ${SRC_FILES}) # Link Qt -target_link_libraries(wino-mail-qt PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network Qt6::Sql Qt6::WebEngineWidgets Qt6::Qml ${WinoMailQtResources}) +target_link_libraries(wino-mail-qt PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network Qt6::Sql Qt6::WebEngineWidgets Qt6::Qml Qt6::Multimedia) # If using external libs # target_link_libraries(wino-mail-qt PRIVATE ${LIBETPAN_LIBRARIES} ${GMIME_LIBRARIES}) # target_include_directories(wino-mail-qt PRIVATE ${LIBETPAN_INCLUDE_DIRS} ${GMIME_INCLUDE_DIRS}) # Install (optional) -install(TARGETS wino-mail-qt DESTINATION bin) +install(TARGETS wino-mail-qt DESTINATION bin) \ No newline at end of file diff --git a/src/core/emailmanager.cpp b/src/core/emailmanager.cpp index 695fcd2..c1d2792 100644 --- a/src/core/emailmanager.cpp +++ b/src/core/emailmanager.cpp @@ -3,6 +3,7 @@ #include #include "../db/dao/mailitemdao.h" #include +#include EmailManager::EmailManager(QObject *parent) : QObject(parent) @@ -32,6 +33,24 @@ QString EmailManager::getStorageDirectory() const return storagePath; } +QString EmailManager::getEmailHtmlById(qint64 id) const +{ + // Get the MailItem by id + MailItem item = getMailItemById(id); + if (item.id() == 0) { + return "

Error: Email not found

"; + } + // Construct the file path: storage directory + fileId + .eml + QString storageDir = getStorageDirectory(); + QString fileName = item.fileId(); + if (fileName.isEmpty()) { + return "

Error: Email file ID is empty

"; + } + QString filePath = storageDir + QDir::separator() + fileName + ".eml"; + // Convert the .eml file to HTML + return convertEmlToHtml(filePath); +} + QString EmailManager::convertEmlToHtml(const QString& emlFilePath) const { // TODO: Implement actual MIME to HTML conversion using gmime or similar @@ -50,4 +69,13 @@ QString EmailManager::convertEmlToHtml(const QString& emlFilePath) const content.replace("&", "&").replace("<", "<").replace(">", ">"); return QString("

Email Content (raw)

%1
") .arg(content); +} + +bool EmailManager::sendEmail(const QString& to, const QString& subject, const QString& body) +{ + // TODO: Implement actual email sending + // For now, just show a message and return true + QMessageBox::information(nullptr, "Send Email", + QString("To: %1\nSubject: %2\nBody: %3").arg(to, subject, body)); + return true; } \ No newline at end of file diff --git a/src/core/emailmanager.h b/src/core/emailmanager.h index dfd79ba..8aaf8f6 100644 --- a/src/core/emailmanager.h +++ b/src/core/emailmanager.h @@ -22,6 +22,9 @@ public: // Returns the HTML content of an email by its ID Q_INVOKABLE QString getEmailHtmlById(qint64 id) const; + // Converts an .eml file to HTML string + QString convertEmlToHtml(const QString& emlFilePath) const; + // Sends an email with the given parameters // Returns true if the email was successfully queued for sending Q_INVOKABLE bool sendEmail(const QString& to, const QString& subject, const QString& body); diff --git a/src/main.cpp b/src/main.cpp index ac20c47..2dfc257 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,15 @@ -#include +#include #include #include #include "core/translator.h" #include "db/dbchangeprocessor.h" #include "core/emailmanager.h" #include "syncscheduler.h" +#include "utils/notificationmanager.h" int main(int argc, char *argv[]) { - QGuiApplication app(argc, argv); + QApplication app(argc, argv); // Load English translation Translator& translator = Translator::instance(); @@ -26,10 +27,15 @@ int main(int argc, char *argv[]) SyncScheduler syncScheduler(&app); syncScheduler.start(); + // Create NotificationManager (system tray and notifications) + NotificationManager notificationManager(&app); + notificationManager.initialize(); // Initialize Qt components after QApplication is ready + QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("translator", static_cast(&translator)); engine.rootContext()->setContextProperty("emailManager", &emailManager); engine.rootContext()->setContextProperty("syncScheduler", &syncScheduler); + engine.rootContext()->setContextProperty("notificationManager", ¬ificationManager); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, diff --git a/src/utils/notificationmanager.cpp b/src/utils/notificationmanager.cpp index 2c5de82..1cbc69a 100644 --- a/src/utils/notificationmanager.cpp +++ b/src/utils/notificationmanager.cpp @@ -4,27 +4,53 @@ NotificationManager::NotificationManager(QObject *parent) : QObject(parent) + , m_trayIcon(nullptr) + , m_trayMenu(nullptr) + , m_showHideAction(nullptr) + , m_quitAction(nullptr) + , m_newMailSound(nullptr) { + // Defer initialization to after QApplication is fully ready + // We'll initialize in a separate method called from main after the event loop starts? + // For now, we do nothing and log. + qDebug() << "NotificationManager: constructor (deferred initialization)"; +} + +NotificationManager::~NotificationManager() +{ + // Cleanup if we ever initialize + if (m_trayMenu) { + delete m_trayMenu; + } + // Note: m_trayIcon, m_showHideAction, m_quitAction, m_newMailSound are children of this or m_trayMenu? + // Actually, m_trayIcon and m_newMailSound have 'this' as parent, so they will be deleted automatically. + // m_showHideAction and m_quitAction have m_trayMenu as parent, so they will be deleted when m_trayMenu is deleted. +} + +void NotificationManager::initialize() +{ + // Initialize the tray icon and related objects + m_trayIcon = new QSystemTrayIcon(this); + m_trayMenu = new QMenu(this); // parent to NotificationManager so it gets deleted with us + m_showHideAction = new QAction("Show/Hide", m_trayMenu); + m_quitAction = new QAction("Quit", m_trayMenu); + m_newMailSound = new QSoundEffect(this); + setupTrayIcon(); setupConnections(); } void NotificationManager::setupTrayIcon() { - m_trayIcon = new QSystemTrayIcon(this); // Set an icon (you may want to load from resources) m_trayIcon->setIcon(QIcon::fromTheme("mail-unread")); m_trayIcon->setToolTip("Wino Mail"); - m_trayMenu = new QMenu(this); - m_showHideAction = new QAction("Show/Hide", this); - m_quitAction = new QAction("Quit", this); m_trayMenu->addAction(m_showHideAction); m_trayMenu->addSeparator(); m_trayMenu->addAction(m_quitAction); m_trayIcon->setContextMenu(m_trayMenu); - m_newMailSound = new QSoundEffect(this); m_newMailSound->setSource(QUrl::fromLocalFile("/usr/share/sounds/freedesktop/stereo/message-new-instant.oga")); m_newMailSound->setVolume(0.5); } diff --git a/src/utils/notificationmanager.h b/src/utils/notificationmanager.h index 24f3955..13f75ea 100644 --- a/src/utils/notificationmanager.h +++ b/src/utils/notificationmanager.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "core/eventbus.h" #include "../core/events.h" @@ -14,7 +15,8 @@ class NotificationManager : public QObject Q_OBJECT public: explicit NotificationManager(QObject *parent = nullptr); - ~NotificationManager() override = default; + ~NotificationManager() override; + void initialize(); // Initialize Qt components after QApplication is ready private slots: void onMailItemAdded(const WinoMail::Events::MailItemAddedEvent& event);