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 }