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

View File

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

View File

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

View File

@ -16,11 +16,15 @@ KiwixWebView::KiwixWebView(QWidget *parent)
KiwixWebView::~KiwixWebView() KiwixWebView::~KiwixWebView()
{} {}
QWebEngineView* KiwixWebView::createWindow(QWebEnginePage::WebWindowType type)
void KiwixWebView::initFromReader(std::shared_ptr<kiwix::Reader> reader)
{ {
std::string url("zim://"); if ( type==QWebEnginePage::WebBrowserBackgroundTab
url += reader->getId(); || type==QWebEnginePage::WebBrowserTab )
url += ".zim/"; {
page()->setUrl(QUrl(QString::fromStdString(url))); 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); KiwixWebView(QWidget *parent = Q_NULLPTR);
virtual ~KiwixWebView(); virtual ~KiwixWebView();
void initFromReader(std::shared_ptr<kiwix::Reader> reader); protected:
virtual QWebEngineView* createWindow(QWebEnginePage::WebWindowType type);
}; };
#endif // KIWIXWEBVIEW_H #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; delete ui;
} }
void MainWindow::displayReader(std::shared_ptr<kiwix::Reader> reader) KTabWidget* MainWindow::getTabWidget()
{ {
auto webview = new KiwixWebView(); return ui->tabWidget;
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);
} }

View File

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

View File

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