void MsgListModel::setMailbox(const QModelIndex &index) { if (!index.isValid() || !index.data(Imap::Mailbox::RoleMailboxIsSelectable).toBool()) return; waitingForMessages = true; const Model *model = 0; TreeItemMailbox *mbox = dynamic_cast<TreeItemMailbox *>(Model::realTreeItem(index, &model)); Q_ASSERT(mbox); TreeItemMsgList *newList = dynamic_cast<TreeItemMsgList *>( mbox->child(0, const_cast<Model *>(model))); Q_ASSERT(newList); checkPersistentIndex(); if (newList != msgListPtr) { msgListPtr = newList; msgList = msgListPtr->toIndex(const_cast<Model*>(model)); msgListPtr->resetWasUnreadState(); RESET_MODEL; emit mailboxChanged(index); } // We want to tell the Model that it should consider starting the IDLE command. // This shall happen regardless on what this model's idea about a "current mailbox" is because the IMAP connection might have // switched to another mailbox behind the scenes. const_cast<Model *>(model)->switchToMailbox(index); }
void MsgListModel::handleRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) { checkPersistentIndex(); if (! parent.isValid()) return; TreeItemMsgList *newList = dynamic_cast<TreeItemMsgList *>(Model::realTreeItem(parent)); if (msgListPtr && msgListPtr == newList) { beginInsertRows(mapFromSource(parent), start, end); } }
int MsgListModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; checkPersistentIndex(); if (! msgListPtr) return 0; return msgListPtr->rowCount(dynamic_cast<Model *>(sourceModel())); }
QModelIndex MsgListModel::mapToSource(const QModelIndex &proxyIndex) const { checkPersistentIndex(); if (!msgListPtr || !proxyIndex.isValid()) return QModelIndex(); if (proxyIndex.parent().isValid()) return QModelIndex(); Model *model = dynamic_cast<Model *>(sourceModel()); Q_ASSERT(model); return model->createIndex(proxyIndex.row(), 0, msgListPtr->m_children[proxyIndex.row()]); }
void MsgListModel::handleMessageCountPossiblyChanged(QModelIndex mailboxIndex) { checkPersistentIndex(); if (! msgListPtr) return; TreeItem *item = Model::realTreeItem(mailboxIndex); TreeItemMailbox *mailbox = dynamic_cast<TreeItemMailbox *>(item); Q_ASSERT(mailbox); if (mailbox == msgListPtr->parent()) { emit unreadCountPossiblyChanged(); } }
void MsgListModel::handleRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { if (! parent.isValid()) { // Top-level items are tricky :(. As a quick hack, let's just die. resetMe(); return; } checkPersistentIndex(); if (! msgListPtr) return; TreeItem *item = Model::realTreeItem(parent); TreeItemMailbox *mailbox = dynamic_cast<TreeItemMailbox *>(item); TreeItemMsgList *newList = dynamic_cast<TreeItemMsgList *>(item); if (parent.isValid()) { Q_ASSERT(parent.model() == sourceModel()); } else { // a top-level mailbox might have been deleted, so we gotta setup proper pointer mailbox = static_cast<Model *>(sourceModel())->m_mailboxes; Q_ASSERT(mailbox); } if (newList) { if (newList == msgListPtr) { beginRemoveRows(mapFromSource(parent), start, end); for (int i = start; i <= end; ++i) emit messageRemoved(msgListPtr->m_children[i]); } } else if (mailbox) { Q_ASSERT(start > 0); // if we're below it, we're gonna die for (int i = start; i <= end; ++i) { const Model *model = 0; QModelIndex translatedParent; Model::realTreeItem(parent, &model, &translatedParent); // FIXME: this assumes that no rows were removed by the proxy model TreeItemMailbox *m = dynamic_cast<TreeItemMailbox *>(static_cast<TreeItem *>(model->index(i, 0, translatedParent).internalPointer())); Q_ASSERT(m); TreeItem *up = msgListPtr->parent(); while (up) { if (m == up) { resetMe(); return; } up = up->parent(); } } } }
QModelIndex MsgListModel::mapFromSource(const QModelIndex &sourceIndex) const { checkPersistentIndex(); if (! msgListPtr) return QModelIndex(); if (sourceIndex.model() != sourceModel()) return QModelIndex(); if (dynamic_cast<TreeItemMessage *>(Model::realTreeItem(sourceIndex))) { return index(sourceIndex.row(), 0, QModelIndex()); } else { return QModelIndex(); } }
void MsgListModel::handleRowsRemoved(const QModelIndex &parent, int start, int end) { Q_UNUSED(start); Q_UNUSED(end); checkPersistentIndex(); if (! msgListPtr) return; if (! parent.isValid()) { // already handled by resetMe() in handleRowsAboutToBeRemoved() return; } if (dynamic_cast<TreeItemMsgList *>(Model::realTreeItem(parent)) == msgListPtr) endRemoveRows(); }
void MsgListModel::handleRowsInserted(const QModelIndex &parent, int start, int end) { checkPersistentIndex(); if (! parent.isValid()) return; Q_UNUSED(start); Q_UNUSED(end); TreeItemMsgList *newList = dynamic_cast<TreeItemMsgList *>(Model::realTreeItem(parent)); if (msgListPtr && msgListPtr == newList) { endInsertRows(); } if (waitingForMessages) { waitingForMessages = false; emit messagesAvailable(); } }
QModelIndex MsgListModel::currentMailbox() const { checkPersistentIndex(); return msgList.parent(); }
QVariant MsgListModel::data(const QModelIndex &proxyIndex, int role) const { checkPersistentIndex(); if (! msgListPtr) return QVariant(); if (! proxyIndex.isValid() || proxyIndex.model() != this) return QVariant(); TreeItemMessage *message = dynamic_cast<TreeItemMessage *>(Model::realTreeItem(proxyIndex)); Q_ASSERT(message); switch (role) { case Qt::DisplayRole: case Qt::ToolTipRole: switch (proxyIndex.column()) { case SUBJECT: return QAbstractProxyModel::data(proxyIndex, Qt::DisplayRole); case FROM: return QLatin1String("[from]"); case TO: return QLatin1String("[to]"); case CC: return QLatin1String("[cc]"); case BCC: return QLatin1String("[bcc]"); case DATE: return message->envelope(static_cast<Model *>(sourceModel())).date; case RECEIVED_DATE: return message->internalDate(static_cast<Model *>(sourceModel())); case SIZE: return message->size(static_cast<Model *>(sourceModel())); default: return QVariant(); } case RoleIsFetched: case RoleIsUnavailable: case RoleMessageUid: case RoleMessageIsMarkedDeleted: case RoleMessageIsMarkedRead: case RoleMessageIsMarkedForwarded: case RoleMessageIsMarkedReplied: case RoleMessageIsMarkedRecent: case RoleMessageIsMarkedFlagged: case RoleMessageDate: case RoleMessageFrom: case RoleMessageTo: case RoleMessageCc: case RoleMessageBcc: case RoleMessageSender: case RoleMessageReplyTo: case RoleMessageInReplyTo: case RoleMessageMessageId: case RoleMessageSubject: case RoleMessageFlags: case RoleMessageSize: case RoleMessageHeaderReferences: case RoleMessageHeaderListPost: case RoleMessageHeaderListPostNo: case RoleMessageHasAttachments: return dynamic_cast<TreeItemMessage *>(Model::realTreeItem( proxyIndex))->data(static_cast<Model *>(sourceModel()), role); default: return QAbstractProxyModel::data(createIndex(proxyIndex.row(), 0, proxyIndex.internalPointer()), role); } }