1 /* ============================================================
2 * Falkon - Qt web browser
3 * Copyright (C) 2010-2018 David Rosca <nowrep@gmail.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 * ============================================================ */
18 #include "navigationbar.h"
19 #include "toolbutton.h"
20 #include "browserwindow.h"
21 #include "mainapplication.h"
22 #include "iconprovider.h"
23 #include "websearchbar.h"
24 #include "reloadstopbutton.h"
25 #include "enhancedmenu.h"
26 #include "tabwidget.h"
27 #include "tabbedwebview.h"
28 #include "webpage.h"
29 #include "qzsettings.h"
30 #include "qztools.h"
31 #include "abstractbuttoninterface.h"
32 #include "navigationbartoolbutton.h"
33 #include "navigationbarconfigdialog.h"
34 
35 #include <QTimer>
36 #include <QSplitter>
37 #include <QHBoxLayout>
38 #include <QStackedWidget>
39 #include <QWebEngineHistory>
40 #include <QMouseEvent>
41 #include <QStyleOption>
42 
titleForUrl(QString title,const QUrl & url)43 static QString titleForUrl(QString title, const QUrl &url)
44 {
45     if (title.isEmpty()) {
46         title = url.toString(QUrl::RemoveFragment);
47     }
48     if (title.isEmpty()) {
49         return NavigationBar::tr("Empty Page");
50     }
51     return QzTools::truncatedText(title, 40);
52 }
53 
iconForPage(const QUrl & url,const QIcon & sIcon)54 static QIcon iconForPage(const QUrl &url, const QIcon &sIcon)
55 {
56     QIcon icon;
57     icon.addPixmap(IconProvider::iconForUrl(url).pixmap(16));
58     icon.addPixmap(sIcon.pixmap(16), QIcon::Active);
59     return icon;
60 }
61 
NavigationBar(BrowserWindow * window)62 NavigationBar::NavigationBar(BrowserWindow* window)
63     : QWidget(window)
64     , m_window(window)
65 {
66     setObjectName(QSL("navigationbar"));
67 
68     m_layout = new QHBoxLayout(this);
69     m_layout->setMargin(style()->pixelMetric(QStyle::PM_ToolBarItemMargin, 0, this)
70                           + style()->pixelMetric(QStyle::PM_ToolBarFrameWidth, 0, this));
71     m_layout->setSpacing(style()->pixelMetric(QStyle::PM_ToolBarItemSpacing, 0, this));
72     setLayout(m_layout);
73 
74     m_buttonBack = new ToolButton(this);
75     m_buttonBack->setObjectName("navigation-button-back");
76     m_buttonBack->setToolTip(tr("Back"));
77     m_buttonBack->setToolButtonStyle(Qt::ToolButtonIconOnly);
78     m_buttonBack->setToolbarButtonLook(true);
79     m_buttonBack->setShowMenuOnRightClick(true);
80     m_buttonBack->setAutoRaise(true);
81     m_buttonBack->setEnabled(false);
82     m_buttonBack->setFocusPolicy(Qt::NoFocus);
83 
84     m_buttonForward = new ToolButton(this);
85     m_buttonForward->setObjectName("navigation-button-next");
86     m_buttonForward->setToolTip(tr("Forward"));
87     m_buttonForward->setToolButtonStyle(Qt::ToolButtonIconOnly);
88     m_buttonForward->setToolbarButtonLook(true);
89     m_buttonForward->setShowMenuOnRightClick(true);
90     m_buttonForward->setAutoRaise(true);
91     m_buttonForward->setEnabled(false);
92     m_buttonForward->setFocusPolicy(Qt::NoFocus);
93 
94     QHBoxLayout* backNextLayout = new QHBoxLayout();
95     backNextLayout->setContentsMargins(0, 0, 0, 0);
96     backNextLayout->setSpacing(0);
97     backNextLayout->addWidget(m_buttonBack);
98     backNextLayout->addWidget(m_buttonForward);
99     QWidget *backNextWidget = new QWidget(this);
100     backNextWidget->setLayout(backNextLayout);
101 
102     m_reloadStop = new ReloadStopButton(this);
103 
104     ToolButton *buttonHome = new ToolButton(this);
105     buttonHome->setObjectName("navigation-button-home");
106     buttonHome->setToolTip(tr("Home"));
107     buttonHome->setToolButtonStyle(Qt::ToolButtonIconOnly);
108     buttonHome->setToolbarButtonLook(true);
109     buttonHome->setAutoRaise(true);
110     buttonHome->setFocusPolicy(Qt::NoFocus);
111 
112     ToolButton *buttonAddTab = new ToolButton(this);
113     buttonAddTab->setObjectName("navigation-button-addtab");
114     buttonAddTab->setToolTip(tr("New Tab"));
115     buttonAddTab->setToolButtonStyle(Qt::ToolButtonIconOnly);
116     buttonAddTab->setToolbarButtonLook(true);
117     buttonAddTab->setAutoRaise(true);
118     buttonAddTab->setFocusPolicy(Qt::NoFocus);
119 
120     m_menuBack = new Menu(this);
121     m_menuBack->setCloseOnMiddleClick(true);
122     m_buttonBack->setMenu(m_menuBack);
123     connect(m_buttonBack, &ToolButton::aboutToShowMenu, this, &NavigationBar::aboutToShowHistoryBackMenu);
124 
125     m_menuForward = new Menu(this);
126     m_menuForward->setCloseOnMiddleClick(true);
127     m_buttonForward->setMenu(m_menuForward);
128     connect(m_buttonForward, &ToolButton::aboutToShowMenu, this, &NavigationBar::aboutToShowHistoryNextMenu);
129 
130     ToolButton *buttonTools = new ToolButton(this);
131     buttonTools->setObjectName("navigation-button-tools");
132     buttonTools->setPopupMode(QToolButton::InstantPopup);
133     buttonTools->setToolbarButtonLook(true);
134     buttonTools->setToolTip(tr("Tools"));
135     buttonTools->setAutoRaise(true);
136     buttonTools->setFocusPolicy(Qt::NoFocus);
137     buttonTools->setShowMenuInside(true);
138 
139     m_menuTools = new Menu(this);
140     buttonTools->setMenu(m_menuTools);
141     connect(buttonTools, &ToolButton::aboutToShowMenu, this, &NavigationBar::aboutToShowToolsMenu);
142 
143     m_supMenu = new ToolButton(this);
144     m_supMenu->setObjectName("navigation-button-supermenu");
145     m_supMenu->setPopupMode(QToolButton::InstantPopup);
146     m_supMenu->setToolbarButtonLook(true);
147     m_supMenu->setToolTip(tr("Main Menu"));
148     m_supMenu->setAutoRaise(true);
149     m_supMenu->setFocusPolicy(Qt::NoFocus);
150     m_supMenu->setMenu(m_window->superMenu());
151     m_supMenu->setShowMenuInside(true);
152 
153     m_searchLine = new WebSearchBar(m_window);
154 
155     m_navigationSplitter = new QSplitter(this);
156     m_navigationSplitter->addWidget(m_window->tabWidget()->locationBars());
157     m_navigationSplitter->addWidget(m_searchLine);
158 
159     m_navigationSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
160     m_navigationSplitter->setCollapsible(0, false);
161 
162     m_exitFullscreen = new ToolButton(this);
163     m_exitFullscreen->setObjectName("navigation-button-exitfullscreen");
164     m_exitFullscreen->setToolTip(tr("Exit Fullscreen"));
165     m_exitFullscreen->setToolButtonStyle(Qt::ToolButtonIconOnly);
166     m_exitFullscreen->setToolbarButtonLook(true);
167     m_exitFullscreen->setFocusPolicy(Qt::NoFocus);
168     m_exitFullscreen->setAutoRaise(true);
169     m_exitFullscreen->setVisible(false);
170 
171     setContextMenuPolicy(Qt::CustomContextMenu);
172     connect(this, &QWidget::customContextMenuRequested, this, &NavigationBar::contextMenuRequested);
173 
174     connect(m_buttonBack, &QAbstractButton::clicked, this, &NavigationBar::goBack);
175     connect(m_buttonBack, &ToolButton::middleMouseClicked, this, &NavigationBar::goBackInNewTab);
176     connect(m_buttonBack, &ToolButton::controlClicked, this, &NavigationBar::goBackInNewTab);
177     connect(m_buttonForward, &QAbstractButton::clicked, this, &NavigationBar::goForward);
178     connect(m_buttonForward, &ToolButton::middleMouseClicked, this, &NavigationBar::goForwardInNewTab);
179     connect(m_buttonForward, &ToolButton::controlClicked, this, &NavigationBar::goForwardInNewTab);
180 
181     connect(m_reloadStop, &ReloadStopButton::stopClicked, this, &NavigationBar::stop);
182     connect(m_reloadStop, &ReloadStopButton::reloadClicked, this, &NavigationBar::reload);
183     connect(buttonHome, &QAbstractButton::clicked, m_window, &BrowserWindow::goHome);
184     connect(buttonHome, &ToolButton::middleMouseClicked, m_window, &BrowserWindow::goHomeInNewTab);
185     connect(buttonHome, &ToolButton::controlClicked, m_window, &BrowserWindow::goHomeInNewTab);
186     connect(buttonAddTab, &QAbstractButton::clicked, m_window, &BrowserWindow::addTab);
187     connect(buttonAddTab, &ToolButton::middleMouseClicked, m_window->tabWidget(), &TabWidget::addTabFromClipboard);
188     connect(m_exitFullscreen, &QAbstractButton::clicked, m_window, &BrowserWindow::toggleFullScreen);
189 
190     addWidget(backNextWidget, QSL("button-backforward"), tr("Back and Forward buttons"));
191     addWidget(m_reloadStop, QSL("button-reloadstop"), tr("Reload button"));
192     addWidget(buttonHome, QSL("button-home"), tr("Home button"));
193     addWidget(buttonAddTab, QSL("button-addtab"), tr("Add tab button"));
194     addWidget(m_navigationSplitter, QSL("locationbar"), tr("Address and Search bar"));
195     addWidget(buttonTools, QSL("button-tools"), tr("Tools button"));
196     addWidget(m_exitFullscreen, QSL("button-exitfullscreen"), tr("Exit Fullscreen button"));
197 
198     loadSettings();
199 }
200 
~NavigationBar()201 NavigationBar::~NavigationBar()
202 {
203     setCurrentView(nullptr);
204 }
205 
setSplitterSizes(int locationBar,int websearchBar)206 void NavigationBar::setSplitterSizes(int locationBar, int websearchBar)
207 {
208     QList<int> sizes;
209 
210     if (locationBar == 0) {
211         int splitterWidth = m_navigationSplitter->width();
212         sizes << (int)((double)splitterWidth * .80) << (int)((double)splitterWidth * .20);
213     }
214     else {
215         sizes << locationBar << websearchBar;
216     }
217 
218     m_navigationSplitter->setSizes(sizes);
219 }
220 
setCurrentView(TabbedWebView * view)221 void NavigationBar::setCurrentView(TabbedWebView *view)
222 {
223     for (const WidgetData &data : qAsConst(m_widgets)) {
224         if (data.button) {
225             data.button->setWebView(view);
226         }
227     }
228 
229     if (!view) {
230         return;
231     }
232 
233     auto connectPageActions = [this](QWebEnginePage *page) {
234         auto updateButton = [](ToolButton *button, QAction *action) {
235             button->setEnabled(action->isEnabled());
236         };
237         auto updateBackButton = std::bind(updateButton, m_buttonBack, page->action(QWebEnginePage::Back));
238         auto updateForwardButton = std::bind(updateButton, m_buttonForward, page->action(QWebEnginePage::Forward));
239 
240         updateBackButton();
241         updateForwardButton();
242 
243         disconnect(m_backConnection);
244         disconnect(m_forwardConnection);
245         m_backConnection = connect(page->action(QWebEnginePage::Back), &QAction::changed, this, updateBackButton);
246         m_forwardConnection = connect(page->action(QWebEnginePage::Forward), &QAction::changed, this, updateForwardButton);
247     };
248 
249     connectPageActions(view->page());
250     connect(view, &TabbedWebView::pageChanged, this, connectPageActions);
251 }
252 
showReloadButton()253 void NavigationBar::showReloadButton()
254 {
255     m_reloadStop->showReloadButton();
256 }
257 
showStopButton()258 void NavigationBar::showStopButton()
259 {
260     m_reloadStop->showStopButton();
261 }
262 
enterFullScreen()263 void NavigationBar::enterFullScreen()
264 {
265     if (m_layout->indexOf(m_exitFullscreen) != -1) {
266         m_exitFullscreen->show();
267     }
268 }
269 
leaveFullScreen()270 void NavigationBar::leaveFullScreen()
271 {
272     if (m_layout->indexOf(m_exitFullscreen) != -1) {
273         m_exitFullscreen->hide();
274     }
275 }
276 
setSuperMenuVisible(bool visible)277 void NavigationBar::setSuperMenuVisible(bool visible)
278 {
279     m_supMenu->setVisible(visible);
280 }
281 
layoutMargin() const282 int NavigationBar::layoutMargin() const
283 {
284     return m_layout->margin();
285 }
286 
setLayoutMargin(int margin)287 void NavigationBar::setLayoutMargin(int margin)
288 {
289     m_layout->setMargin(margin);
290 }
291 
layoutSpacing() const292 int NavigationBar::layoutSpacing() const
293 {
294     return m_layout->spacing();
295 }
296 
setLayoutSpacing(int spacing)297 void NavigationBar::setLayoutSpacing(int spacing)
298 {
299     m_layout->setSpacing(spacing);
300 }
301 
addWidget(QWidget * widget,const QString & id,const QString & name)302 void NavigationBar::addWidget(QWidget *widget, const QString &id, const QString &name)
303 {
304     if (!widget || id.isEmpty() || name.isEmpty()) {
305         return;
306     }
307 
308     WidgetData data;
309     data.id = id;
310     data.name = name;
311     data.widget = widget;
312     m_widgets[id] = data;
313 
314     reloadLayout();
315 }
316 
removeWidget(const QString & id)317 void NavigationBar::removeWidget(const QString &id)
318 {
319     if (!m_widgets.contains(id)) {
320         return;
321     }
322 
323     m_widgets.remove(id);
324     reloadLayout();
325 }
326 
addToolButton(AbstractButtonInterface * button)327 void NavigationBar::addToolButton(AbstractButtonInterface *button)
328 {
329     if (!button || !button->isValid()) {
330         return;
331     }
332 
333     NavigationBarToolButton *toolButton = new NavigationBarToolButton(button, this);
334     toolButton->setProperty("button-id", button->id());
335     connect(toolButton, &NavigationBarToolButton::visibilityChangeRequested, this, [=]() {
336         if (m_layout->indexOf(toolButton) != -1) {
337             toolButton->updateVisibility();
338         }
339     });
340 
341     WidgetData data;
342     data.id = button->id();
343     data.name = button->name();
344     data.widget = toolButton;
345     data.button = button;
346     m_widgets[data.id] = data;
347 
348     data.button->setWebView(m_window->weView());
349 
350     reloadLayout();
351 }
352 
removeToolButton(AbstractButtonInterface * button)353 void NavigationBar::removeToolButton(AbstractButtonInterface *button)
354 {
355     if (!button || !m_widgets.contains(button->id())) {
356         return;
357     }
358 
359     delete m_widgets.take(button->id()).widget;
360 }
361 
aboutToShowHistoryBackMenu()362 void NavigationBar::aboutToShowHistoryBackMenu()
363 {
364     if (!m_menuBack || !m_window->weView()) {
365         return;
366     }
367     m_menuBack->clear();
368     QWebEngineHistory* history = m_window->weView()->history();
369 
370     int curindex = history->currentItemIndex();
371     int count = 0;
372 
373     for (int i = curindex - 1; i >= 0; i--) {
374         QWebEngineHistoryItem item = history->itemAt(i);
375         if (item.isValid()) {
376             QString title = titleForUrl(item.title(), item.url());
377 
378             const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowBack));
379             Action* act = new Action(icon, title);
380             act->setData(i);
381             connect(act, &QAction::triggered, this, &NavigationBar::loadHistoryIndex);
382             connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab()));
383             m_menuBack->addAction(act);
384         }
385 
386         count++;
387         if (count == 20) {
388             break;
389         }
390     }
391 
392     m_menuBack->addSeparator();
393     m_menuBack->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear history"), this, &NavigationBar::clearHistory);
394 }
395 
aboutToShowHistoryNextMenu()396 void NavigationBar::aboutToShowHistoryNextMenu()
397 {
398     if (!m_menuForward || !m_window->weView()) {
399         return;
400     }
401     m_menuForward->clear();
402 
403     QWebEngineHistory* history = m_window->weView()->history();
404     int curindex = history->currentItemIndex();
405     int count = 0;
406 
407     for (int i = curindex + 1; i < history->count(); i++) {
408         QWebEngineHistoryItem item = history->itemAt(i);
409         if (item.isValid()) {
410             QString title = titleForUrl(item.title(), item.url());
411 
412             const QIcon icon = iconForPage(item.url(), IconProvider::standardIcon(QStyle::SP_ArrowForward));
413             Action* act = new Action(icon, title);
414             act->setData(i);
415             connect(act, &QAction::triggered, this, &NavigationBar::loadHistoryIndex);
416             connect(act, SIGNAL(ctrlTriggered()), this, SLOT(loadHistoryIndexInNewTab()));
417             m_menuForward->addAction(act);
418         }
419 
420         count++;
421         if (count == 20) {
422             break;
423         }
424     }
425 
426     m_menuForward->addSeparator();
427     m_menuForward->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear history"), this, &NavigationBar::clearHistory);
428 }
429 
aboutToShowToolsMenu()430 void NavigationBar::aboutToShowToolsMenu()
431 {
432     m_menuTools->clear();
433 
434     m_window->createToolbarsMenu(m_menuTools->addMenu(tr("Toolbars")));
435     m_window->createSidebarsMenu(m_menuTools->addMenu(tr("Sidebar")));
436     m_menuTools->addSeparator();
437 
438     for (const WidgetData &data : qAsConst(m_widgets)) {
439         AbstractButtonInterface *button = data.button;
440         if (button && (!button->isVisible() || !m_layoutIds.contains(data.id))) {
441             QString title = button->title();
442             if (!button->badgeText().isEmpty()) {
443                 title.append(QSL(" (%1)").arg(button->badgeText()));
444             }
445             m_menuTools->addAction(button->icon(), title, this, &NavigationBar::toolActionActivated)->setData(data.id);
446         }
447     }
448 
449     m_menuTools->addSeparator();
450     m_menuTools->addAction(IconProvider::settingsIcon(), tr("Configure Toolbar"), this, &NavigationBar::openConfigurationDialog);
451 }
452 
clearHistory()453 void NavigationBar::clearHistory()
454 {
455     QWebEngineHistory* history = m_window->weView()->page()->history();
456     history->clear();
457 }
458 
contextMenuRequested(const QPoint & pos)459 void NavigationBar::contextMenuRequested(const QPoint &pos)
460 {
461     QMenu menu;
462     m_window->createToolbarsMenu(&menu);
463     menu.addSeparator();
464     menu.addAction(IconProvider::settingsIcon(), tr("Configure Toolbar"), this, &NavigationBar::openConfigurationDialog);
465     menu.exec(mapToGlobal(pos));
466 }
467 
openConfigurationDialog()468 void NavigationBar::openConfigurationDialog()
469 {
470     NavigationBarConfigDialog *dialog = new NavigationBarConfigDialog(this);
471     dialog->show();
472 }
473 
toolActionActivated()474 void NavigationBar::toolActionActivated()
475 {
476     QAction *act = qobject_cast<QAction*>(sender());
477     if (!act) {
478         return;
479     }
480     const QString id = act->data().toString();
481     if (!m_widgets.contains(id)) {
482         return;
483     }
484     WidgetData data = m_widgets.value(id);
485     if (!data.button) {
486         return;
487     }
488     ToolButton *buttonTools = qobject_cast<ToolButton*>(m_widgets.value(QSL("button-tools")).widget);
489     if (!buttonTools) {
490         return;
491     }
492 
493     AbstractButtonInterface::ClickController *c = new AbstractButtonInterface::ClickController;
494     c->visualParent = buttonTools;
495     c->popupPosition = [=](const QSize &size) {
496         QPoint pos = buttonTools->mapToGlobal(buttonTools->rect().bottomRight());
497         if (QApplication::isRightToLeft()) {
498             pos.setX(pos.x() - buttonTools->rect().width());
499         } else {
500             pos.setX(pos.x() - size.width());
501         }
502         c->popupOpened = true;
503         return pos;
504     };
505     c->popupClosed = [=]() {
506         buttonTools->setDown(false);
507         delete c;
508     };
509     emit data.button->clicked(c);
510     if (c->popupOpened) {
511         buttonTools->setDown(true);
512     } else {
513         c->popupClosed();
514     }
515 }
516 
loadSettings()517 void NavigationBar::loadSettings()
518 {
519     const QStringList defaultIds = {
520         QSL("button-backforward"),
521         QSL("button-reloadstop"),
522         QSL("button-home"),
523         QSL("locationbar"),
524         QSL("button-downloads"),
525         QSL("adblock-icon"),
526         QSL("button-tools")
527     };
528 
529     Settings settings;
530     settings.beginGroup(QSL("NavigationBar"));
531     m_layoutIds = settings.value(QSL("Layout"), defaultIds).toStringList();
532     m_searchLine->setVisible(settings.value(QSL("ShowSearchBar"), true).toBool());
533     settings.endGroup();
534 
535     m_layoutIds.removeDuplicates();
536     m_layoutIds.removeAll(QString());
537     if (!m_layoutIds.contains(QSL("locationbar"))) {
538         m_layoutIds.append(QSL("locationbar"));
539     }
540 
541     reloadLayout();
542 }
543 
reloadLayout()544 void NavigationBar::reloadLayout()
545 {
546     if (m_widgets.isEmpty()) {
547         return;
548     }
549 
550     setUpdatesEnabled(false);
551 
552     // Clear layout
553     while (m_layout->count() != 0) {
554         QLayoutItem *item = m_layout->takeAt(0);
555         if (!item) {
556             continue;
557         }
558         QWidget *widget = item->widget();
559         if (!widget) {
560             continue;
561         }
562         widget->setParent(nullptr);
563     }
564 
565     // Hide all widgets
566     for (const WidgetData &data : m_widgets) {
567         data.widget->hide();
568     }
569 
570     // Add widgets to layout
571     for (const QString &id : qAsConst(m_layoutIds)) {
572         const WidgetData data = m_widgets.value(id);
573         if (data.widget) {
574             m_layout->addWidget(data.widget);
575             NavigationBarToolButton *button = qobject_cast<NavigationBarToolButton*>(data.widget);
576             if (button) {
577                 button->updateVisibility();
578             } else {
579                 data.widget->show();
580             }
581         }
582     }
583 
584     m_layout->addWidget(m_supMenu);
585 
586     // Make sure search bar is visible
587     if (m_searchLine->isVisible() && m_navigationSplitter->sizes().at(1) == 0) {
588         const int locationBarSize = m_navigationSplitter->sizes().at(0);
589         setSplitterSizes(locationBarSize - 50, 50);
590     }
591 
592     if (m_window->isFullScreen()) {
593         enterFullScreen();
594     } else {
595         leaveFullScreen();
596     }
597 
598     setUpdatesEnabled(true);
599 }
600 
loadHistoryIndex()601 void NavigationBar::loadHistoryIndex()
602 {
603     QWebEngineHistory* history = m_window->weView()->page()->history();
604 
605     if (QAction* action = qobject_cast<QAction*>(sender())) {
606         loadHistoryItem(history->itemAt(action->data().toInt()));
607     }
608 }
609 
loadHistoryIndexInNewTab(int index)610 void NavigationBar::loadHistoryIndexInNewTab(int index)
611 {
612     if (QAction* action = qobject_cast<QAction*>(sender())) {
613         index = action->data().toInt();
614     }
615 
616     if (index == -1) {
617         return;
618     }
619 
620     QWebEngineHistory* history = m_window->weView()->page()->history();
621     loadHistoryItemInNewTab(history->itemAt(index));
622 }
623 
stop()624 void NavigationBar::stop()
625 {
626     m_window->action(QSL("View/Stop"))->trigger();
627 }
628 
reload()629 void NavigationBar::reload()
630 {
631     m_window->action(QSL("View/Reload"))->trigger();
632 }
633 
goBack()634 void NavigationBar::goBack()
635 {
636     auto view = m_window->weView();
637     view->setFocus();
638     view->back();
639 }
640 
goBackInNewTab()641 void NavigationBar::goBackInNewTab()
642 {
643     QWebEngineHistory* history = m_window->weView()->page()->history();
644 
645     if (!history->canGoBack()) {
646         return;
647     }
648 
649     loadHistoryItemInNewTab(history->backItem());
650 }
651 
goForward()652 void NavigationBar::goForward()
653 {
654     auto view = m_window->weView();
655     view->setFocus();
656     view->forward();
657 }
658 
goForwardInNewTab()659 void NavigationBar::goForwardInNewTab()
660 {
661     QWebEngineHistory* history = m_window->weView()->page()->history();
662 
663     if (!history->canGoForward()) {
664         return;
665     }
666 
667     loadHistoryItemInNewTab(history->forwardItem());
668 }
669 
loadHistoryItem(const QWebEngineHistoryItem & item)670 void NavigationBar::loadHistoryItem(const QWebEngineHistoryItem &item)
671 {
672     m_window->weView()->page()->history()->goToItem(item);
673 }
674 
loadHistoryItemInNewTab(const QWebEngineHistoryItem & item)675 void NavigationBar::loadHistoryItemInNewTab(const QWebEngineHistoryItem &item)
676 {
677     TabWidget* tabWidget = m_window->tabWidget();
678     int tabIndex = tabWidget->duplicateTab(tabWidget->currentIndex());
679 
680     QWebEngineHistory* history = m_window->weView(tabIndex)->page()->history();
681     history->goToItem(item);
682 
683     if (qzSettings->newTabPosition == Qz::NT_SelectedTab) {
684         tabWidget->setCurrentIndex(tabIndex);
685     }
686 
687 }
688