File indexing completed on 2024-12-22 04:41:07
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program 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 3 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, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "locationcompletermodel.h" 0019 #include "mainapplication.h" 0020 #include "iconprovider.h" 0021 #include "bookmarkitem.h" 0022 #include "bookmarks.h" 0023 #include "qzsettings.h" 0024 #include "browserwindow.h" 0025 #include "tabwidget.h" 0026 #include "sqldatabase.h" 0027 0028 LocationCompleterModel::LocationCompleterModel(QObject* parent) 0029 : QStandardItemModel(parent) 0030 { 0031 } 0032 0033 void LocationCompleterModel::setCompletions(const QList<QStandardItem*> &items) 0034 { 0035 clear(); 0036 addCompletions(items); 0037 } 0038 0039 void LocationCompleterModel::addCompletions(const QList<QStandardItem*> &items) 0040 { 0041 for (QStandardItem *item : items) { 0042 item->setIcon(QPixmap::fromImage(item->data(ImageRole).value<QImage>())); 0043 setTabPosition(item); 0044 if (item->icon().isNull()) { 0045 item->setIcon(IconProvider::emptyWebIcon()); 0046 } 0047 appendRow(QList<QStandardItem*>{item}); 0048 } 0049 } 0050 0051 QList<QStandardItem*> LocationCompleterModel::suggestionItems() const 0052 { 0053 QList<QStandardItem*> items; 0054 for (int i = 0; i < rowCount(); ++i) { 0055 QStandardItem *it = item(i); 0056 if (it->data(SearchSuggestionRole).toBool()) { 0057 items.append(it); 0058 } 0059 } 0060 return items; 0061 } 0062 0063 QSqlQuery LocationCompleterModel::createDomainQuery(const QString &text) 0064 { 0065 if (text.isEmpty() || text == QLatin1String("www.")) { 0066 return QSqlQuery(SqlDatabase::instance()->database()); 0067 } 0068 0069 bool withoutWww = text.startsWith(QLatin1Char('w')) && !text.startsWith(QLatin1String("www.")); 0070 QString query = QSL("SELECT url FROM history WHERE "); 0071 0072 if (withoutWww) { 0073 query.append(QLatin1String("url NOT LIKE ? AND url NOT LIKE ? AND ")); 0074 } 0075 else { 0076 query.append(QLatin1String("url LIKE ? OR url LIKE ? OR ")); 0077 } 0078 0079 query.append(QLatin1String("(url LIKE ? OR url LIKE ?) ORDER BY date DESC LIMIT 1")); 0080 0081 QSqlQuery sqlQuery(SqlDatabase::instance()->database()); 0082 sqlQuery.prepare(query); 0083 0084 if (withoutWww) { 0085 sqlQuery.addBindValue(QSL("http://www.%")); 0086 sqlQuery.addBindValue(QSL("https://www.%")); 0087 sqlQuery.addBindValue(QSL("http://%1%").arg(text)); 0088 sqlQuery.addBindValue(QSL("https://%1%").arg(text)); 0089 } 0090 else { 0091 sqlQuery.addBindValue(QSL("http://%1%").arg(text)); 0092 sqlQuery.addBindValue(QSL("https://%1%").arg(text)); 0093 sqlQuery.addBindValue(QSL("http://www.%1%").arg(text)); 0094 sqlQuery.addBindValue(QSL("https://www.%1%").arg(text)); 0095 } 0096 0097 return sqlQuery; 0098 } 0099 0100 QSqlQuery LocationCompleterModel::createHistoryQuery(const QString &searchString, int limit, bool exactMatch) 0101 { 0102 QStringList searchList; 0103 QString query = QLatin1String("SELECT id, url, title, count FROM history WHERE "); 0104 0105 if (exactMatch) { 0106 query.append(QLatin1String("title LIKE ? OR url LIKE ? ")); 0107 } 0108 else { 0109 searchList = searchString.split(QLatin1Char(' '), Qt::SkipEmptyParts); 0110 const int slSize = searchList.size(); 0111 for (int i = 0; i < slSize; ++i) { 0112 query.append(QLatin1String("(title LIKE ? OR url LIKE ?) ")); 0113 if (i < slSize - 1) { 0114 query.append(QLatin1String("AND ")); 0115 } 0116 } 0117 } 0118 0119 query.append(QLatin1String("ORDER BY date DESC LIMIT ?")); 0120 0121 QSqlQuery sqlQuery(SqlDatabase::instance()->database()); 0122 sqlQuery.prepare(query); 0123 0124 if (exactMatch) { 0125 sqlQuery.addBindValue(QSL("%%1%").arg(searchString)); 0126 sqlQuery.addBindValue(QSL("%%1%").arg(searchString)); 0127 } 0128 else { 0129 for (const QString &str : std::as_const(searchList)) { 0130 sqlQuery.addBindValue(QSL("%%1%").arg(str)); 0131 sqlQuery.addBindValue(QSL("%%1%").arg(str)); 0132 } 0133 } 0134 0135 sqlQuery.addBindValue(limit); 0136 0137 return sqlQuery; 0138 } 0139 0140 void LocationCompleterModel::setTabPosition(QStandardItem* item) const 0141 { 0142 Q_ASSERT(item); 0143 0144 item->setData(-1, TabPositionTabRole); 0145 0146 if (!qzSettings->showSwitchTab || item->data(VisitSearchItemRole).toBool()) { 0147 return; 0148 } 0149 0150 const QUrl url = item->data(UrlRole).toUrl(); 0151 const QList<BrowserWindow*> windows = mApp->windows(); 0152 0153 for (BrowserWindow* window : windows) { 0154 QList<WebTab*> tabs = window->tabWidget()->allTabs(); 0155 for (int i = 0; i < tabs.count(); ++i) { 0156 WebTab* tab = tabs.at(i); 0157 if (tab->url() == url) { 0158 item->setData(QVariant::fromValue<void*>(static_cast<void*>(window)), TabPositionWindowRole); 0159 item->setData(i, TabPositionTabRole); 0160 return; 0161 } 0162 } 0163 } 0164 } 0165 0166 void LocationCompleterModel::refreshTabPositions() const 0167 { 0168 for (int row = 0; row < rowCount(); ++row) { 0169 QStandardItem* itm = item(row); 0170 if (itm) { 0171 setTabPosition(itm); 0172 } 0173 } 0174 }