File indexing completed on 2024-04-28 12:23:21

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