File indexing completed on 2024-05-12 16:23:40
0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im> 0002 // SPDX-FileCopyrightText: 2020 Rinigus <rinigus.git@gmail.com> 0003 // 0004 // SPDX-License-Identifier: GPL-2.0-or-later 0005 0006 #include "bookmarkshistorymodel.h" 0007 #include "browsermanager.h" 0008 0009 #include <QDateTime> 0010 #include <QDebug> 0011 #include <QSqlError> 0012 0013 #include <QCoroFuture> 0014 #include <QCoroTask> 0015 0016 constexpr int QUERY_LIMIT = 1000; 0017 0018 BookmarksHistoryModel::BookmarksHistoryModel(QObject *parent) 0019 : QAbstractListModel(parent) 0020 { 0021 connect(BrowserManager::instance(), &BrowserManager::databaseTableChanged, this, &BookmarksHistoryModel::onDatabaseChanged); 0022 } 0023 0024 QHash<int, QByteArray> BookmarksHistoryModel::roleNames() const { 0025 return { 0026 {Id, "id"}, 0027 {Url, "url"}, 0028 {Title, "title"}, 0029 {Icon, "iconName"}, 0030 {LastVisitedDelta, "lastVisitedDelte"} 0031 }; 0032 } 0033 0034 QVariant BookmarksHistoryModel::data(const QModelIndex &index, int role) const 0035 { 0036 auto &item = m_entries.at(index.row()); 0037 switch (role) { 0038 case Role::Id: 0039 return item.id; 0040 case Role::Title: 0041 return item.title; 0042 case Role::Url: 0043 return item.url; 0044 case Role::Icon: 0045 return item.icon; 0046 case Role::LastVisitedDelta: 0047 return item.lastVisitedDelta; 0048 } 0049 0050 Q_UNREACHABLE(); 0051 } 0052 0053 void BookmarksHistoryModel::setActive(bool a) 0054 { 0055 if (m_active == a) 0056 return; 0057 m_active = a; 0058 if (m_active) 0059 fetchData(); 0060 else 0061 clear(); 0062 0063 Q_EMIT activeChanged(); 0064 } 0065 0066 void BookmarksHistoryModel::setBookmarks(bool b) 0067 { 0068 if (m_bookmarks == b) 0069 return; 0070 m_bookmarks = b; 0071 fetchData(); 0072 Q_EMIT bookmarksChanged(); 0073 } 0074 0075 void BookmarksHistoryModel::setHistory(bool h) 0076 { 0077 if (m_history == h) 0078 return; 0079 m_history = h; 0080 fetchData(); 0081 Q_EMIT historyChanged(); 0082 } 0083 0084 void BookmarksHistoryModel::setFilter(const QString &f) 0085 { 0086 if (m_filter == f) 0087 return; 0088 m_filter = f; 0089 fetchData(); 0090 Q_EMIT filterChanged(); 0091 } 0092 0093 void BookmarksHistoryModel::onDatabaseChanged(const QString &table) 0094 { 0095 if ((table == QLatin1String("bookmarks") && m_bookmarks) || (table == QLatin1String("history") && m_history)) 0096 fetchData(); 0097 } 0098 0099 void BookmarksHistoryModel::fetchData() 0100 { 0101 if (!m_active) 0102 return; 0103 0104 auto future = [history = m_history, bookmarks = m_bookmarks, filter = m_filter]() mutable -> QCoro::Task<std::vector<BookmarksHistoryRecord>> { 0105 auto db = BrowserManager::instance() 0106 ->databaseManager() 0107 ->database(); 0108 0109 const qint64 currentTimeInUnix = QDateTime::currentSecsSinceEpoch(); 0110 0111 if (filter.isEmpty()) { 0112 // No clue why this works 0113 filter = QStringLiteral(""); 0114 } 0115 0116 if (bookmarks && history) { 0117 co_return co_await db->getResults<BookmarksHistoryRecord>( 0118 QStringLiteral("SELECT rowid AS id, url, title, icon, ? - lastVisited AS lastVisitedDelta " 0119 "FROM (SELECT * FROM bookmarks UNION SELECT * FROM history) " 0120 "WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%' " 0121 "LIMIT %1").arg(QUERY_LIMIT), 0122 currentTimeInUnix, filter, filter); 0123 } else if (bookmarks) { 0124 co_return co_await db->getResults<BookmarksHistoryRecord>( 0125 QStringLiteral("SELECT rowid AS id, url, title, icon, ? - lastVisited AS lastVisitedDelta " 0126 "FROM bookmarks " 0127 "WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%'"), 0128 currentTimeInUnix, filter, filter); 0129 } else if (history) { 0130 co_return co_await db->getResults<BookmarksHistoryRecord>( 0131 QStringLiteral("SELECT rowid AS id, url, title, icon, ? - lastVisited AS lastVisitedDelta " 0132 "FROM history " 0133 "WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%'" 0134 "LIMIT %1").arg(QUERY_LIMIT), 0135 currentTimeInUnix, filter, filter); 0136 } 0137 0138 co_return {}; 0139 }(); 0140 0141 QCoro::connect(std::move(future), this, [this](auto result) { 0142 if (m_entries == result) { 0143 return; 0144 } 0145 0146 beginResetModel(); 0147 m_entries = std::move(result); 0148 endResetModel(); 0149 }); 0150 } 0151 0152 void BookmarksHistoryModel::clear() 0153 { 0154 beginResetModel(); 0155 m_entries.clear(); 0156 endResetModel(); 0157 } 0158 0159 #include "moc_bookmarkshistorymodel.cpp"