/** @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);
}
Beispiel #2
0
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));
}