File indexing completed on 2024-05-19 16:09:31
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2011 Paul Mendez <paulestebanms@gmail.com> 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 "KPrCustomSlideShowsModel.h" 0021 0022 //Calligra headers 0023 #include "KPrCustomSlideShows.h" 0024 #include "KPrDocument.h" 0025 #include "KoPAPageBase.h" 0026 #include "commands/KPrEditCustomSlideShowsCommand.h" 0027 #include "commands/KPrAddCustomSlideShowCommand.h" 0028 #include "commands/KPrDelCustomSlideShowCommand.h" 0029 #include "commands/KPrRenameCustomSlideShowCommand.h" 0030 0031 //KF5 headers 0032 #include <klocalizedstring.h> 0033 0034 //Qt headers 0035 #include <QIcon> 0036 #include <QMimeData> 0037 #include <QApplication> 0038 #include <QMenu> 0039 0040 //Other 0041 #include <algorithm> 0042 0043 KPrCustomSlideShowsModel::KPrCustomSlideShowsModel(KPrDocument *document, QObject *parent) 0044 : QAbstractListModel(parent) 0045 , m_customSlideShows(document->customSlideShows()) 0046 , m_iconSize(QSize(200,200)) 0047 , m_document(document) 0048 { 0049 connect(m_customSlideShows, SIGNAL(updated()), this, SLOT(updateModel())); 0050 } 0051 0052 KPrCustomSlideShowsModel::~KPrCustomSlideShowsModel(){ 0053 } 0054 0055 QVariant KPrCustomSlideShowsModel::data(const QModelIndex &index, int role) const 0056 { 0057 if (!index.isValid() || !m_customSlideShows || m_activeCustomSlideShowName.isEmpty()) { 0058 return QVariant(); 0059 } 0060 Q_ASSERT(index.model() == this); 0061 0062 KoPAPageBase *page = m_customSlideShows->pageByIndex(m_activeCustomSlideShowName, index.row()); 0063 0064 switch (role) { 0065 case Qt::DisplayRole: 0066 { 0067 QString name = i18n("Unknown"); 0068 if (page) { 0069 name = page->name(); 0070 if (name.isEmpty()) { 0071 //Default case 0072 name = i18n("Slide %1", index.row()); 0073 } 0074 } 0075 return name; 0076 } 0077 case Qt::DecorationRole: 0078 { 0079 return QIcon(page->thumbnail(m_iconSize)); 0080 } 0081 default: 0082 return QVariant(); 0083 } 0084 } 0085 0086 int KPrCustomSlideShowsModel::rowCount(const QModelIndex &parent) const 0087 { 0088 if (!m_activeCustomSlideShowName.isEmpty()) { 0089 if (!parent.isValid()) { 0090 return m_customSlideShows->getByName(m_activeCustomSlideShowName).count(); 0091 } 0092 } 0093 0094 return 0; 0095 } 0096 0097 Qt::ItemFlags KPrCustomSlideShowsModel::flags(const QModelIndex &index) const 0098 { 0099 if (m_activeCustomSlideShowName.isEmpty()) { 0100 return 0; 0101 } 0102 0103 Qt::ItemFlags defaultFlags = QAbstractListModel::flags (index); 0104 0105 if (index.isValid()) { 0106 return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; 0107 } 0108 else { 0109 return Qt::ItemIsDropEnabled | defaultFlags; 0110 } 0111 } 0112 0113 QModelIndex KPrCustomSlideShowsModel::index(int row, int column, const QModelIndex &parent) const 0114 { 0115 if (m_activeCustomSlideShowName.isEmpty()) { 0116 return QModelIndex(); 0117 } 0118 0119 // check if parent is root node 0120 if (!parent.isValid()) { 0121 if (row >= 0 && row < rowCount(QModelIndex())) { 0122 return createIndex(row, column, m_customSlideShows->pageByIndex(m_activeCustomSlideShowName, row)); 0123 } 0124 } 0125 return QModelIndex(); 0126 } 0127 0128 QStringList KPrCustomSlideShowsModel::mimeTypes() const 0129 { 0130 return QStringList() << "application/x-calligra-customslideshows"; 0131 } 0132 0133 QMimeData * KPrCustomSlideShowsModel::mimeData(const QModelIndexList &indexes) const 0134 { 0135 // check if there is data to encode 0136 if (! indexes.count()) { 0137 return 0; 0138 } 0139 0140 // check if we support a format 0141 const QStringList types = mimeTypes(); 0142 if (types.isEmpty()) { 0143 return 0; 0144 } 0145 0146 QMimeData *data = new QMimeData(); 0147 QByteArray encoded; 0148 QDataStream stream(&encoded, QIODevice::WriteOnly); 0149 0150 // encode the data & order slides 0151 QModelIndexList::ConstIterator it = indexes.begin(); 0152 0153 QMap<int, KoPAPageBase*> map; 0154 for( ; it != indexes.end(); ++it) { 0155 map.insert(m_customSlideShows->indexByPage(m_activeCustomSlideShowName, (KoPAPageBase*)it->internalPointer()), 0156 (KoPAPageBase*)it->internalPointer()); 0157 } 0158 0159 QList<KoPAPageBase *> slides = map.values(); 0160 0161 foreach (KoPAPageBase *slide, slides) { 0162 stream << QVariant::fromValue(qulonglong((void*)slide)); 0163 } 0164 0165 data->setData(types[0], encoded); 0166 return data; 0167 } 0168 0169 Qt::DropActions KPrCustomSlideShowsModel::supportedDropActions() const 0170 { 0171 return Qt::MoveAction | Qt::CopyAction; 0172 } 0173 0174 bool KPrCustomSlideShowsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 0175 { 0176 if (action == Qt::IgnoreAction) { 0177 return true; 0178 } 0179 0180 if (data->hasFormat("application/x-calligra-sliderssorter") || data->hasFormat("application/x-calligra-customslideshows")) { 0181 0182 if (column > 0) { 0183 return false; 0184 } 0185 0186 QList<KoPAPageBase *> slides; 0187 0188 int beginRow = 0; 0189 0190 if (row != -1) { 0191 beginRow = row; 0192 } 0193 else if (parent.isValid()) { 0194 beginRow = parent.row(); 0195 } 0196 else { 0197 beginRow = rowCount(QModelIndex()); 0198 } 0199 0200 if (data->hasFormat("application/x-calligra-sliderssorter")) { 0201 QByteArray encoded = data->data("application/x-calligra-sliderssorter"); 0202 slides = decodeSlidesList(encoded); 0203 0204 if (slides.empty()) { 0205 return false; 0206 } 0207 0208 //perform action 0209 doCustomSlideShowAction(KPrCustomSlideShowsModel::SlidesAdd, slides, QList<int>(), beginRow); 0210 } 0211 else if (data->hasFormat("application/x-calligra-customslideshows")) { 0212 QByteArray encoded = data->data("application/x-calligra-customslideshows"); 0213 slides = decodeSlidesList(encoded); 0214 0215 if (slides.empty()) { 0216 return false; 0217 } 0218 0219 //perform action 0220 doCustomSlideShowAction(KPrCustomSlideShowsModel::SlidesMove, slides, QList<int>(), beginRow); 0221 } 0222 return true; 0223 } 0224 return false; 0225 } 0226 0227 QList<KoPAPageBase *> KPrCustomSlideShowsModel::decodeSlidesList(const QByteArray &encoded) 0228 { 0229 QList<KoPAPageBase *> slides; 0230 QDataStream stream(encoded); 0231 0232 // decode the data 0233 while(!stream.atEnd()) { 0234 QVariant v; 0235 stream >> v; 0236 slides.append(static_cast<KoPAPageBase*>((void*)v.value<qulonglong>())); 0237 } 0238 return slides; 0239 } 0240 0241 void KPrCustomSlideShowsModel::setCustomSlideShows(KPrCustomSlideShows *customShows) 0242 { 0243 beginResetModel(); 0244 m_customSlideShows = customShows; 0245 m_activeCustomSlideShowName.clear(); 0246 endResetModel(); 0247 } 0248 0249 0250 QString KPrCustomSlideShowsModel::activeCustomSlideShow() const 0251 { 0252 return m_activeCustomSlideShowName; 0253 } 0254 0255 void KPrCustomSlideShowsModel::setActiveSlideShow(const QString &name) 0256 { 0257 if (!m_customSlideShows || (m_activeCustomSlideShowName == name)) { 0258 return; 0259 } 0260 if (m_customSlideShows->names().contains(name)) { 0261 beginResetModel(); 0262 m_activeCustomSlideShowName = name; 0263 endResetModel(); 0264 } 0265 } 0266 0267 void KPrCustomSlideShowsModel::setActiveSlideShow(int index) 0268 { 0269 if (!m_customSlideShows) { 0270 return; 0271 } 0272 QString name = m_customSlideShows->names().value(index); 0273 setActiveSlideShow(name); 0274 } 0275 0276 void KPrCustomSlideShowsModel::setIconSize(const QSize &size) 0277 { 0278 m_iconSize = size; 0279 } 0280 0281 QStringList KPrCustomSlideShowsModel::customShowsNamesList() const 0282 { 0283 if (m_customSlideShows) { 0284 return m_customSlideShows->names(); 0285 } 0286 0287 return QStringList(); 0288 } 0289 0290 void KPrCustomSlideShowsModel::setDocument(KPrDocument *document) 0291 { 0292 m_document = document; 0293 setCustomSlideShows(document->customSlideShows()); 0294 } 0295 0296 void KPrCustomSlideShowsModel::removeSlidesByIndexes(const QModelIndexList &pageIndexes) 0297 { 0298 QList<KoPAPageBase *> slides; 0299 QList<int> indexesList; 0300 0301 foreach (const QModelIndex &index, pageIndexes) { 0302 indexesList.append(index.row()); 0303 } 0304 0305 doCustomSlideShowAction(KPrCustomSlideShowsModel::SlidesDelete, slides, indexesList); 0306 } 0307 0308 void KPrCustomSlideShowsModel::addSlides(const QList<KoPAPageBase *> &pages, const int &row) 0309 { 0310 doCustomSlideShowAction(KPrCustomSlideShowsModel::SlidesAdd, pages, QList<int>(), row); 0311 } 0312 0313 bool KPrCustomSlideShowsModel::doCustomSlideShowAction(const CustomShowActions &action, const QList<KoPAPageBase *> &slides, QList<int> indexes, int beginRow) 0314 { 0315 bool updated = false; 0316 int start = beginRow; 0317 0318 //get the slideshow 0319 if (m_activeCustomSlideShowName.isEmpty()) { 0320 return false; 0321 } 0322 QList<KoPAPageBase*> selectedSlideShow = m_customSlideShows->getByName(m_activeCustomSlideShowName); 0323 0324 if (action == KPrCustomSlideShowsModel::SlidesAdd) { 0325 //insert the slides on the current custom show 0326 int i = beginRow; 0327 foreach(KoPAPageBase *page, slides) { 0328 selectedSlideShow.insert(i, page); 0329 i++; 0330 } 0331 updated = true; 0332 } 0333 else if (action == KPrCustomSlideShowsModel::SlidesMove) { 0334 //move the slides on the current custom show 0335 // slides order within the slides list is important to get the expected behaviour 0336 if (beginRow >= selectedSlideShow.count()) { 0337 beginRow = selectedSlideShow.count(); 0338 } 0339 int i = 0; 0340 foreach(KoPAPageBase *page, slides) 0341 { 0342 int from = selectedSlideShow.indexOf(page); 0343 if (from < beginRow) { 0344 selectedSlideShow.move(from, beginRow - 1); 0345 start--; 0346 } 0347 else { 0348 selectedSlideShow.move(from, beginRow + i); 0349 i++; 0350 } 0351 } 0352 updated = true; 0353 } 0354 else if (action == KPrCustomSlideShowsModel::SlidesDelete) { 0355 //delete de slides on the current custom show 0356 //delete command use indexes because the custom show could have 0357 //more than one copy of the same slide. 0358 std::sort(indexes.begin(), indexes.end()); 0359 int i = 0; 0360 foreach(int row, indexes) { 0361 selectedSlideShow.removeAt(row - i); 0362 i++; 0363 } 0364 updated = true; 0365 } 0366 else { 0367 updated = false; 0368 } 0369 0370 if (updated) { 0371 //update the SlideShow with the resulting list 0372 KPrEditCustomSlideShowsCommand *command = new KPrEditCustomSlideShowsCommand( 0373 m_document, m_activeCustomSlideShowName, selectedSlideShow); 0374 m_document->addCommand(command); 0375 emit selectPages(start, slides.count()); 0376 } 0377 return updated; 0378 } 0379 0380 void KPrCustomSlideShowsModel::addNewCustomShow(const QString &name) 0381 { 0382 KPrAddCustomSlideShowCommand *command = new KPrAddCustomSlideShowCommand(m_document, this, name); 0383 m_document->addCommand(command); 0384 } 0385 0386 void KPrCustomSlideShowsModel::renameCustomShow(const QString &oldName, const QString &newName) 0387 { 0388 KPrRenameCustomSlideShowCommand *command = new KPrRenameCustomSlideShowCommand(m_document, this, oldName, newName); 0389 m_document->addCommand(command); 0390 } 0391 0392 void KPrCustomSlideShowsModel::removeCustomShow(const QString &name) 0393 { 0394 KPrDelCustomSlideShowCommand *command = new KPrDelCustomSlideShowCommand(m_document, this, name); 0395 m_document->addCommand(command); 0396 } 0397 0398 void KPrCustomSlideShowsModel::updateCustomSlideShowsList(const QString &name) 0399 { 0400 m_activeCustomSlideShowName.clear(); 0401 setActiveSlideShow(name); 0402 emit customSlideShowsChanged(); 0403 } 0404 0405 void KPrCustomSlideShowsModel::updateModel() 0406 { 0407 emit layoutAboutToBeChanged(); 0408 emit layoutChanged(); 0409 }