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

0001 /***************************************************************************
0002  *  Copyright (C) 2021 by Renaud Guezennec                               *
0003  *   http://www.rolisteam.org/contact                                      *
0004  *                                                                         *
0005  *   This software 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 "model/historymodel.h"
0021 
0022 #include <QSet>
0023 #include <QUuid>
0024 
0025 #include "worker/iohelper.h"
0026 
0027 namespace history
0028 {
0029 auto findLink(const QString& id, const QList<LinkInfo>& links)
0030 {
0031     return std::find_if(std::begin(links), std::end(links), [id](const LinkInfo& info) { return info.id == id; });
0032 }
0033 
0034 HistoryModel::HistoryModel(QObject* parent) : QAbstractTableModel(parent)
0035 {
0036     m_columns << tr("Path") << tr("id") << tr("type") << tr("last access") << tr("bookmarked");
0037 }
0038 
0039 QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const
0040 {
0041     if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
0042     {
0043         return m_columns[section];
0044     }
0045     else
0046         return {};
0047 }
0048 
0049 int HistoryModel::rowCount(const QModelIndex& parent) const
0050 {
0051     // For list models only the root node (an invalid parent) should return the list's size. For all
0052     // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
0053     if(parent.isValid())
0054         return 0;
0055 
0056     // FIXME: Implement me!
0057     return m_links.size();
0058 }
0059 
0060 int HistoryModel::columnCount(const QModelIndex& parent) const
0061 {
0062     if(parent.isValid())
0063         return 0;
0064     return m_columns.size();
0065 }
0066 
0067 QVariant HistoryModel::data(const QModelIndex& index, int role) const
0068 {
0069     QSet<int> allowedRole(
0070         {Qt::DisplayRole, Qt::EditRole, PathRole, NameRole, IdRole, TypeRole, LastAccessRole, BookmarkRole});
0071 
0072     if(!index.isValid() || !allowedRole.contains(role))
0073     {
0074         return QVariant();
0075     }
0076     int wantedData= 0;
0077 
0078     if(role < PathRole)
0079         wantedData= PathRole + index.column();
0080     else
0081         wantedData= role;
0082 
0083     auto const& info= m_links.at(index.row());
0084 
0085     QVariant res;
0086     switch(wantedData)
0087     {
0088     case PathRole:
0089         res= info.url;
0090         break;
0091     case NameRole:
0092         res= info.displayName;
0093         break;
0094     case IdRole:
0095         res= info.id;
0096         break;
0097     case TypeRole:
0098         res= QVariant::fromValue(info.type);
0099         break;
0100     case LastAccessRole:
0101         res= info.lastAccess;
0102         break;
0103     case BookmarkRole:
0104         res= info.bookmarked;
0105         break;
0106     default:
0107         break;
0108     }
0109 
0110     return res;
0111 }
0112 
0113 bool HistoryModel::setData(const QModelIndex& idx, const QVariant& data, int role)
0114 {
0115     int wantedData= 0;
0116     if(role < PathRole)
0117         wantedData= PathRole + idx.column();
0118     else
0119         wantedData= role;
0120 
0121     auto& info= m_links[idx.row()];
0122 
0123     QVector<int> roleVec;
0124     switch(wantedData)
0125     {
0126     case PathRole:
0127         info.url= QUrl::fromUserInput(data.toString());
0128         break;
0129     case NameRole:
0130         info.displayName= data.toString();
0131         break;
0132     case BookmarkRole:
0133         info.bookmarked= data.toBool();
0134         break;
0135     default:
0136         break;
0137     }
0138     emit dataChanged(index(idx.row(), 0), index(idx.row(), columnCount()), roleVec);
0139 
0140     return true;
0141 }
0142 
0143 Qt::ItemFlags HistoryModel::flags(const QModelIndex& index) const
0144 {
0145     if(!index.isValid())
0146         return Qt::NoItemFlags;
0147 
0148     int role= index.column() + PathRole;
0149     QSet<int> editableRole({PathRole, NameRole, BookmarkRole});
0150 
0151     if(editableRole.contains(role))
0152     {
0153         return Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
0154     }
0155     else
0156     {
0157         return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
0158     }
0159 }
0160 
0161 LinkInfo HistoryModel::idToPath(const QString& id) const
0162 {
0163     auto it= findLink(id, m_links);
0164     if(it != std::end(m_links))
0165         return *it;
0166     else
0167         return {};
0168 }
0169 
0170 void HistoryModel::refreshAccess(const QString& id)
0171 {
0172     auto const& itc= findLink(id, m_links);
0173     if(itc != std::end(m_links))
0174     {
0175         auto it= m_links.begin() + (itc - m_links.begin());
0176         it->lastAccess= QDateTime::currentDateTime();
0177         sortModel();
0178     }
0179 }
0180 
0181 void HistoryModel::addLink(const QUrl& path, const QString& displayName, Core::ContentType type)
0182 {
0183     if(path.isEmpty())
0184         return;
0185 
0186     auto it= std::find_if(std::begin(m_links), std::end(m_links),
0187                           [path, type](const LinkInfo& info)
0188                           {
0189                               qDebug() << "info and path:" << info.url << path;
0190                               return info.url == path && info.type == type;
0191                           });
0192 
0193     if(it != std::end(m_links))
0194     {
0195         refreshAccess(it->id);
0196     }
0197     else
0198     {
0199         beginInsertRows(QModelIndex(), 0, 0);
0200         LinkInfo info{QUuid::createUuid().toString(QUuid::WithoutBraces), displayName, path, type};
0201         m_links.prepend(info);
0202         endInsertRows();
0203     }
0204 }
0205 
0206 int HistoryModel::maxCapacity() const
0207 {
0208     return m_maxCapacity;
0209 }
0210 
0211 void HistoryModel::setLinks(const QList<LinkInfo>& links)
0212 {
0213     beginResetModel();
0214     m_links.clear();
0215     m_links << links;
0216     endResetModel();
0217 }
0218 
0219 void HistoryModel::clear()
0220 {
0221     beginResetModel();
0222     m_links.clear();
0223     endResetModel();
0224 }
0225 
0226 void HistoryModel::setMaxCapacity(int max)
0227 {
0228     if(m_maxCapacity == max)
0229         return;
0230     m_maxCapacity= max;
0231     emit maxCapacityChanged();
0232 }
0233 
0234 void HistoryModel::sortModel()
0235 {
0236     beginResetModel();
0237     std::sort(std::begin(m_links), std::end(m_links),
0238               [](const LinkInfo& a, const LinkInfo& b)
0239               {
0240                   if(a.bookmarked != b.bookmarked)
0241                       return a.bookmarked;
0242                   else
0243                   {
0244                       return a.lastAccess < b.lastAccess;
0245                   }
0246               });
0247     endResetModel();
0248 }
0249 const QList<LinkInfo>& HistoryModel::data() const
0250 {
0251     return m_links;
0252 }
0253 } // namespace history