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:
@@ -0,0 +1,224 @@
|
||||
#include "ui/connectionwizard.h"
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
#include <QSslSocket>
|
||||
|
||||
ConnectionWizard::ConnectionWizard(QWidget *parent, AccountService *accountService)
|
||||
: QWizard(parent), m_accountService(accountService)
|
||||
{
|
||||
setWindowTitle("Configurar conexión de correo");
|
||||
setWizardStyle(QWizard::ModernStyle);
|
||||
setOption(QWizard::HaveHelpButton, false);
|
||||
setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
|
||||
|
||||
setupPageIntro();
|
||||
setupPageIncoming();
|
||||
setupPageOutgoing();
|
||||
setupPageAuth();
|
||||
setupPageTest();
|
||||
|
||||
// Set page order
|
||||
addPage(m_introPage);
|
||||
addPage(m_incomingPage);
|
||||
addPage(m_outgoingPage);
|
||||
addPage(m_authPage);
|
||||
addPage(m_testPage);
|
||||
|
||||
// Start at intro
|
||||
startId();
|
||||
}
|
||||
|
||||
void ConnectionWizard::setupPageIntro()
|
||||
{
|
||||
m_introPage = new QWizardPage(this);
|
||||
m_introPage->setTitle("Configuración de conexión");
|
||||
m_introPage->setSubTitle("Introduce los datos de los servidores entrantes y salientes para configurar tu cuenta de correo.");
|
||||
|
||||
QVBoxLayout *lay = new QVBoxLayout(m_introPage);
|
||||
QLabel *info = new QLabel(
|
||||
"Este asistente te guiará paso a paso para configurar los servidores IMAP/POP3 y SMTP.\\n"
|
||||
"Si no conoces los datos, consulta a tu proveedor de correo o busca en sus páginas de soporte."
|
||||
);
|
||||
info->setWordWrap(true);
|
||||
lay->addWidget(info);
|
||||
lay->addStretch();
|
||||
m_introPage->setLayout(lay);
|
||||
}
|
||||
|
||||
void ConnectionWizard::setupPageIncoming()
|
||||
{
|
||||
m_incomingPage = new QWizardPage(this);
|
||||
m_incomingPage->setTitle("Servidor entrante (IMAP/POP3)");
|
||||
m_incomingPage->setSubTitle("Configura el servidor que recibirá tus correos.");
|
||||
|
||||
QFormLayout *form = new QFormLayout();
|
||||
m_incomingTypeCombo = new QComboBox();
|
||||
m_incomingTypeCombo->addItem("IMAP", QVariant::fromValue(QString("imap")));
|
||||
m_incomingTypeCombo->addItem("POP3", QVariant::fromValue(QString("pop3")));
|
||||
form->addRow("Tipo:", m_incomingTypeCombo);
|
||||
|
||||
m_incomingHostEdit = new QLineEdit();
|
||||
m_incomingHostEdit->setPlaceholderText("ej. imap.ejemplo.com");
|
||||
form->addRow("Servidor:", m_incomingHostEdit);
|
||||
|
||||
m_incomingPortEdit = new QLineEdit();
|
||||
m_incomingPortEdit->setPlaceholderText("993");
|
||||
m_incomingPortEdit->setValidator(new QIntValidator(1, 65535, this));
|
||||
form->addRow("Puerto:", m_incomingPortEdit);
|
||||
|
||||
m_incomingSslCheck = new QCheckBox("Usar conexión segura (SSL/TLS)");
|
||||
m_incomingSslCheck->setChecked(true);
|
||||
form->addRow("", m_incomingSslCheck);
|
||||
|
||||
m_incomingPage->setLayout(form);
|
||||
}
|
||||
|
||||
void ConnectionWizard::setupPageOutgoing()
|
||||
{
|
||||
m_outgoingPage = new QWizardPage(this);
|
||||
m_outgoingPage->setTitle("Servidor saliente (SMTP)");
|
||||
m_outgoingPage->setSubTitle("Configura el servidor que enviará tus correos.");
|
||||
|
||||
QFormLayout *form = new QFormLayout();
|
||||
m_outgoingHostEdit = new QLineEdit();
|
||||
m_outgoingHostEdit->setPlaceholderText("ej. smtp.ejemplo.com");
|
||||
form->addRow("Servidor:", m_outgoingHostEdit);
|
||||
|
||||
m_outgoingPortEdit = new QLineEdit();
|
||||
m_outgoingPortEdit->setPlaceholderText("587");
|
||||
m_outgoingPortEdit->setValidator(new QIntValidator(1, 65535, this));
|
||||
form->addRow("Puerto:", m_outgoingPortEdit);
|
||||
|
||||
m_outgoingSslCheck = new QCheckBox("Usar conexión segura (STARTTLS/SSL)");
|
||||
m_outgoingSslCheck->setChecked(true);
|
||||
form->addRow("", m_outgoingSslCheck);
|
||||
|
||||
m_outgoingPage->setLayout(form);
|
||||
}
|
||||
|
||||
void ConnectionWizard::setupPageAuth()
|
||||
{
|
||||
m_authPage = new QWizardPage(this);
|
||||
m_authPage->setTitle("Autenticación");
|
||||
m_authPage->setSubTitle("Introduce tu nombre de usuario y contraseña para acceder a los servidores.");
|
||||
|
||||
QFormLayout *form = new QFormLayout();
|
||||
m_usernameEdit = new QLineEdit();
|
||||
m_usernameEdit->setPlaceholderText("tu-usuario@dominio.com");
|
||||
form->addRow("Usuario:", m_usernameEdit);
|
||||
|
||||
m_passwordEdit = new QLineEdit();
|
||||
m_passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
m_passwordEdit->setPlaceholderText("Contraseña");
|
||||
form->addRow("Contraseña:", m_passwordEdit);
|
||||
|
||||
m_authMethodCombo = new QComboBox();
|
||||
m_authMethodCombo->addItem("Contraseña normal", QVariant::fromValue(QString("plain")));
|
||||
m_authMethodCombo->addItem("Autenticación OAuth2", QVariant::fromValue(QString("oauth2")));
|
||||
form->addRow("Método:", m_authMethodCombo);
|
||||
|
||||
m_authPage->setLayout(form);
|
||||
}
|
||||
|
||||
void ConnectionWizard::setupPageTest()
|
||||
{
|
||||
m_testPage = new QWizardPage(this);
|
||||
m_testPage->setTitle("Probar conexión");
|
||||
m_testPage->setSubTitle("Verifica que los datos ingresados sean correctos.");
|
||||
|
||||
QVBoxLayout *lay = new QVBoxLayout(m_testPage);
|
||||
m_testStatusLabel = new QLabel("Listo para probar la conexión.");
|
||||
m_testStatusLabel->setAlignment(Qt::AlignCenter);
|
||||
m_testStatusLabel->setStyleSheet("font-size: 14px; color: #555;");
|
||||
lay->addWidget(m_testStatusLabel);
|
||||
|
||||
m_testDetailLabel = new QLabel("");
|
||||
m_testDetailLabel->setWordWrap(true);
|
||||
m_testDetailLabel->setAlignment(Qt::AlignCenter);
|
||||
m_testDetailLabel->setStyleSheet("font-size: 12px; color: #888;");
|
||||
lay->addWidget(m_testDetailLabel);
|
||||
|
||||
lay->addStretch();
|
||||
|
||||
m_testButton = new QPushButton("Probar conexión ahora");
|
||||
m_testButton->setStyleSheet(
|
||||
"QPushButton { background-color: #0071e3; color: white; border: none; padding: 8px 16px; border-radius: 4px; }"
|
||||
"QPushButton:hover { background-color: #005bb5; }"
|
||||
);
|
||||
lay->addWidget(m_testButton, 0, Qt::AlignCenter);
|
||||
|
||||
connect(m_testButton, &QPushButton::clicked, this, &ConnectionWizard::onTestClicked);
|
||||
|
||||
m_testPage->setLayout(lay);
|
||||
}
|
||||
|
||||
void ConnectionWizard::onTestClicked()
|
||||
{
|
||||
if (!m_accountService) {
|
||||
m_testStatusLabel->setText("⚠️ Servicio de cuenta no disponible.");
|
||||
m_testStatusLabel->setStyleSheet("color: #e60000;");
|
||||
m_testDetailLabel->setText("El servicio de cuenta no está inicializado.");
|
||||
return;
|
||||
}
|
||||
|
||||
Account::ConnectionSettings settings = connectionSettings();
|
||||
// Basic validation
|
||||
if (settings.incomingHost.isEmpty() || settings.username.isEmpty() || settings.password.isEmpty()) {
|
||||
m_testStatusLabel->setText("⚠️ Faltan datos obligatorios.");
|
||||
m_testStatusLabel->setStyleSheet("color: #e60000;");
|
||||
m_testDetailLabel->setText("Por favor, completa los campos de servidor entrante, usuario y contraseña.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_testStatusLabel->setText("⏳ Probando conexión...");
|
||||
m_testStatusLabel->setStyleSheet("color: #0071e3;");
|
||||
m_testDetailLabel->setText("Conectando al servidor IMAP...");
|
||||
|
||||
// Use a small delay to allow UI update before blocking call
|
||||
QTimer::singleShot(0, this, [this, settings]() {
|
||||
QString errorMsg;
|
||||
bool ok = m_accountService->testConnection(settings, errorMsg);
|
||||
if (ok) {
|
||||
m_testStatusLabel->setText("✅ Conexión exitosa.");
|
||||
m_testStatusLabel->setStyleSheet("color: #34c759;");
|
||||
m_testDetailLabel->setText("Los datos ingresados son correctos. Puedes finalizar la configuración.");
|
||||
} else {
|
||||
m_testStatusLabel->setText("❌ Error de conexión.");
|
||||
m_testStatusLabel->setStyleSheet("color: #ff3b30;");
|
||||
m_testDetailLabel->setText(errorMsg.isEmpty() ? "Error desconocido." : errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Account::ConnectionSettings ConnectionWizard::connectionSettings() const
|
||||
{
|
||||
Account::ConnectionSettings s;
|
||||
// Incoming
|
||||
s.type = m_incomingTypeCombo->currentData().toString(); // "imap" or "pop3"
|
||||
s.incomingHost = m_incomingHostEdit->text().trimmed();
|
||||
s.incomingPort = m_incomingPortEdit->text().toInt();
|
||||
s.incomingSsl = m_incomingSslCheck->isChecked();
|
||||
|
||||
// Outgoing (SMTP)
|
||||
s.outgoingHost = m_outgoingHostEdit->text().trimmed();
|
||||
s.outgoingPort = m_outgoingPortEdit->text().toInt();
|
||||
s.outgoingSsl = m_outgoingSslCheck->isChecked();
|
||||
|
||||
// Auth
|
||||
s.username = m_usernameEdit->text().trimmed();
|
||||
s.password = m_passwordEdit->text();
|
||||
s.authMethod = m_authMethodCombo->currentData().toString(); // "plain" or "oauth2"
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void ConnectionWizard::accept()
|
||||
{
|
||||
// When Finish is pressed, emit the settings and close
|
||||
Account::ConnectionSettings settings = connectionSettings();
|
||||
emit settingsReady(settings);
|
||||
QWizard::accept();
|
||||
}
|
||||
|
||||
#include "connectionwizard.moc"
|
||||
Reference in New Issue
Block a user