File indexing completed on 2024-04-28 16:21:24
0001 /* This file is part of the KDE project 0002 Copyright 2009 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. 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 "MapModel.h" 0021 0022 #include "Map.h" 0023 #include "ModelSupport.h" 0024 #include "Sheet.h" 0025 #include "SheetModel.h" 0026 0027 #include "commands/SheetCommands.h" 0028 0029 #include <KoIcon.h> 0030 0031 using namespace Calligra::Sheets; 0032 0033 class MapModel::Private 0034 { 0035 public: 0036 Map* map; 0037 0038 public: 0039 bool isSheetIndex(const QModelIndex& index, const MapModel* mapModel) const; 0040 }; 0041 0042 bool MapModel::Private::isSheetIndex(const QModelIndex& index, const MapModel* mapModel) const 0043 { 0044 if (!index.parent().isValid()) { 0045 return false; 0046 } 0047 // If it is a cell, the parent's (the sheet's) model has to be this model. 0048 if (index.parent().model() != mapModel || index.parent().internalPointer() != map) { 0049 return false; 0050 } 0051 // If it is a cell, the parent (the sheet) has no parent. 0052 if (index.parent().parent().isValid()) { 0053 return false; 0054 } 0055 // Do not exceed the sheet list. 0056 if (index.parent().row() >= map->count()) { 0057 return false; 0058 } 0059 // The index' (the cell's) model has to match the sheet model. 0060 if (index.model() != map->sheet(index.parent().row())->model()) { 0061 return false; 0062 } 0063 return true; 0064 } 0065 0066 0067 MapModel::MapModel(Map* map) 0068 : QAbstractListModel(map) 0069 , d(new Private) 0070 { 0071 d->map = map; 0072 connect(d->map, SIGNAL(sheetAdded(Sheet*)), 0073 this, SLOT(addSheet(Sheet*))); 0074 connect(d->map, SIGNAL(sheetRemoved(Sheet*)), 0075 this, SLOT(removeSheet(Sheet*))); 0076 } 0077 0078 MapModel::~MapModel() 0079 { 0080 delete d; 0081 } 0082 0083 QVariant MapModel::data(const QModelIndex &index, int role) const 0084 { 0085 if (!index.isValid()) { 0086 return QVariant(); 0087 } 0088 // Propagation to sheet model 0089 if (d->isSheetIndex(index, this)) { 0090 return d->map->sheet(index.parent().row())->model()->data(index, role); 0091 } 0092 if (index.row() >= d->map->count()) { 0093 return QVariant(); 0094 } 0095 // 0096 const Sheet* const sheet = d->map->sheet(index.row()); 0097 switch (role) { 0098 case Qt::DisplayRole: 0099 case Qt::EditRole: 0100 return QVariant(sheet->sheetName()); 0101 case Qt::DecorationRole: 0102 return QVariant(koIcon("x-office-spreadsheet")); 0103 case VisibilityRole: 0104 return QVariant(!sheet->isHidden()); 0105 case ProtectionRole: 0106 return QVariant(sheet->isProtected()); 0107 default: 0108 break; 0109 } 0110 return QVariant(); 0111 } 0112 0113 Qt::ItemFlags MapModel::flags(const QModelIndex &index) const 0114 { 0115 if (!index.isValid()) { 0116 return Qt::NoItemFlags; 0117 } 0118 // Propagation to sheet model 0119 if (d->isSheetIndex(index, this)) { 0120 return d->map->sheet(index.parent().row())->model()->flags(index); 0121 } 0122 if (index.row() >= d->map->count()) { 0123 return Qt::NoItemFlags; 0124 } 0125 0126 Qt::ItemFlags flags = Qt::ItemIsEnabled; 0127 if (!d->map->isProtected()) { 0128 flags |= Qt::ItemIsSelectable; 0129 const Sheet* const sheet = d->map->sheet(index.row()); 0130 if (!sheet->isProtected()) { 0131 flags |= Qt::ItemIsEditable; 0132 } 0133 } 0134 return flags; 0135 } 0136 0137 QVariant MapModel::headerData(int section, Qt::Orientation orientation, int role) const 0138 { 0139 Q_UNUSED(orientation) 0140 if (section == 0 && role == Qt::DisplayRole) { 0141 return QVariant(i18n("Sheet name")); 0142 } 0143 return QVariant(); 0144 } 0145 0146 QModelIndex MapModel::index(int row, int column, const QModelIndex &parent) const 0147 { 0148 QModelIndex index; 0149 if (parent.isValid()) { 0150 // If it is a cell, the parent's (the sheet's) model has to be this model. 0151 if (parent.model() != this || parent.internalPointer() != d->map) { 0152 return QModelIndex(); 0153 } 0154 // If it is a cell, the parent (the sheet) has no parent. 0155 if (parent.parent().isValid()) { 0156 return QModelIndex(); 0157 } 0158 // Do not exceed the sheet list. 0159 if (parent.row() >= d->map->count()) { 0160 return QModelIndex(); 0161 } 0162 Sheet* const sheet = d->map->sheet(index.parent().row()); 0163 index = sheet->model()->index(row, column, parent); 0164 } else { 0165 index = createIndex(row, column, d->map); 0166 } 0167 return index; 0168 } 0169 0170 int MapModel::rowCount(const QModelIndex &parent) const 0171 { 0172 if (parent.isValid()) { 0173 return 0; 0174 } 0175 return d->map->count(); 0176 } 0177 0178 bool MapModel::setData(const QModelIndex &index, const QVariant &value, int role) 0179 { 0180 // Propagation to sheet model 0181 if (d->isSheetIndex(index, this)) { 0182 return d->map->sheet(index.parent().row())->model()->setData(index, value, role); 0183 } 0184 0185 if (index.isValid() && index.row() < d->map->count()) { 0186 Sheet* const sheet(d->map->sheet(index.row())); 0187 switch (role) { 0188 case Qt::EditRole: { 0189 const QString name(value.toString()); 0190 if (!name.isEmpty()) { 0191 KUndo2Command* const command = new RenameSheetCommand(sheet, name); 0192 emit addCommandRequested(command); 0193 emit dataChanged(index, index); 0194 return true; 0195 } 0196 break; 0197 } 0198 case VisibilityRole: 0199 setHidden(sheet, value.toBool()); 0200 break; 0201 case ProtectionRole: 0202 break; 0203 default: 0204 break; 0205 } 0206 } 0207 return false; 0208 } 0209 0210 bool MapModel::setHidden(Sheet* sheet, bool hidden) 0211 { 0212 KUndo2Command* command; 0213 if (hidden && !sheet->isHidden()) { 0214 command = new HideSheetCommand(sheet); 0215 } else if (!hidden && sheet->isHidden()) { 0216 command = new ShowSheetCommand(sheet); 0217 } else { 0218 return false; // nothing to do 0219 } 0220 emit addCommandRequested(command); 0221 return true; 0222 } 0223 0224 Map* MapModel::map() const 0225 { 0226 return d->map; 0227 } 0228 0229 void MapModel::addSheet(Sheet* sheet) 0230 { 0231 debugSheets << "Added sheet:" << sheet->sheetName(); 0232 emit layoutChanged(); 0233 } 0234 0235 void MapModel::removeSheet(Sheet *sheet) 0236 { 0237 debugSheets << "Removed sheet:" << sheet->sheetName(); 0238 emit layoutChanged(); 0239 }