File indexing completed on 2024-12-22 04:41:14

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2018 Anmol Gautam <tarptaeya@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 "qmltabs.h"
0019 #include "tabwidget.h"
0020 #include "pluginproxy.h"
0021 #include "qml/qmlstaticdata.h"
0022 #include <QQmlEngine>
0023 
0024 QmlTabs::QmlTabs(QObject *parent)
0025     : QObject(parent)
0026 {
0027     const QList<BrowserWindow*> windows = mApp->windows();
0028     for (BrowserWindow *window : windows) {
0029         windowCreated(window);
0030     }
0031 
0032     connect(mApp->plugins(), &PluginProxy::mainWindowCreated, this, &QmlTabs::windowCreated);
0033 }
0034 
0035 bool QmlTabs::setCurrentIndex(const QVariantMap &map)
0036 {
0037     if (!map.contains(QSL("index"))) {
0038         qWarning() << "Unable to set current index:" << "index not defined";
0039         return false;
0040     }
0041 
0042     const int index = map.value(QSL("index")).toInt();
0043 
0044     const auto window = getWindow(map);
0045     if (!window) {
0046         return false;
0047     }
0048     window->tabWidget()->setCurrentIndex(index);
0049     return true;
0050 }
0051 
0052 bool QmlTabs::nextTab(int windowId)
0053 {
0054     const auto window = getWindow(windowId);
0055     if (!window) {
0056         return false;
0057     }
0058     window->tabWidget()->nextTab();
0059     return true;
0060 }
0061 
0062 bool QmlTabs::previousTab(int windowId)
0063 {
0064     const auto window = getWindow(windowId);
0065     if (!window) {
0066         return false;
0067     }
0068     window->tabWidget()->previousTab();
0069     return true;
0070 }
0071 
0072 bool QmlTabs::moveTab(const QVariantMap &map)
0073 {
0074     if (!map.contains(QSL("from"))) {
0075         qWarning() << "Unable to move tab:" << "from not defined";
0076         return false;
0077     }
0078     if (!map.contains(QSL("to"))) {
0079         qWarning() << "Unable to move tab:" << "to not defined";
0080         return false;
0081     }
0082 
0083     const int from = map.value(QSL("from")).toInt();
0084     const int to = map.value(QSL("to")).toInt();
0085 
0086     const auto window = getWindow(map);
0087     if (!window) {
0088         return false;
0089     }
0090     window->tabWidget()->moveTab(from, to);
0091     return true;
0092 }
0093 
0094 bool QmlTabs::pinTab(const QVariantMap &map)
0095 {
0096     if (!map.contains(QSL("index"))) {
0097         qWarning() << "Unable to pin tab:" << "index not defined";
0098         return false;
0099     }
0100 
0101     const int index = map.value(QSL("index")).toInt();
0102 
0103     const auto window = getWindow(map);
0104     if (!window) {
0105         return false;
0106     }
0107 
0108     WebTab *webTab = window->tabWidget()->webTab(index);
0109 
0110     if (webTab->isPinned()) {
0111         return false;
0112     }
0113 
0114     webTab->togglePinned();
0115     return true;
0116 }
0117 
0118 bool QmlTabs::unpinTab(const QVariantMap &map)
0119 {
0120     if (!map.contains(QSL("index"))) {
0121         qWarning() << "Unable to unpin tab:" << "index not defined";
0122         return false;
0123     }
0124 
0125     const int index = map.value(QSL("index")).toInt();
0126 
0127     const auto window = getWindow(map);
0128     if (!window) {
0129         return false;
0130     }
0131 
0132     WebTab *webTab = window->tabWidget()->webTab(index);
0133 
0134     if (!webTab->isPinned()) {
0135         return false;
0136     }
0137 
0138     webTab->togglePinned();
0139     return true;
0140 }
0141 
0142 bool QmlTabs::detachTab(const QVariantMap &map)
0143 {
0144     if (!map.contains(QSL("index"))) {
0145         qWarning() << "Unable to detatch tab:" << "index not defined";
0146         return false;
0147     }
0148 
0149     const int index = map.value(QSL("index")).toInt();
0150 
0151     const auto window = getWindow(map);
0152     if (!window) {
0153         return false;
0154     }
0155     window->tabWidget()->detachTab(index);
0156     return true;
0157 }
0158 
0159 bool QmlTabs::duplicate(const QVariantMap &map)
0160 {
0161     if (!map.contains(QSL("index"))) {
0162         qWarning() << "Unable to duplicate:" << "index not defined";
0163         return false;
0164     }
0165 
0166     const int index = map.value(QSL("index")).toInt();
0167 
0168     const auto window = getWindow(map);
0169     if (!window) {
0170         return false;
0171     }
0172     window->tabWidget()->duplicateTab(index);
0173     return true;
0174 }
0175 
0176 bool QmlTabs::closeTab(const QVariantMap &map)
0177 {
0178     if (!map.contains(QSL("index"))) {
0179         qWarning() << "Unable to close tab:" << "index not defined";
0180         return false;
0181     }
0182 
0183     const int index = map.value(QSL("index")).toInt();
0184 
0185     const auto window = getWindow(map);
0186     if (!window) {
0187         return false;
0188     }
0189     window->tabWidget()->closeTab(index);
0190     return true;
0191 }
0192 
0193 bool QmlTabs::reloadTab(const QVariantMap &map)
0194 {
0195     if (!map.contains(QSL("index"))) {
0196         qWarning() << "Unable to reload tab:" << "index not defined";
0197         return false;
0198     }
0199 
0200     const int index = map.value(QSL("index")).toInt();
0201 
0202     const auto window = getWindow(map);
0203     if (!window) {
0204         return false;
0205     }
0206     window->tabWidget()->reloadTab(index);
0207     return true;
0208 }
0209 
0210 bool QmlTabs::stopTab(const QVariantMap &map)
0211 {
0212     if (!map.contains(QSL("index"))) {
0213         qWarning() << "Unable to close tab:" << "index not defined";
0214         return false;
0215     }
0216 
0217     const int index = map.value(QSL("index")).toInt();
0218 
0219     const auto window = getWindow(map);
0220     if (!window) {
0221         return false;
0222     }
0223     window->tabWidget()->stopTab(index);
0224     return true;
0225 }
0226 
0227 QmlTab *QmlTabs::get(const QVariantMap &map) const
0228 {
0229     if (!map.contains(QSL("index"))) {
0230         qWarning() << "Unable to set current index:" << "index not defined";
0231         return nullptr;
0232     }
0233 
0234     const int index = map.value(QSL("index")).toInt();
0235 
0236     const auto window = getWindow(map);
0237     if (!window) {
0238         return nullptr;
0239     }
0240     const auto webTab = window->tabWidget()->webTab(index);
0241     return QmlStaticData::instance().getTab(webTab);
0242 }
0243 
0244 int QmlTabs::normalTabsCount(int windowId) const
0245 {
0246     const auto window = getWindow(windowId);
0247     if (!window) {
0248         return -1;
0249     }
0250     return window->tabWidget()->normalTabsCount();
0251 }
0252 
0253 int QmlTabs::pinnedTabsCount(int windowId) const
0254 {
0255     const auto window = getWindow(windowId);
0256     if (!window) {
0257         return -1;
0258     }
0259     return window->tabWidget()->pinnedTabsCount();
0260 }
0261 
0262 QList<QObject*> QmlTabs::getAll(const QVariantMap &map) const
0263 {
0264     const auto window = getWindow(map);
0265     if (!window) {
0266         return {};
0267     }
0268 
0269     const bool withPinned = map.value(QSL("withPinned")).toBool();
0270     const QList<WebTab*> tabList = window->tabWidget()->allTabs(withPinned);
0271 
0272     QList<QObject*> list;
0273     list.reserve(tabList.size());
0274     for (WebTab *tab : tabList) {
0275         list.append(QmlStaticData::instance().getTab(tab));
0276     }
0277 
0278     return list;
0279 }
0280 
0281 QList<QObject*> QmlTabs::search(const QVariantMap &map)
0282 {
0283     const QString title = map.value(QSL("title")).toString();
0284     const QString url = map.value(QSL("url")).toString();
0285     const bool withPinned = map.value(QSL("withPinned")).toBool();
0286     QList<QObject*> list;
0287     for (BrowserWindow *window : mApp->windows()) {
0288         for (WebTab *webTab : window->tabWidget()->allTabs(withPinned)) {
0289             if (webTab->title().contains(title, Qt::CaseInsensitive)
0290                     || QString::fromUtf8(webTab->url().toEncoded()).contains(url, Qt::CaseInsensitive)) {
0291                 list.append(QmlStaticData::instance().getTab(webTab));
0292             }
0293         }
0294     }
0295     return list;
0296 }
0297 
0298 bool QmlTabs::addTab(const QVariantMap &map)
0299 {
0300     const QString urlString = map.value(QSL("url")).toString();
0301     const auto window = getWindow(map);
0302     if (!window) {
0303         qDebug() << "Unable to add tab:" << "window not found";
0304         return false;
0305     }
0306     LoadRequest req(QUrl::fromEncoded(urlString.toUtf8()));
0307     const int ret = window->tabWidget()->addView(req);
0308     return ret != -1 ? true : false;
0309 }
0310 
0311 BrowserWindow *QmlTabs::getWindow(const QVariantMap &map) const
0312 {
0313     const int windowId = map.value(QSL("windowId"), -1).toInt();
0314     return getWindow(windowId);
0315 }
0316 
0317 BrowserWindow *QmlTabs::getWindow(int windowId) const
0318 {
0319     if (windowId == -1) {
0320         return mApp->getWindow();
0321     }
0322 
0323     auto windowIdHash = QmlStaticData::instance().windowIdHash();
0324     for (auto it = windowIdHash.cbegin(); it != windowIdHash.cend(); it++) {
0325         BrowserWindow *window = it.key();
0326         if (QmlStaticData::instance().windowIdHash().value(window, -1) == windowId) {
0327             return window;
0328         }
0329     }
0330     qWarning() << "Unable to get window with given windowId";
0331     return nullptr;
0332 }
0333 
0334 void QmlTabs::windowCreated(BrowserWindow *window)
0335 {
0336     const int windowId = QmlStaticData::instance().windowIdHash().value(window, -1);
0337 
0338     connect(window->tabWidget(), &TabWidget::changed, this, [this, windowId]{
0339         Q_EMIT changed(windowId);
0340     });
0341 
0342     connect(window->tabWidget(), &TabWidget::tabInserted, this, [this, windowId](int index){
0343         QVariantMap map;
0344         map.insert(QSL("windowId"), windowId);
0345         map.insert(QSL("index"), index);
0346         Q_EMIT tabInserted(map);
0347     });
0348 
0349     connect(window->tabWidget(), &TabWidget::tabRemoved, this, [this, windowId](int index){
0350         QVariantMap map;
0351         map.insert(QSL("windowId"), windowId);
0352         map.insert(QSL("index"), index);
0353         Q_EMIT tabRemoved(map);
0354     });
0355 
0356     connect(window->tabWidget(), &TabWidget::tabMoved, this, [this, windowId](int from, int to){
0357         QVariantMap map;
0358         map.insert(QSL("windowId"), windowId);
0359         map.insert(QSL("from"), from);
0360         map.insert(QSL("to"), to);
0361         Q_EMIT tabMoved(map);
0362     });
0363 }