File indexing completed on 2024-05-05 05:40:34
0001 /*************************************************************************** 0002 * Copyright (C) 2009 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * Rolisteam is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "session/sessionitemmodel.h" 0021 0022 #include <QDebug> 0023 #include <QFileInfo> 0024 #include <QIcon> 0025 #include <QUrl> 0026 0027 ////////////////////////////////////// 0028 /// SessionItemModel 0029 ///////////////////////////////////// 0030 namespace session 0031 { 0032 SessionItemModel::SessionItemModel() : m_rootItem(new SessionItem()) 0033 { 0034 m_header << tr("Name") << tr("Path"); 0035 0036 m_rootItem->setParentNode(nullptr); 0037 } 0038 0039 SessionItemModel::~SessionItemModel()= default; 0040 QModelIndex SessionItemModel::index(int row, int column, const QModelIndex& parent) const 0041 { 0042 if(row < 0) 0043 return QModelIndex(); 0044 0045 SessionItem* parentItem= nullptr; 0046 0047 if(!parent.isValid()) 0048 parentItem= m_rootItem.get(); 0049 else 0050 parentItem= static_cast<SessionItem*>(parent.internalPointer()); 0051 0052 SessionItem* childItem= parentItem->childAt(row); 0053 if(childItem) 0054 return createIndex(row, column, childItem); 0055 else 0056 return QModelIndex(); 0057 } 0058 bool SessionItemModel::setData(const QModelIndex& index, const QVariant& value, int role) 0059 { 0060 if(!index.isValid()) 0061 return false; 0062 0063 if(Qt::EditRole == role) 0064 { 0065 SessionItem* childItem= static_cast<SessionItem*>(index.internalPointer()); 0066 childItem->setName(value.toString()); 0067 return true; 0068 } 0069 return false; 0070 } 0071 Qt::ItemFlags SessionItemModel::flags(const QModelIndex& index) const 0072 { 0073 if(!index.isValid()) 0074 return Qt::NoItemFlags | Qt::ItemIsDropEnabled; 0075 0076 SessionItem* childItem= static_cast<SessionItem*>(index.internalPointer()); 0077 if(!childItem->isLeaf()) 0078 return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; 0079 else 0080 return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; 0081 } 0082 QStringList SessionItemModel::mimeTypes() const 0083 { 0084 QStringList types; 0085 types << "rolisteam/cleverurilist" 0086 << "text/uri-list"; 0087 return types; 0088 } 0089 0090 QMimeData* SessionItemModel::mimeData(const QModelIndexList& indexes) const 0091 { 0092 Q_UNUSED(indexes) 0093 /*CleverUriMimeData* mimeData= new CleverUriMimeData(); 0094 0095 for(const QModelIndex& index : indexes) 0096 { 0097 if((index.isValid()) && (index.column() == 0)) 0098 { 0099 ResourcesNode* item= static_cast<ResourcesNode*>(index.internalPointer()); 0100 mimeData->addResourceNode(item, index); 0101 } 0102 } 0103 return mimeData;*/ 0104 return nullptr; 0105 } 0106 0107 /*void SessionItemModel::updateNode(ResourcesNode* node) 0108 { 0109 QModelIndex nodeIndex; 0110 QModelIndex parent; 0111 QList<ResourcesNode*> path; 0112 if(m_rootItem->seekNode(path, node)) 0113 { 0114 ResourcesNode* parentItem= nullptr; 0115 for(auto& i : path) 0116 { 0117 if(nullptr != parentItem) 0118 { 0119 nodeIndex= index(parentItem->indexOf(i), 0, parent); 0120 parent= nodeIndex; 0121 } 0122 parentItem= i; 0123 } 0124 } 0125 emit dataChanged(nodeIndex, nodeIndex); 0126 }*/ 0127 0128 Qt::DropActions SessionItemModel::supportedDropActions() const 0129 { 0130 return Qt::CopyAction | Qt::MoveAction; 0131 } 0132 bool SessionItemModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, 0133 const QModelIndex& parent) 0134 { 0135 Q_UNUSED(column); 0136 0137 if(action == Qt::IgnoreAction) 0138 return false; 0139 0140 bool added= false; 0141 0142 if(data->hasFormat("rolisteam/cleverurilist")) 0143 { 0144 // const CleverUriMimeData* mediaData= qobject_cast<const CleverUriMimeData*>(data); 0145 0146 // if(nullptr != mediaData) 0147 { 0148 /* QList<ResourcesNode*> mediaList= mediaData->getList().values(); 0149 QList<QModelIndex> indexList= mediaData->getList().keys(); 0150 { 0151 if(action == Qt::MoveAction) 0152 { 0153 added= moveMediaItem(mediaList, parent, row, indexList); 0154 } 0155 }*/ 0156 } 0157 } 0158 else if((data->hasUrls()) && (!added)) 0159 { 0160 QList<QUrl> list= data->urls(); 0161 for(QUrl& url : list) 0162 { 0163 if(url.isLocalFile()) 0164 { 0165 QFileInfo fileInfo(url.toLocalFile()); 0166 if(fileInfo.isFile()) 0167 { 0168 } 0169 // addChildMediaTo(medium,parent); 0170 } 0171 // else if(url.isLocalFile()) 0172 } 0173 } 0174 return added; 0175 } 0176 0177 bool SessionItemModel::moveMediaItem(QList<SessionItem*> items, const QModelIndex& parentToBe, int row, 0178 QList<QModelIndex>& formerPosition) 0179 { 0180 SessionItem* parentItem= static_cast<SessionItem*>(parentToBe.internalPointer()); 0181 0182 if(nullptr == parentItem) 0183 { 0184 parentItem= m_rootItem.get(); 0185 } 0186 int orignRow= row; 0187 0188 QList<int> listRow; 0189 0190 if((!items.isEmpty()) && (!formerPosition.isEmpty())) 0191 { 0192 SessionItem* item= items.at(0); 0193 SessionItem* parent= item->parentNode(); 0194 QModelIndex formerPositionIndex= formerPosition.at(0); 0195 QModelIndex sourceParent= formerPositionIndex.parent(); 0196 QModelIndex destinationParent= parentToBe; 0197 0198 int sourceFirst= parent->indexOf(item); 0199 int sourceLast= parent->indexOf(item) + items.size() - 1; 0200 0201 int destinationRow= orignRow < 0 ? parentItem->childrenCount() : orignRow; 0202 if((sourceParent == destinationParent) 0203 && ((destinationRow == parentItem->childrenCount()) || (destinationRow > sourceFirst))) 0204 { 0205 destinationRow-= items.size() - 1; 0206 } 0207 if((sourceParent == destinationParent) && (sourceFirst == destinationRow)) 0208 { 0209 destinationRow-= items.size(); 0210 return false; 0211 } 0212 0213 if(!beginMoveRows(sourceParent, sourceFirst, sourceLast, destinationParent, destinationRow)) 0214 return false; 0215 } 0216 0217 for(int i= items.size() - 1; i >= 0; --i) 0218 { 0219 while(listRow.contains(row)) 0220 { 0221 ++row; 0222 } 0223 0224 SessionItem* item= items.at(i); 0225 SessionItem* parent= item->parentNode(); 0226 QModelIndex formerPositionIndex= formerPosition.at(i); 0227 0228 if(nullptr != parent) 0229 { 0230 parent->removeChild(item); 0231 if((orignRow == -1 && parentItem == m_rootItem.get())) 0232 { 0233 orignRow= parentItem->childrenCount(); 0234 row= orignRow; 0235 } 0236 else if(formerPositionIndex.row() < orignRow && parentToBe == formerPositionIndex.parent()) 0237 { 0238 orignRow-= 1; 0239 row= orignRow; 0240 } 0241 0242 parentItem->insertChildAt(orignRow, item); // row 0243 //--- 0244 int oldRow= formerPositionIndex.row(); 0245 if(oldRow > orignRow && parentItem == m_rootItem.get() && parent == m_rootItem.get()) 0246 { 0247 oldRow+= items.size() - 1 - i; 0248 } 0249 listRow.append(row); 0250 } 0251 } 0252 0253 endMoveRows(); 0254 return true; 0255 } 0256 QModelIndex SessionItemModel::parent(const QModelIndex& index) const 0257 { 0258 if(!index.isValid()) 0259 return QModelIndex(); 0260 0261 SessionItem* childItem= static_cast<SessionItem*>(index.internalPointer()); 0262 SessionItem* parentItem= childItem->parentNode(); 0263 0264 if(parentItem == m_rootItem.get()) 0265 return QModelIndex(); 0266 0267 SessionItem* grandParent= parentItem->parentNode(); 0268 0269 if(grandParent == nullptr) 0270 return QModelIndex(); 0271 0272 return createIndex(grandParent->indexOf(parentItem), 0, parentItem); 0273 } 0274 int SessionItemModel::rowCount(const QModelIndex& index) const 0275 { 0276 if(index.isValid()) 0277 { 0278 SessionItem* tmp= static_cast<SessionItem*>(index.internalPointer()); 0279 return tmp->childrenCount(); 0280 } 0281 else 0282 { 0283 return m_rootItem->childrenCount(); 0284 } 0285 } 0286 int SessionItemModel::columnCount(const QModelIndex&) const 0287 { 0288 return m_header.size(); 0289 } 0290 QVariant SessionItemModel::data(const QModelIndex& index, int role) const 0291 { 0292 if(!index.isValid()) 0293 return QVariant(); 0294 0295 SessionItem* tmp= static_cast<SessionItem*>(index.internalPointer()); 0296 if(!tmp) 0297 return {}; 0298 0299 auto sessionData= tmp->data(); 0300 0301 QVariant var; 0302 switch(role) 0303 { 0304 case Qt::DisplayRole: 0305 case Qt::EditRole: 0306 var= sessionData->name(); 0307 break; 0308 case Qt::DecorationRole: 0309 if(index.column() == Name) 0310 { 0311 } 0312 break; 0313 case Qt::BackgroundRole: 0314 { 0315 /* if(tmp->type() != ResourcesNode::Cleveruri) 0316 break; 0317 auto const& cleverUri= dynamic_cast<CleverURI*>(tmp); 0318 if(!cleverUri) 0319 break; 0320 if(cleverUri->hasData() || cleverUri->exists() || cleverUri->contentType() == 0321 Core::ContentType::WEBVIEW) break; 0322 0323 var= QColor(Qt::red).lighter();*/ 0324 } 0325 break; 0326 } 0327 return var; 0328 } 0329 0330 void SessionItemModel::addResource(SessionItem* node, const QModelIndex& parent) 0331 { 0332 if(!node) 0333 return; 0334 0335 if(m_rootItem->contains(node->uuid())) 0336 return; 0337 0338 SessionItem* parentItem= nullptr; 0339 auto parentbis= parent; 0340 if(!parent.isValid()) 0341 { 0342 parentItem= m_rootItem.get(); 0343 } 0344 else 0345 { 0346 SessionItem* node= static_cast<SessionItem*>(parent.internalPointer()); 0347 if(node->isLeaf()) 0348 { 0349 node= node->parentNode(); // leaf's parent is not a leaf indeed 0350 parentbis= parentbis.parent(); 0351 } 0352 parentItem= dynamic_cast<SessionItem*>(node); // nullptr when it is not a chapter. 0353 } 0354 0355 if(nullptr == parentItem) 0356 return; 0357 0358 beginInsertRows(parentbis, parentItem->childrenCount(), parentItem->childrenCount()); 0359 parentItem->insertChildAt(parentItem->childrenCount(), node); 0360 endInsertRows(); 0361 } 0362 0363 void SessionItemModel::remove(QModelIndex& index) 0364 { 0365 if(!index.isValid()) 0366 return; 0367 SessionItem* indexItem= static_cast<SessionItem*>(index.internalPointer()); 0368 QModelIndex parent= index.parent(); 0369 SessionItem* parentItem= nullptr; 0370 0371 if(!parent.isValid()) 0372 parentItem= m_rootItem.get(); 0373 else 0374 parentItem= static_cast<SessionItem*>(parent.internalPointer()); 0375 0376 beginRemoveRows(index.parent(), index.row(), index.row()); 0377 parentItem->removeChild(indexItem); 0378 endRemoveRows(); 0379 } 0380 0381 void SessionItemModel::removeNode(SessionItem* node) 0382 { 0383 if(nullptr == node) 0384 return; 0385 0386 auto parent= node->parentNode(); 0387 if(parent == nullptr) 0388 return; 0389 0390 auto idx= createIndex(parent->indexOf(node), 0, node); 0391 remove(idx); 0392 } 0393 0394 void SessionItemModel::removeMedia(const QString& id) 0395 { 0396 auto item= m_rootItem->find(id); 0397 // auto idx= createIndex(item->rowInParent(), 0, item); 0398 0399 removeNode(item); 0400 } 0401 0402 void SessionItemModel::addMedia(const QString& id, const QString& path, Core::ContentType type, const QString& name) 0403 { 0404 auto uri= new SessionItem(); 0405 auto data= uri->data(); 0406 data->setUuid(id); 0407 data->setData(QVariant::fromValue(type)); 0408 data->setName(name); 0409 data->setType(SessionItemType::Media); 0410 addResource(uri, QModelIndex()); 0411 } 0412 0413 void SessionItemModel::clearData() 0414 { 0415 if(!m_rootItem) 0416 return; 0417 0418 m_rootItem->clear(); 0419 } 0420 0421 QVariant SessionItemModel::headerData(int section, Qt::Orientation orientation, int role) const 0422 { 0423 QVariant var; 0424 if(orientation == Qt::Horizontal) 0425 { 0426 switch(role) 0427 { 0428 case Qt::DisplayRole: 0429 var= m_header.at(section); 0430 break; 0431 case Qt::TextAlignmentRole: 0432 var= Qt::AlignHCenter; 0433 break; 0434 default: 0435 break; 0436 } 0437 } 0438 return var; 0439 } 0440 //////////////////////// 0441 //////////////////////// 0442 0443 SessionData::SessionData() {} 0444 0445 void SessionData::setUuid(const QString& uuid) 0446 { 0447 m_uuid= uuid; 0448 } 0449 0450 QString SessionData::uuid() const 0451 { 0452 return m_uuid; 0453 } 0454 0455 void SessionData::setName(const QString& name) 0456 { 0457 m_name= name; 0458 } 0459 0460 QString SessionData::name() const 0461 { 0462 return m_name; 0463 } 0464 0465 void SessionData::setPath(const QString& path) 0466 { 0467 m_path= path; 0468 } 0469 0470 QString SessionData::path() const 0471 { 0472 return m_path; 0473 } 0474 0475 void SessionData::setData(const QVariant& data) 0476 { 0477 m_data= data; 0478 } 0479 0480 QVariant SessionData::data() const 0481 { 0482 return m_data; 0483 } 0484 0485 SessionItemType SessionData::type() const 0486 { 0487 return m_type; 0488 } 0489 0490 void SessionData::setType(SessionItemType type) 0491 { 0492 m_type= type; 0493 } 0494 0495 //////////////////////// 0496 //////////////////////// 0497 0498 SessionItem::SessionItem() : m_data(new SessionData) {} 0499 0500 bool SessionItem::isLeaf() const 0501 { 0502 return (m_data->type() != Chapter); 0503 } 0504 0505 int SessionItem::childrenCount() const 0506 { 0507 return static_cast<int>(m_children.size()); 0508 } 0509 0510 SessionData* SessionItem::data() const 0511 { 0512 return m_data.get(); 0513 } 0514 0515 int SessionItem::indexOf(SessionItem* item) const 0516 { 0517 auto it= std::find_if(std::begin(m_children), std::end(m_children), 0518 [item](const std::unique_ptr<SessionItem>& child) { return item == child.get(); }); 0519 0520 if(it == std::end(m_children)) 0521 return -1; 0522 0523 return std::distance(std::begin(m_children), it); 0524 } 0525 0526 void SessionItem::insertChildAt(int row, SessionItem* item) 0527 { 0528 std::unique_ptr<SessionItem> child(item); 0529 child->setParentNode(this); 0530 m_children.insert(m_children.begin() + row, std::move(child)); 0531 } 0532 0533 SessionItem* SessionItem::childAt(int i) const 0534 { 0535 if(m_children.size() <= i && i < 0) 0536 return nullptr; 0537 0538 auto it= m_children.begin() + i; 0539 return it->get(); 0540 } 0541 0542 void SessionItem::setParentNode(SessionItem* parent) 0543 { 0544 m_parent= parent; 0545 } 0546 0547 SessionItem* SessionItem::parentNode() const 0548 { 0549 return m_parent; 0550 } 0551 0552 void SessionItem::removeChild(SessionItem* item) 0553 { 0554 auto it= std::find_if(std::begin(m_children), std::end(m_children), 0555 [item](const std::unique_ptr<SessionItem>& child) { return item == child.get(); }); 0556 0557 if(it == std::end(m_children)) 0558 return; 0559 0560 m_children.erase(it); 0561 } 0562 0563 void SessionItem::setName(const QString& name) 0564 { 0565 if(m_data) 0566 m_data->setName(name); 0567 } 0568 0569 bool SessionItem::contains(const QString& id) const 0570 { 0571 auto it= std::find_if(std::begin(m_children), std::end(m_children), 0572 [id](const std::unique_ptr<SessionItem>& child) { return id == child->uuid(); }); 0573 0574 return it != m_children.end(); 0575 } 0576 0577 QString SessionItem::uuid() const 0578 { 0579 if(m_data) 0580 return m_data->uuid(); 0581 0582 return {}; 0583 } 0584 0585 void SessionItem::clear() 0586 { 0587 m_children.clear(); 0588 } 0589 0590 SessionItem* SessionItem::find(const QString& id) const 0591 { 0592 auto it= std::find_if(std::begin(m_children), std::end(m_children), 0593 [id](const std::unique_ptr<SessionItem>& child) { return id == child->uuid(); }); 0594 0595 if(it != m_children.end()) 0596 return it->get(); 0597 0598 SessionItem* item= nullptr; 0599 for(auto const& child : m_children) 0600 { 0601 item= child->find(id); 0602 if(item != nullptr) 0603 break; 0604 } 0605 return item; 0606 } 0607 } // namespace session