Allow user to open a link in a new tab.

When a user <Ctrl+LeftClick> or <MiddleClick> on a link, `QWebEngineView`
try to open a new window using the `createWindow` method.

By overloading it, we can create our own tab as we want.
This commit is contained in:
Matthieu Gautier 2018-07-18 17:30:06 +02:00
parent 1287c93368
commit 81766be447
10 changed files with 92 additions and 25 deletions

View File

@ -38,7 +38,8 @@ SOURCES += \
kiwixrequestinterceptor.cpp \
kiwixwebview.cpp \
library.cpp \
topwidget.cpp
topwidget.cpp \
ktabwidget.cpp
HEADERS += \
mainwindow.h \
@ -49,6 +50,7 @@ HEADERS += \
kiwixwebview.h \
library.h \
topwidget.h \
ktabwidget.h \
kconstants.h
FORMS += \
@ -60,6 +62,7 @@ isEmpty(PREFIX) {
target.path = $$PREFIX/bin
INSTALLS += target
static {
PKGCONFIG_OPTION = "--static"
}

View File

@ -43,6 +43,7 @@ KiwixApp::KiwixApp(int& argc, char *argv[])
setFont(font);
mainWindow = new MainWindow;
mainWindow->show();
tabWidget = mainWindow->getTabWidget();
errorDialog = new QErrorMessage(mainWindow);
}
@ -60,12 +61,20 @@ KiwixApp *KiwixApp::instance()
void KiwixApp::openZimFile(const QString &zimfile)
{
QString zimId;
try {
auto zimId = library.openBook(zimfile);
mainWindow->displayReader(library.getReader(zimId));
zimId = library.openBook(zimfile);
} catch (const std::exception& e) {
showMessage("Cannot open " + zimfile + ": \n" + e.what());
return;
}
openUrl(QUrl("zim://"+zimId+"/"));
}
void KiwixApp::openUrl(const QUrl &url, bool newTab) {
auto reader = library.getReader(url.host());
Q_ASSERT(reader);
tabWidget->openUrl(reader, url, newTab);
}
void KiwixApp::showMessage(const QString &message)

View File

@ -3,6 +3,7 @@
#include "library.h"
#include "mainwindow.h"
#include "ktabwidget.h"
#include "kiwixschemehandler.h"
#include "kiwixrequestinterceptor.h"
@ -18,16 +19,21 @@ public:
static KiwixApp* instance();
void openZimFile(const QString& zimfile);
void openUrl(const QUrl& url, bool newTab=true);
void showMessage(const QString& message);
KiwixSchemeHandler* getSchemeHandler() { return &schemeHandler; }
KiwixRequestInterceptor* getRequestInterceptor() { return &requestIntercetor; }
Library* getLibrary() { return &library; }
MainWindow* getMainWindow() { return mainWindow; }
KTabWidget* getTabWidget() { return tabWidget; }
void showMessage(const QString& message);
private:
Library library;
MainWindow* mainWindow;
KTabWidget* tabWidget;
QErrorMessage* errorDialog;
KiwixSchemeHandler schemeHandler;

View File

@ -16,11 +16,15 @@ KiwixWebView::KiwixWebView(QWidget *parent)
KiwixWebView::~KiwixWebView()
{}
void KiwixWebView::initFromReader(std::shared_ptr<kiwix::Reader> reader)
QWebEngineView* KiwixWebView::createWindow(QWebEnginePage::WebWindowType type)
{
std::string url("zim://");
url += reader->getId();
url += ".zim/";
page()->setUrl(QUrl(QString::fromStdString(url)));
if ( type==QWebEnginePage::WebBrowserBackgroundTab
|| type==QWebEnginePage::WebBrowserTab )
{
auto tabWidget = KiwixApp::instance()->getTabWidget();
return tabWidget->createNewTab(type==QWebEnginePage::WebBrowserTab);
}
return nullptr;
}
}

View File

@ -12,7 +12,8 @@ public:
KiwixWebView(QWidget *parent = Q_NULLPTR);
virtual ~KiwixWebView();
void initFromReader(std::shared_ptr<kiwix::Reader> reader);
protected:
virtual QWebEngineView* createWindow(QWebEnginePage::WebWindowType type);
};
#endif // KIWIXWEBVIEW_H

27
ktabwidget.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "ktabwidget.h"
KTabWidget::KTabWidget(QWidget *parent) :
QTabWidget(parent)
{
}
KiwixWebView* KTabWidget::createNewTab(bool setCurrent)
{
KiwixWebView* webView = new KiwixWebView();
// Ownership of webview is passed to the tabWidget
addTab(webView, "");
if (setCurrent) {
setCurrentWidget(webView);
}
return webView;
}
void KTabWidget::openUrl(std::shared_ptr<kiwix::Reader> reader, const QUrl& url, bool newTab)
{
KiwixWebView* webView = nullptr;
if (newTab || !currentWidget()) {
webView = createNewTab(true);
}
webView->setUrl(url);
}

18
ktabwidget.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef KTABWIDGET_H
#define KTABWIDGET_H
#include <QTableWidget>
#include <memory>
#include <kiwix/reader.h>
#include "kiwixwebview.h"
class KTabWidget : public QTabWidget
{
public:
KTabWidget(QWidget* parent=nullptr);
KiwixWebView* createNewTab(bool setCurrent);
void openUrl(std::shared_ptr<kiwix::Reader> reader, const QUrl &url, bool newTab);
};
#endif // KTABWIDGET_H

View File

@ -23,16 +23,8 @@ MainWindow::~MainWindow()
delete ui;
}
void MainWindow::displayReader(std::shared_ptr<kiwix::Reader> reader)
KTabWidget* MainWindow::getTabWidget()
{
auto webview = new KiwixWebView();
std::string favicon_content;
std::string favicon_mimetype;
reader->getFavicon(favicon_content, favicon_mimetype);
QPixmap pixmap;
pixmap.loadFromData((const uchar*)favicon_content.data(), favicon_content.size());
auto icon = QIcon(pixmap);
// Ownership of webview is passed to the tabWidget
ui->tabWidget->addTab(webview, icon, QString::fromStdString(reader->getTitle()));
webview->initFromReader(reader);
return ui->tabWidget;
}

View File

@ -3,6 +3,7 @@
#include <QMainWindow>
#include "kiwixwebview.h"
#include "ktabwidget.h"
namespace Ui {
class MainWindow;
@ -16,11 +17,11 @@ public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void displayReader(std::shared_ptr<kiwix::Reader> reader);
KTabWidget* getTabWidget();
private:
Ui::MainWindow *ui;
std::map<std::shared_ptr<kiwix::Reader>, KiwixWebView*> webviews_map;
};
#endif // MAINWINDOW_H

View File

@ -19,7 +19,7 @@
<widget class="QWidget" name="centralWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTabWidget" name="tabWidget">
<widget class="KTabWidget" name="tabWidget">
<property name="tabShape">
<enum>QTabWidget::Rounded</enum>
</property>
@ -50,6 +50,12 @@
<extends>QToolBar</extends>
<header>topwidget.h</header>
</customwidget>
<customwidget>
<class>KTabWidget</class>
<extends>QTabWidget</extends>
<header>ktabwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>