diff --git a/vcs/models/vcseventmodel.h b/vcs/models/vcseventmodel.h --- a/vcs/models/vcseventmodel.h +++ b/vcs/models/vcseventmodel.h @@ -22,6 +22,7 @@ #define KDEVPLATFORM_VCSEVENTMODEL_H #include +#include #include @@ -34,7 +35,12 @@ class IBasicVersionControl; class VcsEvent; -class KDEVPLATFORMVCS_EXPORT VcsEventModel : public QAbstractTableModel +/** + * This is a generic model to store a list of VcsEvents. + * + * To add events use @c addEvents + */ +class KDEVPLATFORMVCS_EXPORT VcsBasicEventModel : public QAbstractTableModel { Q_OBJECT public: @@ -46,23 +52,43 @@ ColumnCount, }; - VcsEventModel( KDevelop::IBasicVersionControl* iface, const KDevelop::VcsRevision& rev, const QUrl& url, QObject* parent ); - ~VcsEventModel() override; - int rowCount( const QModelIndex& = QModelIndex() ) const override; - int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - QVariant data( const QModelIndex&, int role = Qt::DisplayRole ) const override; - QVariant headerData( int, Qt::Orientation, int role = Qt::DisplayRole ) const override; - KDevelop::VcsEvent eventForIndex( const QModelIndex& ) const; + VcsBasicEventModel(QObject* parent); + ~VcsBasicEventModel() override; + int rowCount(const QModelIndex& = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + QVariant data(const QModelIndex&, int role = Qt::DisplayRole) const override; + QVariant headerData(int, Qt::Orientation, int role = Qt::DisplayRole) const override; + KDevelop::VcsEvent eventForIndex(const QModelIndex&) const; +protected: + void addEvents(const QList&); + +private: + QScopedPointer d; +}; + +/** + * This model stores a list of VcsEvents corresponding to the log obtained + * via IBasicVersionControl::log for a given revision. The model is populated + * lazily via @c fetchMore. + */ +class KDEVPLATFORMVCS_EXPORT VcsEventLogModel : public VcsBasicEventModel +{ +Q_OBJECT +public: + + VcsEventLogModel(KDevelop::IBasicVersionControl* iface, const KDevelop::VcsRevision& rev, const QUrl& url, QObject* parent); + ~VcsEventLogModel() override; + + /// Adds events to the model via @sa IBasicVersionControl::log void fetchMore(const QModelIndex& parent) override; bool canFetchMore(const QModelIndex& parent) const override; private slots: void jobReceivedResults( KJob* job ); private: - void addEvents( const QList& ); - class VcsEventModelPrivate* const d; + QScopedPointer d; }; } diff --git a/vcs/models/vcseventmodel.cpp b/vcs/models/vcseventmodel.cpp --- a/vcs/models/vcseventmodel.cpp +++ b/vcs/models/vcseventmodel.cpp @@ -38,43 +38,30 @@ namespace KDevelop { -class VcsEventModelPrivate +class VcsBasicEventModelPrivate { public: QList m_events; - KDevelop::IBasicVersionControl* m_iface; - VcsRevision m_rev; - QUrl m_url; - bool done; - bool fetching; }; -VcsEventModel::VcsEventModel( KDevelop::IBasicVersionControl* iface, const VcsRevision& rev, const QUrl& url, QObject* parent ) - : QAbstractTableModel( parent ), d(new VcsEventModelPrivate) +VcsBasicEventModel::VcsBasicEventModel(QObject* parent) + : QAbstractTableModel(parent), d(new VcsBasicEventModelPrivate) { - d->m_iface = iface; - d->m_rev = rev; - d->m_url = url; - d->done = false; - d->fetching = false; } -VcsEventModel::~VcsEventModel() -{ - delete d; -} +VcsBasicEventModel::~VcsBasicEventModel() = default; -int VcsEventModel::rowCount( const QModelIndex& parent) const +int VcsBasicEventModel::rowCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : d->m_events.count(); } -int VcsEventModel::columnCount( const QModelIndex& parent) const +int VcsBasicEventModel::columnCount(const QModelIndex& parent) const { return parent.isValid() ? 0 : ColumnCount; } -QVariant VcsEventModel::data( const QModelIndex& idx, int role ) const +QVariant VcsBasicEventModel::data(const QModelIndex& idx, int role) const { if( !idx.isValid() || role != Qt::DisplayRole ) return QVariant(); @@ -100,7 +87,7 @@ return QVariant(); } -QVariant VcsEventModel::headerData( int section, Qt::Orientation orientation, int role ) const +QVariant VcsBasicEventModel::headerData(int section, Qt::Orientation orientation, int role) const { if( section < 0 || section >= columnCount() || orientation != Qt::Horizontal || role != Qt::DisplayRole ) return QVariant(); @@ -120,7 +107,7 @@ return QVariant(); } -void VcsEventModel::addEvents( const QList& list ) +void VcsBasicEventModel::addEvents(const QList& list) { if( list.isEmpty() ) return; @@ -130,32 +117,54 @@ endInsertRows(); } -KDevelop::VcsEvent VcsEventModel::eventForIndex( const QModelIndex& idx ) const +KDevelop::VcsEvent VcsBasicEventModel::eventForIndex(const QModelIndex& idx) const { if( !idx.isValid() || idx.row() < 0 || idx.row() >= rowCount() ) { return KDevelop::VcsEvent(); } return d->m_events.at( idx.row() ); } -bool VcsEventModel::canFetchMore(const QModelIndex& parent) const +class VcsEventLogModelPrivate +{ +public: + KDevelop::IBasicVersionControl* m_iface; + VcsRevision m_rev; + QUrl m_url; + bool done; + bool fetching; +}; + +VcsEventLogModel::VcsEventLogModel(KDevelop::IBasicVersionControl* iface, const VcsRevision& rev, const QUrl& url, QObject* parent) + : KDevelop::VcsBasicEventModel(parent), d(new VcsEventLogModelPrivate) +{ + d->m_iface = iface; + d->m_rev = rev; + d->m_url = url; + d->done = false; + d->fetching = false; +} + +VcsEventLogModel::~VcsEventLogModel() = default; + +bool VcsEventLogModel::canFetchMore(const QModelIndex& parent) const { return !d->done && !d->fetching && !parent.isValid(); } -void VcsEventModel::fetchMore(const QModelIndex& parent) +void VcsEventLogModel::fetchMore(const QModelIndex& parent) { d->fetching = true; Q_ASSERT(!parent.isValid()); Q_UNUSED(parent); VcsJob* job = d->m_iface->log(d->m_url, d->m_rev, qMax(rowCount(), 100)); - connect(this, &VcsEventModel::destroyed, job, [job] { job->kill(); }); - connect(job, &VcsJob::finished, this, &VcsEventModel::jobReceivedResults); + connect(this, &VcsEventLogModel::destroyed, job, [job] { job->kill(); }); + connect(job, &VcsJob::finished, this, &VcsEventLogModel::jobReceivedResults); ICore::self()->runController()->registerJob( job ); } -void VcsEventModel::jobReceivedResults(KJob* job) +void VcsEventLogModel::jobReceivedResults(KJob* job) { QList l = qobject_cast(job)->fetchResults().toList(); if(l.isEmpty() || job->error()!=0) { @@ -171,13 +180,12 @@ } } d->m_rev = newevents.last().revision(); - if(!d->m_events.isEmpty()) { + if (rowCount()) { newevents.removeFirst(); } d->done = newevents.isEmpty(); addEvents( newevents ); d->fetching = false; } } - diff --git a/vcs/widgets/vcseventwidget.cpp b/vcs/widgets/vcseventwidget.cpp --- a/vcs/widgets/vcseventwidget.cpp +++ b/vcs/widgets/vcseventwidget.cpp @@ -65,7 +65,7 @@ Ui::VcsEventWidget* m_ui; VcsItemEventModel* m_detailModel; - VcsEventModel *m_logModel; + VcsEventLogModel *m_logModel; QUrl m_url; QModelIndex m_contextIndex; VcsEventWidget* q; @@ -197,7 +197,7 @@ d->m_ui = new Ui::VcsEventWidget(); d->m_ui->setupUi(this); - d->m_logModel = new VcsEventModel(iface, rev, url, this); + d->m_logModel = new VcsEventLogModel(iface, rev, url, this); d->m_ui->eventView->setModel( d->m_logModel ); d->m_ui->eventView->sortByColumn(0, Qt::DescendingOrder); d->m_ui->eventView->setContextMenuPolicy( Qt::CustomContextMenu );