feat: IMAP sync incremental + Account Setup Wizard + robust FETCH parser

- ImapSynchronizer::syncFolder(): detecta eliminados (UIDs locales no en servidor), fetch nuevos (sinceUid), actualiza flags (FLAGS batch)
- fetchAllUids(): SELECT + SEARCH ALL para lista completa UIDs servidor
- parseAndUpdateFlags(): FETCH FLAGS en lotes 100, update DB si cambió read/flagged
- AccountSetupDialog: integra ConnectionWizard para IMAP/POP3 con test de conexión real
- IMAP FETCH parser robusto: logging respuesta servidor + fallback UID-by-UID
- Fix: FETCH failed logging muestra first/last UID + respuesta truncada
This commit is contained in:
2026-08-17 15:34:49 +02:00
parent 364624aada
commit a004bdd60f
94 changed files with 19408 additions and 1047 deletions
+92 -22
View File
@@ -7,6 +7,7 @@
#include <QRegularExpressionValidator>
#include <QIntValidator>
#include <QTimer>
#include "ui/connectionwizard.h"
// ─────────────────────── Constructor ───────────────────────
AccountSetupDialog::AccountSetupDialog(AccountService *accountService, QWidget *parent)
@@ -427,7 +428,8 @@ void AccountSetupDialog::onNextClicked()
if (page == PageProvider) {
if (m_selectedProvider == 2) {
goToPage(PageImap);
// Launch ConnectionWizard for IMAP/POP3 setup
launchConnectionWizard();
} else {
// Update OAuth page subtitle based on provider
goToPage(PageOAuth);
@@ -441,6 +443,20 @@ void AccountSetupDialog::onNextClicked()
}
}
void AccountSetupDialog::launchConnectionWizard()
{
ConnectionWizard wizard(this, m_accountService);
wizard.setWindowTitle("Configurar cuenta IMAP / POP3");
wizard.setWizardStyle(QWizard::ModernStyle);
connect(&wizard, &ConnectionWizard::settingsReady,
this, &AccountSetupDialog::onConnectionWizardFinished);
if (wizard.exec() == QDialog::Accepted) {
// Settings were emitted and handled in onConnectionWizardFinished
}
}
void AccountSetupDialog::onBackClicked()
{
int page = m_stack->currentIndex();
@@ -552,27 +568,81 @@ void AccountSetupDialog::submitImapAccount()
m_sslCheckbox->isChecked() ? "" : "No")
);
// Disable UI during connection attempt
m_btnBack->setEnabled(false);
m_btnNext->setEnabled(false);
m_btnCancel->setEnabled(false);
QString errorMsg;
bool success = m_accountService->testConnection(account.connectionSettings(), errorMsg);
if (success) {
if (m_isEditing) {
account.setId(m_editingAccountId);
m_accountService->updateAccount(account);
} else {
m_accountService->addAccount(account);
}
m_btnCancel->setEnabled(true);
} else {
QMessageBox::warning(this, tr("Connection failed"), tr("Could not connect to IMAP server: %1").arg(errorMsg));
// Re-enable UI
m_btnBack->setEnabled(true);
m_btnNext->setEnabled(true);
m_btnCancel->setEnabled(true);
}
// Disable UI during connection attempt
m_btnBack->setEnabled(false);
m_btnNext->setEnabled(false);
m_btnCancel->setEnabled(false);
QString errorMsg;
bool success = m_accountService->testConnection(account.connectionSettings(), errorMsg);
if (success) {
if (m_isEditing) {
account.setId(m_editingAccountId);
m_accountService->updateAccount(account);
} else {
m_accountService->addAccount(account);
}
m_btnCancel->setEnabled(true);
} else {
QMessageBox::warning(this, tr("Connection failed"), tr("Could not connect to IMAP server: %1").arg(errorMsg));
// Re-enable UI
m_btnBack->setEnabled(true);
m_btnNext->setEnabled(true);
m_btnCancel->setEnabled(true);
}
}
// ─────────────────── Account Result ───────────────────
void AccountSetupDialog::onConnectionWizardFinished(const Account::ConnectionSettings &settings)
{
QString email = settings.username;
QString name = email.split("@").first();
// Show progress
m_accountCreatedOk = false;
goToPage(PageProgress);
m_progressIcon->setText("");
m_progressText->setText("Conectando al servidor...");
m_progressDetail->setText(
QString("Servidor IMAP: %1:%2\nServidor SMTP: %3:%4\nSSL: %5")
.arg(settings.incomingHost)
.arg(settings.incomingPort)
.arg(settings.outgoingHost)
.arg(settings.outgoingPort)
.arg(settings.incomingSsl ? "" : "No")
);
// Disable UI during connection attempt
m_btnBack->setEnabled(false);
m_btnNext->setEnabled(false);
m_btnCancel->setEnabled(false);
QString errorMsg;
bool success = m_accountService->testConnection(settings, errorMsg);
if (success) {
// Create account with the connection settings
Account account;
account.setEmail(email);
account.setDisplayName(name);
// Determine account type from protocol
if (settings.type == "pop3") {
account.setType(AccountType::POP3);
} else {
account.setType(AccountType::IMAP);
}
account.setConnectionSettings(settings);
if (m_isEditing) {
account.setId(m_editingAccountId);
m_accountService->updateAccount(account);
} else {
m_accountService->addAccount(account);
}
m_btnCancel->setEnabled(true);
} else {
showError(tr("Could not connect to server: %1").arg(errorMsg));
}
}
// ─────────────────── Account Result ───────────────────