#include "notificationmanager.h" #include #include NotificationManager::NotificationManager(QObject *parent) : QObject(parent) , m_trayIcon(nullptr) , m_trayMenu(nullptr) , m_showHideAction(nullptr) , m_quitAction(nullptr) , m_newMailSound(nullptr) , m_errorSound(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, m_errorSound are children of this or m_trayMenu? // Actually, m_trayIcon and m_newMailSound, m_errorSound 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(); // 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); m_errorSound = new QSoundEffect(this); setupTrayIcon(); setupConnections(); } void NotificationManager::setupTrayIcon() { // Set an icon (you may want to load from resources) m_trayIcon->setIcon(QIcon::fromTheme("mail-unread")); m_trayIcon->setToolTip("Wino Mail"); m_trayMenu->addAction(m_showHideAction); m_trayMenu->addSeparator(); m_trayMenu->addAction(m_quitAction); m_trayIcon->setContextMenu(m_trayMenu); m_newMailSound->setSource(QUrl::fromLocalFile("/usr/share/sounds/freedesktop/stereo/message-new-instant.oga")); m_newMailSound->setVolume(0.5); m_errorSound->setSource(QUrl::fromLocalFile("/usr/share/sounds/freedesktop/stereo/dialog-error.oga")); m_errorSound->setVolume(0.5); } void NotificationManager::setupConnections() { // Connect tray icon signals connect(m_trayIcon, &QSystemTrayIcon::activated, this, &NotificationManager::onTrayIconActivated); connect(m_showHideAction, &QAction::triggered, this, &NotificationManager::onShowHideRequested); connect(m_quitAction, &QAction::triggered, qApp, &QGuiApplication::quit); // Subscribe to events SUBSCRIBE(WinoMail::Events::MailItemAddedEvent, [this](const WinoMail::Events::MailItemAddedEvent& event) { onMailItemAdded(event); }); SUBSCRIBE(WinoMail::Events::MailItemRemovedEvent, [this](const WinoMail::Events::MailItemRemovedEvent& event) { onMailItemRemoved(event); }); SUBSCRIBE(WinoMail::Events::MailItemUpdatedEvent, [this](const WinoMail::Events::MailItemUpdatedEvent& event) { onMailItemUpdated(event); }); SUBSCRIBE(WinoMail::Events::AccountConnectedEvent, [this](const WinoMail::Events::AccountConnectedEvent& event) { onAccountConnected(event); }); SUBSCRIBE(WinoMail::Events::AccountDisconnectedEvent, [this](const WinoMail::Events::AccountDisconnectedEvent& event) { onAccountDisconnected(event); }); SUBSCRIBE(WinoMail::Events::SyncStartedEvent, [this](const WinoMail::Events::SyncStartedEvent& event) { onSyncStarted(event); }); SUBSCRIBE(WinoMail::Events::SyncFinishedEvent, [this](const WinoMail::Events::SyncFinishedEvent& event) { onSyncFinished(event); }); SUBSCRIBE(WinoMail::Events::ErrorEvent, [this](const WinoMail::Events::ErrorEvent& event) { onErrorOccurred(event); }); // Show tray icon m_trayIcon->show(); } void NotificationManager::onMailItemAdded(const WinoMail::Events::MailItemAddedEvent& event) { qDebug() << "NotificationManager: New mail arrived -" << event.item.subject(); // Show a system tray notification m_trayIcon->showMessage( "Wino Mail - Nuevo correo", event.item.subject(), QSystemTrayIcon::MessageIcon::Information, 5000 // 5 seconds ); // Play sound playNewMailSound(); } void NotificationManager::onMailItemRemoved(const WinoMail::Events::MailItemRemovedEvent& event) { qDebug() << "NotificationManager: Mail removed - UID:" << event.itemUid; // Show a system tray notification m_trayIcon->showMessage( "Wino Mail - Correo eliminado", QString("Correo con UID %1 eliminado").arg(event.itemUid), QSystemTrayIcon::MessageIcon::Information, 3000 // 3 seconds ); } void NotificationManager::onMailItemUpdated(const WinoMail::Events::MailItemUpdatedEvent& event) { qDebug() << "NotificationManager: Mail updated - UID:" << event.item.id() << "Changed fields:" << event.changedFields; // Show a system tray notification for significant changes (like read/unread) if (event.changedFields.contains("read") || event.changedFields.contains("flagged")) { m_trayIcon->showMessage( "Wino Mail - Correo actualizado", QString("Correo %1 actualizado").arg(event.item.subject()), QSystemTrayIcon::MessageIcon::Information, 3000 // 3 seconds ); } } void NotificationManager::onAccountConnected(const WinoMail::Events::AccountConnectedEvent& event) { qDebug() << "NotificationManager: Account connected - ID:" << event.accountId << "Provider:" << event.provider; // Show a system tray notification m_trayIcon->showMessage( "Wino Mail - Cuenta conectada", QString("Cuenta %1 conectada (%2)").arg(event.accountId).arg(event.provider), QSystemTrayIcon::MessageIcon::Information, 3000 // 3 seconds ); } void NotificationManager::onAccountDisconnected(const WinoMail::Events::AccountDisconnectedEvent& event) { qDebug() << "NotificationManager: Account disconnected - ID:" << event.accountId << "Provider:" << event.provider << "Reason:" << event.reason; // Show a system tray notification m_trayIcon->showMessage( "Wino Mail - Cuenta desconectada", QString("Cuenta %1 desconectada (%2): %3").arg(event.accountId).arg(event.provider).arg(event.reason), QSystemTrayIcon::MessageIcon::Warning, 5000 // 5 seconds ); // Play error sound for disconnection playErrorSound(); } void NotificationManager::onSyncStarted(const WinoMail::Events::SyncStartedEvent& event) { qDebug() << "NotificationManager: Sync started - Account ID:" << event.accountId << "Folder ID:" << event.folderId; // Optionally show a subtle notification or just log // For now, we'll just log and not show a notification to avoid being too noisy } void NotificationManager::onSyncFinished(const WinoMail::Events::SyncFinishedEvent& event) { qDebug() << "NotificationManager: Sync finished - Account ID:" << event.accountId << "Folder ID:" << event.folderId << "Success:" << event.success; if (!event.success) { // Show error notification and play sound m_trayIcon->showMessage( "Wino Mail - Error de sincronización", QString("Error al sincronizar cuenta %1, carpeta %2: %3").arg(event.accountId).arg(event.folderId).arg(event.errorMessage), QSystemTrayIcon::MessageIcon::Critical, 5000 // 5 seconds ); playErrorSound(); } else { // Optionally show success notification // m_trayIcon->showMessage("Wino Mail - Sincronización completada", QString("Sincronización completada para cuenta %1, carpeta %2").arg(event.accountId).arg(event.folderId), QSystemTrayIcon::MessageIcon::Information, 3000); } } void NotificationManager::onErrorOccurred(const WinoMail::Events::ErrorEvent& event) { qDebug() << "NotificationManager: Error occurred - Source:" << event.source << "Message:" << event.message << "Critical:" << event.isCritical; // Show a system tray notification for critical errors if (event.isCritical) { m_trayIcon->showMessage( "Wino Mail - Error crítico", QString("Error en %1: %2").arg(event.source).arg(event.message), QSystemTrayIcon::MessageIcon::Critical, 5000 // 5 seconds ); playErrorSound(); } } void NotificationManager::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick) { onShowHideRequested(); } } void NotificationManager::onShowHideRequested() { // Emit signal to toggle main window visibility Q_EMIT showHideRequested(); } void NotificationManager::onQuitRequested() { // Already connected to quit } void NotificationManager::playNewMailSound() { if (m_newMailSound->isLoaded()) { m_newMailSound->play(); } } void NotificationManager::playErrorSound() { if (m_errorSound->isLoaded()) { m_errorSound->play(); } } void NotificationManager::showNotification(const QString& title, const QString& message, QSystemTrayIcon::MessageIcon icon, int timeout) { m_trayIcon->showMessage(title, message, icon, timeout); }