Warning, file /office/calligra/braindump/src/DocumentModel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright (c) 2009 Cyrille Berger <cberger@cberger.net> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; 0007 * either version 2, or (at your option) any later version of the License. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public License 0015 * along with this library; see the file COPYING. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "DocumentModel.h" 0021 0022 #include <QMimeData> 0023 0024 #include <KoShapeRenameCommand.h> 0025 0026 #include "RootSection.h" 0027 #include "Section.h" 0028 #include "commands/RenameSectionCommand.h" 0029 #include "commands/InsertSectionCommand.h" 0030 #include "commands/MoveSectionCommand.h" 0031 0032 DocumentModel::DocumentModel(QObject* parent, RootSection* document) : KoDocumentSectionModel(parent), m_document(document) 0033 { 0034 Q_ASSERT(m_document); 0035 } 0036 0037 DocumentModel::~DocumentModel() 0038 { 0039 } 0040 0041 int DocumentModel::rowCount(const QModelIndex &parent) const 0042 { 0043 if(!parent.isValid()) { 0044 return m_document->sections().count(); 0045 } else { 0046 return dataFromIndex(parent)->sections().count(); 0047 } 0048 } 0049 0050 int DocumentModel::columnCount(const QModelIndex &parent) const 0051 { 0052 Q_UNUSED(parent); 0053 return 1; 0054 } 0055 0056 QModelIndex DocumentModel::index(int row, int column, const QModelIndex& parent) const 0057 { 0058 SectionGroup* group; 0059 if(parent.isValid()) { 0060 group = dataFromIndex(parent); 0061 } else { 0062 group = m_document; 0063 } 0064 if(row >= 0 && row < group->sections().count() && column == 0) { 0065 return createIndex(row, column, dataToIndex(group->sections()[row])); 0066 } else { 0067 return QModelIndex(); 0068 } 0069 } 0070 0071 QModelIndex DocumentModel::parent(const QModelIndex& child) const 0072 { 0073 if(child.isValid()) { 0074 Section* childSection = dataFromIndex(child); 0075 SectionGroup* childSectionParent = childSection->sectionParent(); 0076 Q_ASSERT(childSectionParent); 0077 if(childSectionParent->sectionParent()) { 0078 Section* parentAsSection = dynamic_cast<Section*>(childSectionParent); 0079 Q_ASSERT(parentAsSection); 0080 Q_ASSERT(childSectionParent->sectionParent()->sections().contains(parentAsSection)); 0081 return createIndex(childSectionParent->sectionParent()->sections().indexOf(parentAsSection), 0082 0, dataToIndex(parentAsSection)); 0083 } else { 0084 return QModelIndex(); 0085 } 0086 0087 } else { 0088 return QModelIndex(); 0089 } 0090 } 0091 0092 QVariant DocumentModel::data(const QModelIndex &index, int role) const 0093 { 0094 if(index.isValid()) { 0095 Section* section = dataFromIndex(index); 0096 switch(role) { 0097 case Qt::EditRole: 0098 case Qt::DisplayRole: { 0099 return section->name(); 0100 } 0101 case SectionPtr: 0102 return qVariantFromValue(section); 0103 } 0104 } 0105 return QVariant(); 0106 } 0107 0108 bool DocumentModel::setData(const QModelIndex &index, const QVariant &value, int role) 0109 { 0110 if(index.isValid()) { 0111 switch(role) { 0112 case Qt::DisplayRole: 0113 case Qt::EditRole: { 0114 Section* section = dataFromIndex(index); 0115 m_document->addCommand(section, new RenameSectionCommand(this, section, value.toString())); 0116 return true; 0117 } 0118 case ActiveRole: { 0119 Section* section = dataFromIndex(index); 0120 emit(activeSectionChanged(section)); 0121 return true; 0122 } 0123 } 0124 } 0125 return false; 0126 } 0127 0128 Qt::ItemFlags DocumentModel::flags(const QModelIndex &index) const 0129 { 0130 if(index.isValid()) { 0131 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; 0132 return flags; 0133 } else { 0134 return Qt::ItemIsDropEnabled; 0135 } 0136 } 0137 0138 Section* DocumentModel::dataFromIndex(const QModelIndex& index) const 0139 { 0140 Q_ASSERT(index.internalPointer()); 0141 return static_cast<Section*>(index.internalPointer()); 0142 } 0143 0144 void* DocumentModel::dataToIndex(Section* section) const 0145 { 0146 return section; 0147 } 0148 0149 Qt::DropActions DocumentModel::supportedDropActions() const 0150 { 0151 return Qt::MoveAction | Qt::CopyAction; 0152 } 0153 0154 QStringList DocumentModel::mimeTypes() const 0155 { 0156 QStringList types; 0157 types << QLatin1String("application/x-braindumpsectionmodeldatalist"); 0158 return types; 0159 } 0160 0161 QMimeData * DocumentModel::mimeData(const QModelIndexList & indexes) const 0162 { 0163 // check if there is data to encode 0164 if(!indexes.count()) 0165 return 0; 0166 0167 // check if we support a format 0168 QStringList types = mimeTypes(); 0169 if(types.isEmpty()) 0170 return 0; 0171 0172 QMimeData *data = new QMimeData(); 0173 QString format = types[0]; 0174 QByteArray encoded; 0175 QDataStream stream(&encoded, QIODevice::WriteOnly); 0176 0177 // encode the data 0178 QModelIndexList::ConstIterator it = indexes.begin(); 0179 for(; it != indexes.end(); ++it) 0180 stream << qVariantFromValue(qulonglong(it->internalPointer())); 0181 0182 data->setData(format, encoded); 0183 return data; 0184 } 0185 0186 bool DocumentModel::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) 0187 { 0188 Q_UNUSED(column); 0189 0190 // check if the action is supported 0191 if(!data || (action != Qt::MoveAction && action != Qt::CopyAction)) 0192 return false; 0193 // check if the format is supported 0194 QStringList types = mimeTypes(); 0195 Q_ASSERT(!types.isEmpty()); 0196 QString format = types[0]; 0197 if(!data->hasFormat(format)) 0198 return false; 0199 0200 QByteArray encoded = data->data(format); 0201 QDataStream stream(&encoded, QIODevice::ReadOnly); 0202 QList<Section*> shapes; 0203 0204 // decode the data 0205 while(! stream.atEnd()) { 0206 QVariant v; 0207 stream >> v; 0208 shapes.append(static_cast<Section*>((void*)v.value<qulonglong>())); 0209 } 0210 0211 SectionGroup* group; 0212 if(parent.isValid()) { 0213 group = dataFromIndex(parent); 0214 } else { 0215 group = m_document; 0216 0217 } 0218 0219 if(row > group->sections().count()) row = group->sections().count(); 0220 foreach(Section * section, shapes) { 0221 if(action == Qt::CopyAction) { 0222 if(row < 0) { 0223 row = group->sections().count(); 0224 } 0225 m_document->addCommand(section, new InsertSectionCommand(m_document->sectionsIO(), new Section(*section), group, this, row)); 0226 } else { 0227 int idx = group->indexOf(section); 0228 if(0 <= idx && idx < row) { 0229 --row; 0230 } 0231 if(row < 0) { 0232 row = group->sections().count(); 0233 if(group == section->sectionParent()) { 0234 --row; 0235 } 0236 } 0237 m_document->addCommand(section, new MoveSectionCommand(section, group, this, row)); 0238 } 0239 } 0240 return true; 0241 } 0242 0243 void DocumentModel::removeSection(Section* section) 0244 { 0245 SectionGroup* parentGrp = section->sectionParent(); 0246 Q_ASSERT(parentGrp); 0247 0248 QModelIndex parentIndex = parent(index(section)); 0249 int idx = parentGrp->sections().indexOf(section); 0250 beginRemoveRows(parentIndex, idx, idx); 0251 parentGrp->removeSection(section); 0252 endRemoveRows(); 0253 } 0254 0255 void DocumentModel::insertSection(Section* section, SectionGroup* parentGrp, Section* before) 0256 { 0257 Q_ASSERT(before == 0 || parentGrp == before->sectionParent()); 0258 int idx = (before) ? parentGrp->sections().indexOf(before) : parentGrp->sections().count(); 0259 insertSection(section, parentGrp, idx); 0260 } 0261 0262 void DocumentModel::insertSection(Section* section, SectionGroup* parentGrp, int idx) 0263 { 0264 QModelIndex parentIndex = index(parentGrp); 0265 Q_ASSERT(idx >= 0 && idx <= parentGrp->sections().count()); 0266 beginInsertRows(parentIndex, idx, idx); 0267 parentGrp->insertSection(section, idx); 0268 Q_ASSERT(section->sectionParent() == parentGrp); 0269 Q_ASSERT((!(parentIndex.isValid()) && section->sectionParent() == m_document) 0270 || section->sectionParent() == dataFromIndex(parentIndex)); 0271 endInsertRows(); 0272 } 0273 0274 QModelIndex DocumentModel::index(Section* section) 0275 { 0276 SectionGroup* group = section->sectionParent(); 0277 Q_ASSERT(group); 0278 return createIndex(group->sections().indexOf(section), 0, dataToIndex(section)); 0279 } 0280 0281 QModelIndex DocumentModel::index(SectionGroup* section) 0282 { 0283 Section* sec = dynamic_cast<Section*>(section); 0284 if(sec) { 0285 return index(sec); 0286 } else { 0287 return QModelIndex(); 0288 } 0289 } 0290 0291 void DocumentModel::changeSectionName(Section* _section, const QString& _name) 0292 { 0293 _section->setName(_name); 0294 QModelIndex idx = index(_section); 0295 emit(dataChanged(idx, idx)); 0296 }