File indexing completed on 2024-05-05 05:40:26

0001 /***************************************************************************
0002  *   Copyright (C) 2017 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 "data/shortcutmodel.h"
0021 #include <QtDebug>
0022 
0023 ShortCutItem::~ShortCutItem() {}
0024 
0025 ShortCut::ShortCut(const QString& name, const QString& seq) : m_name(name), m_seq(seq) {}
0026 QKeySequence ShortCut::getSequence() const
0027 {
0028     return m_seq;
0029 }
0030 
0031 void ShortCut::setSequence(const QKeySequence& seq)
0032 {
0033     m_seq= seq;
0034 }
0035 
0036 QString ShortCut::getName() const
0037 {
0038     return m_name;
0039 }
0040 
0041 void ShortCut::setName(const QString& name)
0042 {
0043     m_name= name;
0044 }
0045 
0046 //ShortCut::~ShortCut() = default;
0047 
0048 /////////////////////////////////////////
0049 Category::Category(const QString& name) : m_name(name) {}
0050 
0051 Category::Category(Category&& other)
0052     : m_shortcuts(std::move(other.m_shortcuts))
0053 {
0054     m_name = other.m_name;
0055 }
0056 
0057 QString Category::name() const
0058 {
0059     return m_name;
0060 }
0061 
0062 void Category::setName(const QString& name)
0063 {
0064     m_name= name;
0065 }
0066 
0067 ShortCut* Category::getShortCut(int i) const
0068 {
0069     return m_shortcuts[i].get();
0070 }
0071 int Category::size() const
0072 {
0073     return m_shortcuts.size();
0074 }
0075 
0076 bool Category::hasShortCut(ShortCut* cut) const
0077 {
0078     auto cat= std::find_if(m_shortcuts.begin(), m_shortcuts.end(), [cut](const std::unique_ptr<ShortCut>& cato) { return (cato.get() == cut); });
0079     return cat != std::end(m_shortcuts);
0080 }
0081 
0082 int Category::indexOf(ShortCut* cut) const
0083 {
0084     auto cat= std::find_if(m_shortcuts.begin(), m_shortcuts.end(), [cut](const std::unique_ptr<ShortCut>& cato) { return (cato.get() == cut); });
0085 
0086     if(cat == std::end(m_shortcuts))
0087         return -1;
0088     return std::distance(std::begin(m_shortcuts), cat);
0089 }
0090 
0091 void Category::insertShortcut(const QString& name, const QString& key)
0092 {
0093     m_shortcuts.push_back(std::make_unique<ShortCut>(name, key));
0094 }
0095 /////////////////////////////////////////
0096 ShortCutModel::ShortCutModel() {}
0097 
0098 QVariant ShortCutModel::headerData(int section, Qt::Orientation orientation, int role) const
0099 {
0100     if(role == Qt::DisplayRole)
0101     {
0102         if(orientation == Qt::Horizontal)
0103         {
0104             if(section == 0)
0105                 return tr("Action");
0106             else
0107                 return tr("Key");
0108         }
0109     }
0110     return QVariant();
0111 }
0112 
0113 QModelIndex ShortCutModel::index(int r, int c, const QModelIndex& parent) const
0114 {
0115     if(r < 0)
0116         return QModelIndex();
0117 
0118     QModelIndex idx;
0119     if(!parent.isValid())
0120     {
0121         idx = createIndex(r, c, m_root[r].get());
0122     }
0123     else
0124     {
0125         Category* parentItem= static_cast<Category*>(parent.internalPointer());
0126         idx = createIndex(r, c, parentItem->getShortCut(r));
0127     }
0128     return idx;
0129 }
0130 
0131 QModelIndex ShortCutModel::parent(const QModelIndex& index) const
0132 {
0133     if(!index.isValid())
0134         return QModelIndex();
0135 
0136     ShortCutItem* childItem= static_cast<ShortCutItem*>(index.internalPointer());
0137 
0138     if(!childItem->isLeaf())
0139     {
0140         return QModelIndex();
0141     }
0142     else
0143     {
0144         ShortCut* shortCut= dynamic_cast<ShortCut*>(childItem);
0145         if(nullptr != shortCut)
0146         {
0147             auto cat= std::find_if(m_root.begin(), m_root.end(),
0148                                    [shortCut](const std::unique_ptr<Category>& cato) { return cato->hasShortCut(shortCut); });
0149             return createIndex(static_cast<int>(std::distance(m_root.begin(), cat)), 0, (*cat).get());
0150         }
0151     }
0152     return QModelIndex();
0153 }
0154 
0155 void ShortCutModel::addCategory(const QString& category)
0156 {
0157     if(category.isEmpty())
0158         return;
0159 
0160     auto cat= std::find_if(m_root.begin(), m_root.end(), [category](const std::unique_ptr<Category>& cato) { return (cato->name() == category); });
0161     if(cat == m_root.end())
0162     {
0163         beginInsertRows(QModelIndex(), m_root.size(), m_root.size());
0164         m_root.push_back(std::make_unique<Category>(category));
0165         endInsertRows();
0166     }
0167 }
0168 
0169 void ShortCutModel::insertShortCut(const QString& category, const QString& name, const QString& key)
0170 {
0171     auto cat= std::find_if(m_root.begin(), m_root.end(),
0172                            [category](const std::unique_ptr<Category>& cato)
0173                            {
0174                                 return (cato->name() == category);
0175                            });
0176 
0177     if(cat == m_root.end())
0178         return;
0179 
0180     QModelIndex idx= index(std::distance(std::begin(m_root), cat), 0, QModelIndex());
0181 
0182     if(!name.isEmpty())
0183     {
0184         beginInsertRows(idx, (*cat)->size(), (*cat)->size());
0185         (*cat)->insertShortcut(name, key);
0186         endInsertRows();
0187     }
0188 }
0189 
0190 int ShortCutModel::rowCount(const QModelIndex& parent) const
0191 {
0192     if(!parent.isValid())
0193     {
0194         return m_root.size();
0195     }
0196     else
0197     {
0198         ShortCutItem* childItem= static_cast<ShortCutItem*>(parent.internalPointer());
0199         if(childItem->isLeaf())
0200         {
0201             return 0;
0202         }
0203         else if(parent.column() == 0)
0204         {
0205             Category* cat= dynamic_cast<Category*>(childItem);
0206             if(nullptr != cat)
0207             {
0208                 return cat->size();
0209             }
0210         }
0211     }
0212     return 0;
0213 }
0214 
0215 int ShortCutModel::columnCount(const QModelIndex& index) const
0216 {
0217     if(index.isValid())
0218         return 0;
0219 
0220     return 2;
0221 }
0222 
0223 void ShortCutModel::removeCategory(const QString& category, bool isDestoyed)
0224 {
0225     auto it = std::find_if(std::begin(m_root), std::end(m_root),[category](const std::unique_ptr<Category>& cato){
0226         return (cato->name() == category);
0227     });
0228 
0229     if(it == std::end(m_root))
0230         return;
0231 
0232     auto idx = std::distance(std::begin(m_root), it);
0233     beginRemoveRows(QModelIndex(), idx, idx);
0234     if(isDestoyed)
0235         it->release();
0236     m_root.erase(it);
0237     endRemoveRows();
0238 
0239 }
0240 
0241 QVariant ShortCutModel::data(const QModelIndex& index, int role) const
0242 {
0243     if(!index.isValid())
0244         return QVariant();
0245 
0246     if(Qt::DisplayRole == role)
0247     {
0248         ShortCutItem* childItem= static_cast<ShortCutItem*>(index.internalPointer());
0249         if(childItem->isLeaf())
0250         {
0251             ShortCut* shortCut= dynamic_cast<ShortCut*>(childItem);
0252             if(nullptr == shortCut)
0253                 return {};
0254 
0255             if(index.column() == 0)
0256             {
0257                 return shortCut->getName();
0258             }
0259             else
0260             {
0261                 return shortCut->getSequence().toString(QKeySequence::NativeText);
0262             }
0263         }
0264         else
0265         {
0266             Category* cat= dynamic_cast<Category*>(childItem);
0267             if(nullptr != cat && index.column() == 0)
0268             {
0269                 return cat->name();
0270             }
0271         }
0272     }
0273     return QVariant();
0274 }