MsgPartNetworkReply::MsgPartNetworkReply(MsgPartNetAccessManager *parent, const QPersistentModelIndex &part, bool requireFormatting):
    QNetworkReply(parent), part(part), formattedBufferContent(0), requireFormatting(requireFormatting)
{
    QUrl url;
    url.setScheme(QLatin1String("trojita-imap"));
    url.setHost(QLatin1String("msg"));
    url.setPath(part.data(Imap::Mailbox::RolePartPathToPart).toString());
    setUrl(url);

    setOpenMode(QIODevice::ReadOnly | QIODevice::Unbuffered);
    Q_ASSERT(part.isValid());
    const Mailbox::Model *model = 0;
    Mailbox::Model::realTreeItem(part, &model);
    Q_ASSERT(model);

    connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(slotModelDataChanged(QModelIndex,QModelIndex)));

    //TODO: fileDownloadProgress signal in model signal the process of the current download.
    //      This reply might not be the current download, but now we assume that because the only use case here
    //      is just see the download progress of attachments that is usually the only downloading event.
    //      Should match message UID and partId and then emit downloadProgress.
    connect(model, SIGNAL(fileDownloadProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));

    Mailbox::TreeItemPart *partPtr = dynamic_cast<Mailbox::TreeItemPart *>(static_cast<Mailbox::TreeItem *>(part.internalPointer()));
    Q_ASSERT(partPtr);

    // We have to ask for contents before we check whether it's already fetched
    partPtr->fetch(const_cast<Mailbox::Model *>(model));
    // The part data might be already unavailable or already fetched
    QTimer::singleShot(0, this, SLOT(slotMyDataChanged()));

    buffer.setBuffer(partPtr->dataPtr());
    buffer.open(QIODevice::ReadOnly);
}
MsgPartNetworkReply::MsgPartNetworkReply(MsgPartNetAccessManager *parent, const QPersistentModelIndex &part):
    QNetworkReply(parent), part(part)
{
    QUrl url;
    url.setScheme(QStringLiteral("trojita-imap"));
    url.setHost(QStringLiteral("msg"));
    url.setPath(part.data(Imap::Mailbox::RolePartPathToPart).toString());
    setUrl(url);

    setOpenMode(QIODevice::ReadOnly | QIODevice::Unbuffered);
    Q_ASSERT(part.isValid());

    connect(part.model(), &QAbstractItemModel::dataChanged, this, &MsgPartNetworkReply::slotModelDataChanged);

    // We have to ask for contents before we check whether it's already fetched
    part.data(Imap::Mailbox::RolePartData);

    // The part data might be already unavailable or already fetched
    QTimer::singleShot(0, this, SLOT(slotMyDataChanged()));

    QByteArray* bufferPtr = part.data(Imap::Mailbox::RolePartBufferPtr).value<QByteArray*>();
    Q_ASSERT(bufferPtr);
    buffer.setBuffer(bufferPtr);
    buffer.open(QIODevice::ReadOnly);
}
/** @short Check to see whether the data which concern this object has arrived already */
void MsgPartNetworkReply::slotModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
    Q_UNUSED(bottomRight);
    // FIXME: use bottomRight as well!
    if (topLeft.model() != part.model()) {
        return;
    }
    if (topLeft == part) {
        slotMyDataChanged();
    }
}