/** @short Find a message body part through its slash-separated string path */ Imap::Mailbox::TreeItemPart *MsgPartNetAccessManager::pathToPart(const QModelIndex &message, const QString &path) { QStringList items = path.split('/', QString::SkipEmptyParts); const Mailbox::Model *model = 0; Imap::Mailbox::TreeItem *target = Mailbox::Model::realTreeItem(message, &model); Q_ASSERT(model); Q_ASSERT(target); bool ok = ! items.isEmpty(); // if it's empty, it's a bogous URL for (QStringList::const_iterator it = items.constBegin(); it != items.constEnd(); ++it) { uint offset = it->toUInt(&ok); if (!ok) { // special case, we have to dive into that funny, irregular special parts now if (*it == QLatin1String("HEADER")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_HEADER); else if (*it == QLatin1String("TEXT")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_TEXT); else if (*it == QLatin1String("MIME")) target = target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_MIME); else return 0; continue; } if (offset >= target->childrenCount(const_cast<Mailbox::Model *>(model))) { return 0; } target = target->child(offset, const_cast<Mailbox::Model *>(model)); } return dynamic_cast<Imap::Mailbox::TreeItemPart *>(target); }
void MessageView::setMessage(const QModelIndex &index) { // first, let's get a real model QModelIndex messageIndex; const Imap::Mailbox::Model *constModel = 0; Imap::Mailbox::TreeItem *item = Imap::Mailbox::Model::realTreeItem(index, &constModel, &messageIndex); Q_ASSERT(item); // Make sure it's a message Q_ASSERT(messageIndex.isValid()); Imap::Mailbox::Model *realModel = const_cast<Imap::Mailbox::Model *>(constModel); Q_ASSERT(realModel); // The data might be available from the local cache, so let's try to save a possible roundtrip here item->fetch(realModel); if (!messageIndex.data(Imap::Mailbox::RoleIsFetched).toBool()) { // This happens when the message placeholder is already available in the GUI, but the actual message data haven't been // loaded yet. This is especially common with the threading model. // Note that the data might be already available in the cache, it's just that it isn't in the mailbox tree yet. setEmpty(); connect(realModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(handleDataChanged(QModelIndex,QModelIndex))); message = messageIndex; return; } QModelIndex rootPartIndex = messageIndex.child(0, 0); headerSection->show(); if (message != messageIndex) { emptyView->hide(); layout->removeWidget(viewer); if (viewer != emptyView) { viewer->setParent(0); viewer->deleteLater(); } message = messageIndex; netAccess->setExternalsEnabled(false); externalElements->hide(); netAccess->setModelMessage(message); m_loadingItems.clear(); m_loadingSpinner->stop(); PartWidgetFactory::PartLoadingOptions loadingMode; if (m_settings->value(Common::SettingsNames::guiPreferPlaintextRendering, QVariant(true)).toBool()) loadingMode |= PartWidgetFactory::PART_PREFER_PLAINTEXT_OVER_HTML; viewer = factory->create(rootPartIndex, 0, loadingMode); viewer->setParent(this); layout->addWidget(viewer); viewer->show(); m_envelope->setMessage(message); tags->show(); tags->setTagList(messageIndex.data(Imap::Mailbox::RoleMessageFlags).toStringList()); disconnect(this, SLOT(handleDataChanged(QModelIndex,QModelIndex))); connect(realModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(handleDataChanged(QModelIndex,QModelIndex))); emit messageChanged(); // We want to propagate the QWheelEvent to upper layers viewer->installEventFilter(this); } if (realModel->isNetworkAvailable()) markAsReadTimer->start(200); // FIXME: make this configurable }
TreeItemPart *FullMessageCombiner::bodyPartPtr() const { Imap::Mailbox::TreeItem *target = m_model->realTreeItem(m_messageIndex); return dynamic_cast<Imap::Mailbox::TreeItemPart *>(target->specialColumnPtr(0, Imap::Mailbox::TreeItem::OFFSET_TEXT)); }