File indexing completed on 2024-03-24 04:38:29
0001 /*************************************************************************** 0002 * Copyright 2007 Niko Sams <niko.sams@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 ***************************************************************************/ 0010 #include "uploadprojectmodel.h" 0011 0012 #include <kconfiggroup.h> 0013 #include <kfileitem.h> 0014 #include <QDir> 0015 #include "kdevuploaddebug.h" 0016 0017 #include <interfaces/iproject.h> 0018 #include <util/path.h> 0019 0020 #include <project/projectmodel.h> 0021 0022 UploadProjectModel::UploadProjectModel(KDevelop::IProject* project, QObject *parent) 0023 : QSortFilterProxyModel(parent), m_project(project), m_rootItem(nullptr) 0024 { 0025 } 0026 0027 UploadProjectModel::~UploadProjectModel() 0028 { 0029 } 0030 0031 bool UploadProjectModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const 0032 { 0033 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); 0034 KDevelop::ProjectBaseItem* item = projectModel()->itemFromIndex(index); 0035 if (!item) return false; 0036 if (item->project() != m_project) return false; 0037 if (!m_rootItem) return true; 0038 0039 //is source a child of rootItem? 0040 QModelIndex i = index; 0041 while(i.isValid()) { 0042 if (m_rootItem->index() == i) return true; 0043 i = i.parent(); 0044 } 0045 0046 //is source a parent of rootItem? 0047 i = m_rootItem->index(); 0048 while (i.isValid()) { 0049 if (index == i) return true; 0050 i = i.parent(); 0051 } 0052 0053 return false; 0054 } 0055 0056 Qt::ItemFlags UploadProjectModel::flags(const QModelIndex & index) const 0057 { 0058 Qt::ItemFlags ret = QSortFilterProxyModel::flags(index); 0059 ret |= Qt::ItemIsUserCheckable; 0060 ret &= ~Qt::ItemIsEditable; 0061 return ret; 0062 } 0063 0064 QVariant UploadProjectModel::data(const QModelIndex & indx, int role) const 0065 { 0066 if (indx.isValid() && role == Qt::CheckStateRole) { 0067 KDevelop::ProjectBaseItem* i = item(indx); 0068 if (i->file() && m_profileConfigGroup.isValid()) { 0069 if (m_checkStates.contains(indx)) { 0070 return m_checkStates.value(indx); 0071 } else { 0072 qCDebug(KDEVUPLOAD) << "project folder" << m_project->path().path() << "file" << i << i->file(); 0073 qCDebug(KDEVUPLOAD) << "file url" << i->file()->path().path(); 0074 QString url = m_project->path().relativePath(i->file()->path()); 0075 qCDebug(KDEVUPLOAD) << "resulting url" << url; 0076 QDateTime uploadTime(m_profileConfigGroup.readEntry(url, QDateTime())); 0077 if (uploadTime.isValid()) { 0078 KFileItem fileItem(i->file()->path().toUrl()); 0079 QDateTime modTime = fileItem.time(KFileItem::ModificationTime); 0080 if (modTime > uploadTime) { 0081 return Qt::Checked; 0082 } else { 0083 return Qt::Unchecked; 0084 } 0085 } else { 0086 return Qt::Checked; 0087 } 0088 } 0089 } else if (i->folder() && m_profileConfigGroup.isValid()) { 0090 if (!rowCount(indx)) { 0091 //empty folder - should be uploaded too 0092 if (m_checkStates.contains(indx)) { 0093 return m_checkStates.value(indx); 0094 } else { 0095 //don't check for ModificationTime as we do for files 0096 QString url = m_project->path().relativePath(i->folder()->path()); 0097 QDateTime uploadTime(m_profileConfigGroup.readEntry(url, QDateTime())); 0098 if (uploadTime.isValid()) { 0099 return Qt::Unchecked; 0100 } else { 0101 return Qt::Checked; 0102 } 0103 } 0104 } 0105 bool allChecked = true; 0106 bool noneChecked = true; 0107 for (int j = 0; j < rowCount(indx); j++) { 0108 Qt::CheckState s = static_cast<Qt::CheckState>(data(index(j, 0, indx), role).toInt()); 0109 if (s == Qt::Checked) { 0110 noneChecked = false; 0111 } else if (s == Qt::Unchecked) { 0112 allChecked = false; 0113 } else { 0114 return Qt::PartiallyChecked; 0115 } 0116 } 0117 if (allChecked) { 0118 return Qt::Checked; 0119 } else if (noneChecked) { 0120 return Qt::Unchecked; 0121 } 0122 return Qt::PartiallyChecked; 0123 } else { 0124 return QVariant(); 0125 } 0126 } 0127 return QSortFilterProxyModel::data(indx, role); 0128 } 0129 0130 bool UploadProjectModel::setData ( const QModelIndex & indx, const QVariant & value, int role) 0131 { 0132 if (indx.isValid() && role == Qt::CheckStateRole) { 0133 KDevelop::ProjectBaseItem* i = item(indx); 0134 if (i->file()) { 0135 Qt::CheckState s = static_cast<Qt::CheckState>(value.toInt()); 0136 m_checkStates.insert(indx, s); 0137 0138 emit dataChanged(indx, indx); 0139 return true; 0140 } else if (i->folder()) { 0141 if (!rowCount(indx)) { 0142 //empty folder - should be uploaded too 0143 Qt::CheckState s = static_cast<Qt::CheckState>(value.toInt()); 0144 m_checkStates.insert(indx, s); 0145 emit dataChanged(indx, indx); 0146 } else { 0147 //recursive check/uncheck 0148 QModelIndex i = indx; 0149 while((i = nextRecursionIndex(i, indx)).isValid()) { 0150 setData(i, value, role); 0151 } 0152 } 0153 0154 emit dataChanged(indx, indx); 0155 return true; 0156 } 0157 } 0158 return QSortFilterProxyModel::setData(indx, value, role); 0159 } 0160 0161 void UploadProjectModel::setProfileConfigGroup(const KConfigGroup& group) 0162 { 0163 beginResetModel(); 0164 m_profileConfigGroup = group; 0165 m_checkStates.clear(); 0166 endResetModel(); 0167 } 0168 0169 KConfigGroup UploadProjectModel::profileConfigGroup() const 0170 { 0171 return m_profileConfigGroup; 0172 } 0173 0174 KDevelop::ProjectModel* UploadProjectModel::projectModel() const 0175 { 0176 return qobject_cast<KDevelop::ProjectModel*>(sourceModel()); 0177 } 0178 0179 KDevelop::ProjectBaseItem* UploadProjectModel::item(const QModelIndex& index) const 0180 { 0181 return projectModel()->itemFromIndex(mapToSource(index)); 0182 } 0183 0184 QModelIndex UploadProjectModel::nextRecursionIndex(const QModelIndex& current, const QModelIndex& root) const 0185 { 0186 QModelIndex ret; 0187 if (rowCount(current) > 0) { 0188 //firstChild 0189 return index(0, 0, current); 0190 } else if (current != root && current.isValid() && 0191 current.row()+1 < rowCount(current.parent())) { 0192 //nextSibling 0193 return index(current.row()+1, 0, current.parent()); 0194 } 0195 QModelIndex i = current; 0196 while (i.parent() != root && i.isValid() && i.parent().isValid()) { 0197 if (i.parent().row()+1 < rowCount(i.parent().parent())) { 0198 //parent+.nextSibling 0199 return index(i.parent().row()+1, 0, i.parent().parent()); 0200 } 0201 i = i.parent(); 0202 } 0203 0204 //finished 0205 return QModelIndex(); 0206 } 0207 0208 void UploadProjectModel::setRootItem(KDevelop::ProjectBaseItem* item) 0209 { 0210 beginResetModel(); 0211 m_rootItem = item; 0212 endResetModel(); 0213 } 0214 0215 QString UploadProjectModel::currentProfileName() 0216 { 0217 return m_profileConfigGroup.readEntry("name", QString()); 0218 } 0219 0220 QUrl UploadProjectModel::currentProfileUrl() 0221 { 0222 return m_profileConfigGroup.readEntry("url", QUrl()); 0223 } 0224 0225 QUrl UploadProjectModel::currentProfileLocalUrl() 0226 { 0227 return m_profileConfigGroup.readEntry("localUrl", QUrl()); 0228 } 0229 0230 void UploadProjectModel::checkAll() 0231 { 0232 setData(index(0, 0), Qt::Checked, Qt::CheckStateRole); 0233 } 0234 0235 void UploadProjectModel::checkModified() 0236 { 0237 QMapIterator<QModelIndex, Qt::CheckState> i(m_checkStates); 0238 m_checkStates.clear(); 0239 while (i.hasNext()) { 0240 i.next(); 0241 emit dataChanged(i.key(), i.key()); 0242 } 0243 } 0244 0245 void UploadProjectModel::checkInvert() 0246 { 0247 QModelIndex index; 0248 while((index = nextRecursionIndex(index)).isValid()) { 0249 KDevelop::ProjectBaseItem* i = item(index); 0250 if (!(i->folder() && rowCount(index) > 0)) { 0251 //invert files and empty folders 0252 Qt::CheckState v = static_cast<Qt::CheckState>(data(index, Qt::CheckStateRole).toInt()); 0253 if (v == Qt::Unchecked) v = Qt::Checked; else v = Qt::Unchecked; 0254 setData(index, v, Qt::CheckStateRole); 0255 } 0256 } 0257 } 0258 0259 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on