File indexing completed on 2024-05-12 05:44:26

0001 /***************************************************************************
0002  *   Copyright (C) 2007 by Rajko Albrecht  ral@alwins-world.de             *
0003  *   https://kde.org/applications/development/org.kde.kdesvn               *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0019  ***************************************************************************/
0020 
0021 #include "logitemmodel.h"
0022 #include "logmodelhelper.h"
0023 
0024 #include "svnqt/client.h"
0025 
0026 #include <KLocalizedString>
0027 #include <QMap>
0028 #include <QTreeWidget>
0029 
0030 SvnLogModel::SvnLogModel(const svn::LogEntriesMapPtr &_log, const QString &m_name, QObject *parent)
0031     : QAbstractListModel(parent)
0032     , m_emptyString()
0033     , m_min(-1)
0034     , m_max(-1)
0035     , m_name()
0036     , m_left(-1)
0037     , m_right(-1)
0038 {
0039     setLogData(_log, m_name);
0040 }
0041 
0042 void SvnLogModel::setLogData(const svn::LogEntriesMapPtr &log, const QString &name)
0043 {
0044     beginResetModel();
0045     m_data.clear();
0046     endResetModel();
0047     m_name = name;
0048     m_left = m_right = -1;
0049 
0050     QMap<long int, SvnLogModelNodePtr> itemMap;
0051 
0052     m_min = m_max = -1;
0053 
0054     if (log->isEmpty()) {
0055         return;
0056     }
0057 
0058     m_data.reserve(log->count());
0059     beginInsertRows(QModelIndex(), 0, log->count() - 1);
0060     for (const svn::LogEntry &entry : qAsConst(*log)) {
0061         SvnLogModelNodePtr np(new SvnLogModelNode(entry));
0062         m_data.append(np);
0063         if (entry.revision > m_max) {
0064             m_max = entry.revision;
0065         }
0066         if (entry.revision < m_min || m_min == -1) {
0067             m_min = entry.revision;
0068         }
0069         itemMap[entry.revision] = np;
0070     }
0071     endInsertRows();
0072     QString bef = m_name;
0073     qlonglong rev;
0074     // YES! I'd checked it: this is much faster than getting list of keys
0075     // and iterating over that list!
0076     for (long c = m_max; c > -1; --c) {
0077         if (!itemMap.contains(c)) {
0078             continue;
0079         }
0080         if (itemMap[c]->realName().isEmpty()) {
0081             itemMap[c]->setRealName(bef);
0082         }
0083         itemMap[c]->copiedFrom(bef, rev);
0084     }
0085 }
0086 
0087 qlonglong SvnLogModel::min() const
0088 {
0089     return m_min;
0090 }
0091 
0092 qlonglong SvnLogModel::max() const
0093 {
0094     return m_max;
0095 }
0096 
0097 int SvnLogModel::rowCount(const QModelIndex &parent) const
0098 {
0099     return parent.isValid() ? 0 : m_data.count();
0100 }
0101 
0102 QVariant SvnLogModel::data(const QModelIndex &index, int role) const
0103 {
0104     if (!index.isValid() || index.row() >= m_data.count()) {
0105         return QVariant();
0106     }
0107     const SvnLogModelNodePtr &_l = m_data.at(index.row());
0108 
0109     switch (role) {
0110     case Qt::DisplayRole:
0111         switch (index.column()) {
0112         case Revision:
0113             return _l->revision();
0114         case Author:
0115             return _l->author();
0116         case Date:
0117             return _l->date();
0118         case Message:
0119             return _l->shortMessage();
0120         }
0121         break;
0122     case Qt::DecorationRole:
0123         if (index.column() == 0) {
0124             if (index.row() == m_left) {
0125                 return QIcon::fromTheme(QStringLiteral("kdesvnleft"));
0126             }
0127             if (index.row() == m_right) {
0128                 return QIcon::fromTheme(QStringLiteral("kdesvnright"));
0129             }
0130             return QStringLiteral("   ");
0131         }
0132         break;
0133     }
0134     return QVariant();
0135 }
0136 
0137 qlonglong SvnLogModel::toRevision(const QModelIndex &index) const
0138 {
0139     if (!index.isValid() || index.row() >= m_data.count()) {
0140         return -1;
0141     }
0142     return m_data[index.row()]->revision();
0143 }
0144 
0145 const QString &SvnLogModel::fullMessage(const QModelIndex &index) const
0146 {
0147     if (!index.isValid() || index.row() >= m_data.count()) {
0148         return m_emptyString;
0149     }
0150     return m_data[index.row()]->message();
0151 }
0152 
0153 const QString &SvnLogModel::realName(const QModelIndex &index)
0154 {
0155     if (!index.isValid() || index.row() >= m_data.count()) {
0156         return m_emptyString;
0157     }
0158     return m_data[index.row()]->realName();
0159 }
0160 
0161 int SvnLogModel::columnCount(const QModelIndex &idx) const
0162 {
0163     return idx.isValid() ? 0 : Count;
0164 }
0165 
0166 QVariant SvnLogModel::headerData(int section, Qt::Orientation orientation, int role) const
0167 {
0168     Q_UNUSED(orientation);
0169     switch (role) {
0170     case Qt::DisplayRole:
0171         switch (section) {
0172         case Revision:
0173             return i18n("Revision");
0174         case Author:
0175             return i18n("Author");
0176         case Date:
0177             return i18n("Date");
0178         case Message:
0179             return i18n("Message");
0180         }
0181     }
0182     return QVariant();
0183 }
0184 
0185 SvnLogModelNodePtr SvnLogModel::indexNode(const QModelIndex &index) const
0186 {
0187     if (!index.isValid() || index.row() >= m_data.count()) {
0188         return SvnLogModelNodePtr();
0189     }
0190     return m_data.at(index.row());
0191 }
0192 
0193 void SvnLogModel::fillChangedPaths(const QModelIndex &index, QTreeWidget *where)
0194 {
0195     if (!where || !index.isValid() || index.row() >= m_data.count()) {
0196         return;
0197     }
0198     where->clear();
0199     const SvnLogModelNodePtr &_l = m_data.at(index.row());
0200     if (_l->changedPaths().isEmpty()) {
0201         return;
0202     }
0203     QList<QTreeWidgetItem *> _list;
0204     for (const svn::LogChangePathEntry &entry : _l->changedPaths()) {
0205         _list.append(new LogChangePathItem(entry));
0206     }
0207     where->addTopLevelItems(_list);
0208     where->resizeColumnToContents(0);
0209     where->resizeColumnToContents(1);
0210     where->resizeColumnToContents(2);
0211     where->sortByColumn(1, Qt::AscendingOrder);
0212 }
0213 
0214 int SvnLogModel::leftRow() const
0215 {
0216     return m_left;
0217 }
0218 
0219 int SvnLogModel::rightRow() const
0220 {
0221     return m_right;
0222 }
0223 
0224 void SvnLogModel::setLeftRow(int v)
0225 {
0226     if (m_right == v) {
0227         m_right = -1;
0228     }
0229     m_left = v;
0230 }
0231 
0232 void SvnLogModel::setRightRow(int v)
0233 {
0234     if (m_left == v) {
0235         m_left = -1;
0236     }
0237     m_right = v;
0238 }
0239 
0240 //
0241 // SvnLogSortModel
0242 //
0243 void SvnLogSortModel::setSourceModel(QAbstractItemModel *sourceModel)
0244 {
0245     m_sourceModel = qobject_cast<SvnLogModel *>(sourceModel);
0246     QSortFilterProxyModel::setSourceModel(sourceModel);
0247 }
0248 
0249 bool SvnLogSortModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
0250 {
0251     if (source_left.column() != source_right.column() || !m_sourceModel) {
0252         return QSortFilterProxyModel::lessThan(source_left, source_right);
0253     }
0254     const SvnLogModelNodePtr &dataLeft = m_sourceModel->m_data.at(source_left.row());
0255     const SvnLogModelNodePtr &dataRight = m_sourceModel->m_data.at(source_right.row());
0256     switch (source_left.column()) {
0257     case SvnLogModel::Author:
0258         return dataLeft->author() < dataRight->author();
0259     case SvnLogModel::Revision:
0260         return dataLeft->revision() < dataRight->revision();
0261     case SvnLogModel::Date:
0262         return dataLeft->dateMSec() < dataRight->dateMSec();
0263     case SvnLogModel::Message:
0264         return dataLeft->message() < dataRight->message();
0265     default:
0266         break;
0267     }
0268     return QSortFilterProxyModel::lessThan(source_left, source_right);
0269 }
0270 
0271 #include "moc_logitemmodel.cpp"