feat: Search Online (IMAP) + real Calendar/Contacts UI + iCloud auth wiring

Search Online:
- Synchronizer::searchOnline(folderId, query) virtual with default {}
- ImapSynchronizer: SELECT + UID SEARCH (Subject/From/To/TEXT) + fetch results
- MailService::searchOnline() + onlineSearchFinished/onlineSearchError signals
- MainMainWindow::onOnlineSearchRequested shows real server results

Calendar:
- Real QCalendarWidget view with per-day agenda from local mails
- New MailItemDao::findByDateRange(start, end)

Contacts:
- QTableWidget aggregating addresses from all local mails
- Regex email extraction + live search filter

iCloud/AccountService:
- Wire IcloudAuthenticator into AccountService::createAuthenticator
This commit is contained in:
2026-08-30 01:46:34 +02:00
parent d86df8ce51
commit 59692b5706
61 changed files with 1018 additions and 115 deletions
+32 -14
View File
@@ -1143,32 +1143,50 @@ void MainMainWindow::onEmbeddedDetachRequested(QWidget *widget)
void MainMainWindow::onOnlineSearchRequested(const QString& query)
{
if (query.trimmed().isEmpty()) {
QMessageBox::warning(this, "Buscar online", "Introduce un término de búsqueda");
return;
}
if (m_currentFolderId < 0) {
QMessageBox::warning(this, "Buscar online", "Selecciona una carpeta primero");
return;
}
std::optional<Folder> optFolder = FolderDao::findById(m_currentFolderId);
if (!optFolder.has_value()) return;
Folder folder = optFolder.value();
Account* account = m_accountService->findAccountById(folder.accountId());
if (!account) {
QMessageBox::warning(this, "Buscar online", "No se encontró la cuenta para esta carpeta");
return;
}
// Use MailService to search online (IMAP SEARCH)
statusBar()->showMessage(tr("Buscando en servidor: %1").arg(query), 3000);
// TODO: Implement IMAP SEARCH in MailService
// For now, show a message
QMessageBox::information(this, "Buscar online",
QString("Búsqueda en servidor para: '%1'\nCarpeta: %2\nCuenta: %3")
.arg(query)
.arg(folder.name())
.arg(account->email()));
statusBar()->showMessage(tr("Buscando en servidor: %1…").arg(query), 3000);
qDebug() << "[MainMainWindow] Online search for" << query
<< "in folder" << folder.name();
QVector<MailItem> results =
m_mailService->searchOnline(QString::number(account->id()),
QString::number(m_currentFolderId), query);
delete account;
if (results.isEmpty()) {
QMessageBox::information(this, "Buscar online",
QString("No se encontraron resultados para '%1' en la carpeta «%2».")
.arg(query, folder.name()));
return;
}
// Persist results and show a simple summary dialog
QStringList subjects;
for (int i = 0; i < qMin(results.size(), 30); ++i) {
QString s = results[i].subject();
if (s.isEmpty()) s = "(sin asunto)";
subjects << QString("%1. %2").arg(i + 1).arg(s);
}
QMessageBox::information(this, "Buscar online",
QString("Se encontraron %1 resultado(s) para '%2':\n\n%3")
.arg(results.size()).arg(query, subjects.join('\n')));
}
MainMainWindow::~MainMainWindow() = default;