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"