File indexing completed on 2024-05-12 04:38:54

0001 /*
0002     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "vcseventmodel.h"
0008 
0009 #include <QModelIndex>
0010 #include <QVariant>
0011 #include <QDateTime>
0012 #include <QList>
0013 #include <QLocale>
0014 
0015 #include <KLocalizedString>
0016 
0017 #include "../vcsevent.h"
0018 #include "../vcsrevision.h"
0019 #include <vcsjob.h>
0020 #include <interfaces/ibasicversioncontrol.h>
0021 #include <interfaces/icore.h>
0022 #include <interfaces/iruncontroller.h>
0023 
0024 namespace KDevelop
0025 {
0026 
0027 class VcsBasicEventModelPrivate
0028 {
0029 public:
0030     QList<KDevelop::VcsEvent> m_events;
0031 };
0032 
0033 VcsBasicEventModel::VcsBasicEventModel(QObject* parent)
0034     : QAbstractTableModel(parent)
0035     , d_ptr(new VcsBasicEventModelPrivate)
0036 {
0037 }
0038 
0039 VcsBasicEventModel::~VcsBasicEventModel() = default;
0040 
0041 int VcsBasicEventModel::rowCount(const QModelIndex& parent) const
0042 {
0043     Q_D(const VcsBasicEventModel);
0044 
0045     return parent.isValid() ? 0 : d->m_events.count();
0046 }
0047 
0048 int VcsBasicEventModel::columnCount(const QModelIndex& parent) const
0049 {
0050     return parent.isValid() ? 0 : ColumnCount;
0051 }
0052 
0053 QVariant VcsBasicEventModel::data(const QModelIndex& idx, int role) const
0054 {
0055     Q_D(const VcsBasicEventModel);
0056 
0057     if( !idx.isValid() || role != Qt::DisplayRole )
0058         return QVariant();
0059 
0060     if( idx.row() < 0 || idx.row() >= rowCount() || idx.column() < 0 || idx.column() >= columnCount() )
0061         return QVariant();
0062 
0063     KDevelop::VcsEvent ev = d->m_events.at( idx.row() );
0064     switch( idx.column() )
0065     {
0066         case RevisionColumn:
0067             return QVariant( ev.revision().revisionValue() );
0068         case SummaryColumn:
0069             // show the first line only
0070             return QVariant( ev.message().section(QLatin1Char('\n'), 0, 0) );
0071         case AuthorColumn:
0072             return QVariant( ev.author() );
0073         case DateColumn:
0074             return QVariant( QLocale().toString( ev.date() ) );
0075         default:
0076             break;
0077     }
0078     return QVariant();
0079 }
0080 
0081 QVariant VcsBasicEventModel::headerData(int section, Qt::Orientation orientation, int role) const
0082 {
0083     if( section < 0 || section >= columnCount() || orientation != Qt::Horizontal || role != Qt::DisplayRole )
0084         return QVariant();
0085     switch( section )
0086     {
0087         case RevisionColumn:
0088             return QVariant( i18nc("@title:column", "Revision") );
0089         case SummaryColumn:
0090             return QVariant( i18nc("@title:column", "Message") );
0091         case AuthorColumn:
0092             return QVariant( i18nc("@title:column", "Author") );
0093         case DateColumn:
0094             return QVariant( i18nc("@title:column", "Date") );
0095         default:
0096             break;
0097     }
0098     return QVariant();
0099 }
0100 
0101 void VcsBasicEventModel::addEvents(const QList<KDevelop::VcsEvent>& list)
0102 {
0103     Q_D(VcsBasicEventModel);
0104 
0105     if( list.isEmpty() )
0106         return;
0107 
0108     beginInsertRows( QModelIndex(), rowCount(), rowCount()+list.count()-1 );
0109     d->m_events += list;
0110     endInsertRows();
0111 }
0112 
0113 KDevelop::VcsEvent VcsBasicEventModel::eventForIndex(const QModelIndex& idx) const
0114 {
0115     Q_D(const VcsBasicEventModel);
0116 
0117     if( !idx.isValid() || idx.row() < 0 || idx.row() >= rowCount() )
0118     {
0119         return KDevelop::VcsEvent();
0120     }
0121     return d->m_events.at( idx.row() );
0122 }
0123 
0124 class VcsEventLogModelPrivate
0125 {
0126 public:
0127     KDevelop::IBasicVersionControl* m_iface;
0128     VcsRevision m_rev;
0129     QUrl m_url;
0130     bool done;
0131     bool fetching;
0132 };
0133 
0134 VcsEventLogModel::VcsEventLogModel(KDevelop::IBasicVersionControl* iface, const VcsRevision& rev, const QUrl& url, QObject* parent)
0135     : KDevelop::VcsBasicEventModel(parent)
0136     , d_ptr(new VcsEventLogModelPrivate)
0137 {
0138     Q_D(VcsEventLogModel);
0139 
0140     d->m_iface = iface;
0141     d->m_rev = rev;
0142     d->m_url = url;
0143     d->done = false;
0144     d->fetching = false;
0145 }
0146 
0147 VcsEventLogModel::~VcsEventLogModel() = default;
0148 
0149 bool VcsEventLogModel::canFetchMore(const QModelIndex& parent) const
0150 {
0151     Q_D(const VcsEventLogModel);
0152 
0153     return !d->done && !d->fetching && !parent.isValid();
0154 }
0155 
0156 void VcsEventLogModel::fetchMore(const QModelIndex& parent)
0157 {
0158     Q_D(VcsEventLogModel);
0159 
0160     d->fetching = true;
0161     Q_ASSERT(!parent.isValid());
0162     Q_UNUSED(parent);
0163     VcsJob* job = d->m_iface->log(d->m_url, d->m_rev, qMax(rowCount(), 100));
0164     connect(this, &VcsEventLogModel::destroyed, job, [job] { job->kill(); });
0165     connect(job, &VcsJob::finished, this, &VcsEventLogModel::jobReceivedResults);
0166     ICore::self()->runController()->registerJob( job );
0167 }
0168 
0169 void VcsEventLogModel::jobReceivedResults(KJob* job)
0170 {
0171     Q_D(VcsEventLogModel);
0172 
0173     const QList<QVariant> l = qobject_cast<KDevelop::VcsJob *>(job)->fetchResults().toList();
0174     if(l.isEmpty() || job->error()!=0) {
0175         d->done = true;
0176         return;
0177     }
0178     QList<KDevelop::VcsEvent> newevents;
0179     for (const QVariant& v : l) {
0180         if( v.canConvert<KDevelop::VcsEvent>() )
0181         {
0182             newevents << v.value<KDevelop::VcsEvent>();
0183         }
0184     }
0185     d->m_rev = newevents.last().revision();
0186     if (rowCount()) {
0187         newevents.removeFirst();
0188     }
0189     d->done = newevents.isEmpty();
0190     addEvents( newevents );
0191     d->fetching = false;
0192 }
0193 
0194 }
0195 
0196 #include "moc_vcseventmodel.cpp"