File indexing completed on 2024-06-16 04:16:19
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Saurabh Kumar <saurabhk660@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "CommentModel.h" 0008 0009 #include <QDebug> 0010 #include <QMimeData> 0011 #include <QRegularExpression> 0012 0013 #include <kis_icon.h> 0014 0015 StoryboardCommentModel::StoryboardCommentModel(QObject *parent) 0016 : QAbstractListModel(parent) 0017 { 0018 //initialize variables 0019 } 0020 0021 int StoryboardCommentModel::rowCount(const QModelIndex &parent) const 0022 { 0023 if (parent.isValid()) return 0; 0024 return m_commentList.count(); 0025 } 0026 0027 QVariant StoryboardCommentModel::data(const QModelIndex &index, int role) const 0028 { 0029 0030 if (!index.isValid()) { 0031 return QVariant(); 0032 } 0033 if (index.row() >= m_commentList.size()) { 0034 return QVariant(); 0035 } 0036 if (role == Qt::DisplayRole || role == Qt::EditRole) { 0037 return m_commentList.at(index.row()).name; 0038 } 0039 if (role == Qt::DecorationRole) { 0040 if (m_commentList.at(index.row()).visibility) { 0041 return KisIconUtils::loadIcon("visible"); 0042 } 0043 else { 0044 return KisIconUtils::loadIcon("novisible"); 0045 } 0046 } 0047 return QVariant(); 0048 0049 } 0050 0051 bool StoryboardCommentModel::setData(const QModelIndex & index, const QVariant & value, int role) 0052 { 0053 if (index.isValid() && (role == Qt::EditRole || role == Qt::DisplayRole)) { 0054 // POST KRITA/5.0 TODO -- we should be storing this as a map, not an array! 0055 // We only want 1 comment field per comment track title. A data change would 0056 // be appropriate here. 0057 QStringList nameList; 0058 Q_FOREACH(const StoryboardComment& comment, m_commentList) { 0059 nameList << comment.name; 0060 } 0061 0062 0063 QString desiredName = value.toString(); 0064 int splitPoint = desiredName.length(); 0065 while (desiredName.at(splitPoint - 1).isDigit()) { 0066 splitPoint--; 0067 } 0068 0069 const QString prefix = desiredName.left(splitPoint); 0070 int existingNames = prefix.mid(splitPoint).toInt(); 0071 0072 while(nameList.contains(desiredName)) { 0073 existingNames++; 0074 desiredName = prefix + QString::number(existingNames); 0075 } 0076 0077 m_commentList[index.row()].name = desiredName; 0078 emit dataChanged(index, index); 0079 emit sigCommentListChanged(); 0080 return true; 0081 } 0082 0083 if (index.isValid() && role == Qt::DecorationRole) { 0084 m_commentList[index.row()].visibility = !m_commentList[index.row()].visibility; 0085 emit dataChanged(index, index); 0086 emit sigCommentListChanged(); 0087 return true; 0088 } 0089 return false; 0090 } 0091 0092 Qt::ItemFlags StoryboardCommentModel::flags(const QModelIndex & index) const 0093 { 0094 if (!index.isValid()) { 0095 return Qt::ItemIsDropEnabled; 0096 } 0097 return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | 0098 Qt::ItemIsEditable | Qt::ItemIsEnabled ; 0099 } 0100 0101 bool StoryboardCommentModel::insertRows(int position, int rows, const QModelIndex &/*parent*/) 0102 { 0103 beginInsertRows(QModelIndex(), position, position+rows-1); 0104 0105 for (int row = 0; row < rows; ++row) { 0106 StoryboardComment newcomment; 0107 newcomment.name = "Comment"; 0108 newcomment.visibility = true; 0109 0110 if (position < 0 || position > m_commentList.size()) { 0111 return false; 0112 } 0113 m_commentList.insert(position, newcomment); 0114 } 0115 0116 endInsertRows(); 0117 emit sigCommentListChanged(); 0118 return true; 0119 } 0120 0121 bool StoryboardCommentModel::removeRows(int position, int rows, const QModelIndex &/*parent*/) 0122 { 0123 if (rows <= 0) { 0124 return false; 0125 } 0126 beginRemoveRows(QModelIndex(), position, position+rows-1); 0127 0128 for (int row = 0; row < rows; ++row) { 0129 if (position < 0 || position >= m_commentList.size()) { 0130 return false; 0131 } 0132 m_commentList.removeAt(position); 0133 } 0134 endRemoveRows(); 0135 emit sigCommentListChanged(); 0136 return true; 0137 } 0138 0139 bool StoryboardCommentModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, 0140 const QModelIndex &destinationParent, int destinationChild) 0141 { 0142 if (destinationChild == sourceRow || destinationChild == sourceRow + 1) { 0143 return false; 0144 } 0145 if (destinationChild > sourceRow + count - 1) { 0146 //we adjust for the upward shift, see qt doc for why this is needed 0147 beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild + count - 1); 0148 destinationChild = destinationChild - count; 0149 } 0150 else { 0151 beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild); 0152 } 0153 for (int row = 0; row < count; row++) { 0154 if (sourceRow < 0 || sourceRow >= m_commentList.size()) { 0155 return false; 0156 } 0157 if (destinationChild + row < 0 || destinationChild + row >= m_commentList.size()) { 0158 return false; 0159 } 0160 m_commentList.move(sourceRow, destinationChild + row); 0161 } 0162 endMoveRows(); 0163 emit sigCommentListChanged(); 0164 return true; 0165 } 0166 0167 QStringList StoryboardCommentModel::mimeTypes() const 0168 { 0169 QStringList types; 0170 types << QLatin1String("application/x-krita-storyboard"); 0171 return types; 0172 } 0173 0174 QMimeData *StoryboardCommentModel::mimeData(const QModelIndexList &indexes) const 0175 { 0176 QMimeData *mimeData = new QMimeData(); 0177 QByteArray encodeData; 0178 0179 QDataStream stream(&encodeData, QIODevice::WriteOnly); 0180 0181 //take the row number of the index where drag started 0182 foreach (QModelIndex index, indexes) { 0183 if (index.isValid()) { 0184 int row = index.row(); 0185 stream << row; 0186 } 0187 } 0188 0189 mimeData->setData("application/x-krita-storyboard", encodeData); //default mimetype 0190 return mimeData; 0191 } 0192 0193 bool StoryboardCommentModel::dropMimeData(const QMimeData *data, Qt::DropAction action, 0194 int row, int /*column*/, const QModelIndex &parent) 0195 { 0196 if (action == Qt::IgnoreAction) { 0197 return false; 0198 } 0199 if (action == Qt::MoveAction && data->hasFormat("application/x-krita-storyboard")) { 0200 QByteArray bytes = data->data("application/x-krita-storyboard"); 0201 QDataStream stream(&bytes, QIODevice::ReadOnly); 0202 0203 if (parent.isValid()) { 0204 return false; 0205 } 0206 int sourceRow; 0207 QModelIndexList moveRowIndexes; 0208 while (!stream.atEnd()) { 0209 stream >> sourceRow; 0210 QModelIndex index = createIndex(sourceRow, 0); 0211 moveRowIndexes.append(index); 0212 } 0213 moveRows(QModelIndex(), moveRowIndexes.at(0).row(), moveRowIndexes.count(), parent, row); 0214 0215 //returning true deletes the source row 0216 return false; 0217 } 0218 return false; 0219 } 0220 0221 Qt::DropActions StoryboardCommentModel::supportedDropActions() const 0222 { 0223 return Qt::CopyAction | Qt::MoveAction; 0224 } 0225 0226 Qt::DropActions StoryboardCommentModel::supportedDragActions() const 0227 { 0228 return Qt::CopyAction | Qt::MoveAction; 0229 } 0230 0231 void StoryboardCommentModel::resetData(QVector<StoryboardComment> list) 0232 { 0233 beginResetModel(); 0234 m_commentList = list; 0235 emit dataChanged(QModelIndex(), QModelIndex()); 0236 endResetModel(); 0237 } 0238 0239 QVector<StoryboardComment> StoryboardCommentModel::getData() 0240 { 0241 return m_commentList; 0242 }