File indexing completed on 2024-11-10 05:11:09
0001 /* 0002 * Copyright 2018 by Marco Martin <mart@kde.org> 0003 * 0004 * Licensed under the Apache License, Version 2.0 (the "License"); 0005 * you may not use this file except in compliance with the License. 0006 * You may obtain a copy of the License at 0007 * 0008 * http://www.apache.org/licenses/LICENSE-2.0 0009 * 0010 * Unless required by applicable law or agreed to in writing, software 0011 * distributed under the License is distributed on an "AS IS" BASIS, 0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0013 * See the License for the specific language governing permissions and 0014 * limitations under the License. 0015 * 0016 */ 0017 #include "delegatesmodel.h" 0018 #include "abstractdelegate.h" 0019 0020 #include <QTimer> 0021 #include <QDebug> 0022 0023 0024 DelegatesModel::DelegatesModel(QObject *parent) 0025 : QAbstractListModel(parent) 0026 { 0027 m_deleteTimer = new QTimer(this); 0028 m_deleteTimer->setSingleShot(true); 0029 m_deleteTimer->setInterval(2000); 0030 0031 connect(m_deleteTimer, &QTimer::timeout, this, [this]() { 0032 for (auto d : m_delegateLoadersToDelete) { 0033 d->deleteLater(); 0034 } 0035 m_delegateLoadersToDelete.clear(); 0036 }); 0037 } 0038 0039 DelegatesModel::~DelegatesModel() 0040 { 0041 //TODO: necessary? 0042 for (auto c : m_delegateLoadersToDelete) { 0043 c->deleteLater(); 0044 } 0045 for (auto c : m_delegateLoaders) { 0046 c->deleteLater(); 0047 } 0048 } 0049 0050 void DelegatesModel::insertDelegateLoaders(int position, QList<DelegateLoader *> loaders) 0051 { 0052 if (position < 0 || position > m_delegateLoaders.count()) { 0053 return; 0054 } 0055 0056 beginInsertRows(QModelIndex(), position, position + loaders.count() - 1); 0057 0058 int i = 0; 0059 for (auto *loader : loaders) { 0060 m_delegateLoaders.insert(position + i, loader); 0061 if (!loader->delegate()) { 0062 connect(loader, &DelegateLoader::delegateCreated, this, [this, loader]() { 0063 int row = m_delegateLoaders.indexOf(loader); 0064 emit dataChanged(index(row, 0), index(row, 0), {DelegateUi}); 0065 }); 0066 } 0067 connect(loader, &QObject::destroyed, this, [this](QObject *obj) { 0068 const int index = m_delegateLoaders.indexOf(qobject_cast<DelegateLoader *>(obj)); 0069 //if the loader is in the list, remove it 0070 if (index > -1) { 0071 removeRows(index, 1, QModelIndex()); 0072 } 0073 }); 0074 ++i; 0075 } 0076 0077 endInsertRows(); 0078 0079 m_currentIndex = m_delegateLoaders.indexOf(loaders.first()); 0080 emit currentIndexChanged(); 0081 } 0082 0083 void DelegatesModel::clear() 0084 { 0085 0086 beginResetModel(); 0087 m_delegateLoadersToDelete = m_delegateLoaders; 0088 m_deleteTimer->start(); 0089 m_delegateLoaders.clear(); 0090 endResetModel(); 0091 } 0092 0093 QList<AbstractDelegate *> DelegatesModel::delegates() const 0094 { 0095 QList<AbstractDelegate *> delegates; 0096 0097 for (auto c : m_delegateLoaders) { 0098 if (c->delegate()) { 0099 delegates << c->delegate(); 0100 } 0101 } 0102 0103 return delegates; 0104 } 0105 0106 bool DelegatesModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) 0107 { 0108 if (sourceParent.isValid() || destinationParent.isValid()) { 0109 return false; 0110 } 0111 0112 if (count <= 0 || sourceRow == destinationChild || sourceRow < 0 || sourceRow >= m_delegateLoaders.count() || 0113 destinationChild < 0 || destinationChild >= m_delegateLoaders.count() || count - destinationChild > m_delegateLoaders.count() - sourceRow) { 0114 return false; 0115 } 0116 const int sourceLast = sourceRow + count - 1; 0117 0118 //beginMoveRows wants indexes before the source rows are removed from the old order 0119 if (!beginMoveRows(sourceParent, sourceRow, sourceLast, destinationParent, destinationChild)) { 0120 return false; 0121 } 0122 0123 if (sourceRow < destinationChild) { 0124 for (int i = count - 1; i >= 0; --i) { 0125 m_delegateLoaders.move(sourceRow + i, qMin(destinationChild + i, m_delegateLoaders.count() - 1)); 0126 } 0127 } else { 0128 for (int i = 0; i < count; ++i) { 0129 m_delegateLoaders.move(sourceRow + i, destinationChild + i); 0130 } 0131 } 0132 0133 endMoveRows(); 0134 return true; 0135 } 0136 0137 bool DelegatesModel::removeRows(int row, int count, const QModelIndex &parent) 0138 { 0139 if (row < 0 || count <= 0 || row + count > m_delegateLoaders.count() || parent.isValid()) { 0140 return false; 0141 } 0142 0143 beginRemoveRows(parent, row, row + count - 1); 0144 std::copy(m_delegateLoaders.begin() + row, m_delegateLoaders.begin() + row + count, 0145 std::back_inserter(m_delegateLoadersToDelete)); 0146 m_deleteTimer->start(); 0147 m_delegateLoaders.erase(m_delegateLoaders.begin() + row, m_delegateLoaders.begin() + row + count); 0148 0149 endRemoveRows(); 0150 return true; 0151 } 0152 0153 0154 int DelegatesModel::rowCount(const QModelIndex &parent) const 0155 { 0156 if (parent.isValid()) { 0157 return 0; 0158 } 0159 return m_delegateLoaders.count(); 0160 } 0161 0162 QVariant DelegatesModel::data(const QModelIndex &index, int role) const 0163 { 0164 if (!index.isValid() || index.parent().isValid()) { 0165 return QVariant(); 0166 } 0167 const int row = index.row(); 0168 0169 if (row < 0 || row >= m_delegateLoaders.count() || role != DelegateUi) { 0170 return QVariant(); 0171 } 0172 0173 return QVariant::fromValue(m_delegateLoaders[row]->delegate()); 0174 } 0175 0176 QHash<int, QByteArray> DelegatesModel::roleNames() const 0177 { 0178 return { 0179 {DelegateUi, "delegateUi"} 0180 }; 0181 } 0182