<commit_before>/* This file is part of Zanshin Todo.

   Copyright 2008 <NAME> <<EMAIL>>
   Copyright 2008, 2009 <NAME> <<EMAIL>>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "librarymodel.h"

#include <KIcon>
#include <KLocale>

LibraryModel::LibraryModel(QObject *parent)
    : QAbstractProxyModel(parent), m_inboxToken(1), m_libraryToken(2),
      m_tokenShift(m_libraryToken+1), m_type(Projects)
{
}

LibraryModel::~LibraryModel()
{

}

LibraryModel::LibraryType LibraryModel::type() const
{
    return m_type;
}

void LibraryModel::setType(LibraryType type)
{
    m_type = type;
}

QModelIndex LibraryModel::index(int row, int column, const QModelIndex &parent) const
{
    if (column!=0) return QModelIndex();

    if (parent==QModelIndex()) {
        switch (row) {
        case 0:
            return createIndex(row, column, (void*)m_inboxToken);
        case 1:
            return createIndex(row, column, (void*)m_libraryToken);
        default:
            return QModelIndex();
        }
    }

    return mapFromSource(sourceModel()->index(row, column, mapToSource(parent)));
}

QModelIndex LibraryModel::parent(const QModelIndex &index) const
{
    if (index.column()!=0 || !index.isValid()
     || isInbox(index) || isLibraryRoot(index)) {
        return QModelIndex();
    }

    return mapFromSource(sourceModel()->parent(mapToSource(index)));
}

int LibraryModel::rowCount(const QModelIndex &parent) const
{
    if (parent==QModelIndex()) {
        return 2;
    }

    if (parent.column()!=0) return -1;

    if (isInbox(parent)) {
        return 0;
    }

    if (isLibraryRoot(parent)) {
        return sourceModel()->rowCount();
    }

    return sourceModel()->rowCount(mapToSource(parent));
}

int LibraryModel::columnCount(const QModelIndex &/*parent*/) const
{
    return 1;
}

QStringList LibraryModel::mimeTypes() const
{
    return sourceModel()->mimeTypes();
}

Qt::DropActions LibraryModel::supportedDropActions() const
{
    return sourceModel()->supportedDropActions();
}

Qt::ItemFlags LibraryModel::flags(const QModelIndex &index) const
{
    if (isInbox(index) || isLibraryRoot(index)) {
        return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
    }

    return QAbstractProxyModel::flags(index);
}

QMimeData *LibraryModel::mimeData(const QModelIndexList &indexes) const
{
    QModelIndexList sourceIndexes;
    foreach (const QModelIndex &proxyIndex, indexes) {
        sourceIndexes << mapToSource(proxyIndex);
    }

    return sourceModel()->mimeData(sourceIndexes);
}

bool LibraryModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action,
                                int row, int column, const QModelIndex &parent)
{
    QModelIndex sourceParent = mapToSource(parent);
    return sourceModel()->dropMimeData(mimeData, action, row, column, sourceParent);
}

QVariant LibraryModel::data(const QModelIndex &index, int role) const
{
    if (index.column()!=0 || !index.isValid()) return QVariant();

    if (isInbox(index)) {
        switch (role) {
        case Qt::DisplayRole:
            switch (m_type) {
            case Contexts:
                return i18n("No Context");
            default:
                return i18n("Inbox");
            }
        case Qt::DecorationRole:
            return KIcon("mail-folder-inbox");
        default:
            return QVariant();
        }
    }

    if (isLibraryRoot(index)) {
        switch (role) {
        case Qt::DisplayRole:
            switch (m_type) {
            case Contexts:
                return i18n("Contexts");
            default:
                return i18n("Library");
            }
        case Qt::DecorationRole:
            return KIcon("document-multiple");
        default:
            return QVariant();
        }
    }

    return QAbstractProxyModel::data(index, role);
}

QVariant LibraryModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    return sourceModel()->headerData(section, orientation, role);
}

bool LibraryModel::isInbox(const QModelIndex &index) const
{
    return index.internalId()==m_inboxToken;
}

bool LibraryModel::isLibraryRoot(const QModelIndex &index) const
{
    return index.internalId()==m_libraryToken;
}

QModelIndex LibraryModel::mapToSource(const QModelIndex &proxyIndex) const
{
    if (proxyIndex.column()!=0
     || isInbox(proxyIndex)
     || isLibraryRoot(proxyIndex)) {
        return QModelIndex();
    }

    return m_sourceIndexesList[proxyIndex.internalId()-m_tokenShift];
}

QModelIndex LibraryModel::mapFromSource(const QModelIndex &sourceIndex) const
{
    if (!sourceIndex.isValid()) {
        return index(1, 0); // Index of the library item
    } else {
        qint64 indexOf = m_sourceIndexesList.indexOf(sourceIndex);
        if (indexOf==-1) {
            indexOf = m_sourceIndexesList.size();
            m_sourceIndexesList << sourceIndex;
        }

        return createIndex(sourceIndex.row(), sourceIndex.column(), (void*)(indexOf+m_tokenShift));
    }
}

void LibraryModel::setSourceModel(QAbstractItemModel *source)
{
    if (sourceModel()) {
        disconnect(sourceModel());
    }<commit_msg>Be extra paranoid when mapping an index to source.<commit_after>/* This file is part of Zanshin Todo.

   Copyright 2008 <NAME> <<EMAIL>>
   Copyright 2008, 2009 <NAME> <<EMAIL>>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.
*/

#include "librarymodel.h"

#include <KIcon>
#include <KLocale>

LibraryModel::LibraryModel(QObject *parent)
    : QAbstractProxyModel(parent), m_inboxToken(1), m_libraryToken(2),
      m_tokenShift(m_libraryToken+1), m_type(Projects)
{
}

LibraryModel::~LibraryModel()
{

}

LibraryModel::LibraryType LibraryModel::type() const
{
    return m_type;
}

void LibraryModel::setType(LibraryType type)
{
    m_type = type;
}

QModelIndex LibraryModel::index(int row, int column, const QModelIndex &parent) const
{
    if (column!=0) return QModelIndex();

    if (parent==QModelIndex()) {
        switch (row) {
        case 0:
            return createIndex(row, column, (void*)m_inboxToken);
        case 1:
            return createIndex(row, column, (void*)m_libraryToken);
        default:
            return QModelIndex();
        }
    }

    return mapFromSource(sourceModel()->index(row, column, mapToSource(parent)));
}

QModelIndex LibraryModel::parent(const QModelIndex &index) const
{
    if (index.column()!=0 || !index.isValid()
     || isInbox(index) || isLibraryRoot(index)) {
        return QModelIndex();
    }

    return mapFromSource(sourceModel()->parent(mapToSource(index)));
}

int LibraryModel::rowCount(const QModelIndex &parent) const
{
    if (parent==QModelIndex()) {
        return 2;
    }

    if (parent.column()!=0) return -1;

    if (isInbox(parent)) {
        return 0;
    }

    if (isLibraryRoot(parent)) {
        return sourceModel()->rowCount();
    }

    return sourceModel()->rowCount(mapToSource(parent));
}

int LibraryModel::columnCount(const QModelIndex &/*parent*/) const
{
    return 1;
}

QStringList LibraryModel::mimeTypes() const
{
    return sourceModel()->mimeTypes();
}

Qt::DropActions LibraryModel::supportedDropActions() const
{
    return sourceModel()->supportedDropActions();
}

Qt::ItemFlags LibraryModel::flags(const QModelIndex &index) const
{
    if (isInbox(index) || isLibraryRoot(index)) {
        return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
    }

    return QAbstractProxyModel::flags(index);
}

QMimeData *LibraryModel::mimeData(const QModelIndexList &indexes) const
{
    QModelIndexList sourceIndexes;
    foreach (const QModelIndex &proxyIndex, indexes) {
        sourceIndexes << mapToSource(proxyIndex);
    }

    return sourceModel()->mimeData(sourceIndexes);
}

bool LibraryModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action,
                                int row, int column, const QModelIndex &parent)
{
    QModelIndex sourceParent = mapToSource(parent);
    return sourceModel()->dropMimeData(mimeData, action, row, column, sourceParent);
}

QVariant LibraryModel::data(const QModelIndex &index, int role) const
{
    if (index.column()!=0 || !index.isValid()) return QVariant();

    if (isInbox(index)) {
        switch (role) {
        case Qt::DisplayRole:
            switch (m_type) {
            case Contexts:
                return i18n("No Context");
            default:
                return i18n("Inbox");
            }
        case Qt::DecorationRole:
            return KIcon("mail-folder-inbox");
        default:
            return QVariant();
        }
    }

    if (isLibraryRoot(index)) {
        switch (role) {
        case Qt::DisplayRole:
            switch (m_type) {
            case Contexts:
                return i18n("Contexts");
            default:
                return i18n("Library");
            }
        case Qt::DecorationRole:
            return KIcon("document-multiple");
        default:
            return QVariant();
        }
    }

    return QAbstractProxyModel::data(index, role);
}

QVariant LibraryModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    return sourceModel()->headerData(section, orientation, role);
}

bool LibraryModel::isInbox(const QModelIndex &index) const
{
    return index.internalId()==m_inboxToken;
}

bool LibraryModel::isLibraryRoot(const QModelIndex &index) const
{
    return index.internalId()==m_libraryToken;
}

QModelIndex LibraryModel::mapToSource(const QModelIndex &proxyIndex) const
{
    if (proxyIndex.column()!=0
     || isInbox(proxyIndex)
     || isLibraryRoot(proxyIndex)) {
        return QModelIndex();
    }

    int pos = proxyIndex.internalId()-m_tokenShift;

    if (pos>=m_sourceIndexesList.size()) {
        return QModelIndex();
    }

    return m_sourceIndexesList[pos];
}

QModelIndex LibraryModel::mapFromSource(const QModelIndex &sourceIndex) const
{
    if (!sourceIndex.isValid()) {
        return index(1, 0); // Index of the library item
    } else {
        qint64 indexOf = m_sourceIndexesList.indexOf(sourceIndex);
        if (indexOf==-1) {
            indexOf = m_sourceIndexesList.size();
            m_sourceIndexesList << sourceIndex;
        }

        return createIndex(sourceIndex.row(), sourceIndex.column(), (void*)(indexOf+m_tokenShift));
    }
}

void LibraryModel::setSourceModel(QAbstractItemModel *source)
{
    if (sourceModel()) {
        disconnect(sourceModel());
    }
{'fraction_non_alphanumeric': 0.11334411990121775, 'fraction_numerical': 0.008686025717448692, 'mean_word_length': 3.189796646450232, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6369517', 'n_tokens_mistral': 3504, 'n_tokens_neox': 3378, 'n_words': 871}