/*******************************************************************************
**
** smolbote: yet another qute browser
** Copyright (C) 2017 Xian Nox
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see .
**
******************************************************************************/
#include "browser.h"
#include "mainwindow.h"
#include
#include
#include
#include
#include "interfaces.h"
Browser::Browser(int &argc, char *argv[]) :
SingleApplication(argc, argv)
{
setApplicationName("smolbote");
#ifdef GIT_VERSION
setApplicationVersion(GIT_VERSION);
#else
setApplicationVersion("1.0.0");
#endif
}
Browser::~Browser()
{
qDeleteAll(m_windows);
m_windows.clear();
}
QString Browser::applicationLongVersion() const
{
#ifdef GIT_DESCRIBE
return QString(GIT_DESCRIBE);
#else
return applicationVersion();
#endif
}
void Browser::loadPlugins()
{
// Loading plugins
qDebug(">> Looking for plugins...");
// Look for plugins in "../lib/smolbote/plugins"
QDir dir = QDir::current();
dir.cd("../lib/smolbote/plugins");
// Load all plugins
const QStringList files = dir.entryList(QDir::Files | QDir::Readable);
for(const QString &filename : files) {
qDebug("Loading %s", qUtf8Printable(filename));
QPluginLoader loader(dir.absoluteFilePath(filename));
QObject *plugin = loader.instance();
if(plugin) {
PluginInterface *p = qobject_cast(plugin);
if(p) {
qDebug("Successfully loaded plugin [name = %s]", qUtf8Printable(p->name()));
m_plugin = plugin;
}
} else {
qDebug("Plugin load failed");
}
}
qDebug("<< Plugins end...");
}
void Browser::loadProfiles()
{
qDebug(">> Looking for profiles...");
profile("");
QDir dir(settings()->value("browser.profile.path").toString());
const QStringList profileList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for(const QString &name : profileList) {
qDebug("- Adding profile %s", qUtf8Printable(name));
profile(name);
}
qDebug("<< Profiles end...");
//connect(this, SIGNAL(messageAvailable(QStringList)), this, SLOT(addWindow(QStringList)));
connect(this, &Browser::messageAvailable, this, [&](const QHash params) {
//qDebug("Creating new window for [%s]", qUtf8Printable(params["urls"].toString()));
createWindow(params);
});
}
Browser *Browser::instance()
{
return static_cast(QCoreApplication::instance());
}
Settings *Browser::settings()
{
Q_ASSERT(m_settings);
return m_settings.get();
}
BookmarksWidget *Browser::bookmarks()
{
if(!m_bookmarksManager) {
m_bookmarksManager = QSharedPointer(new BookmarksWidget(settings()->value("bookmarks.path").toString()), &QObject::deleteLater);
}
return m_bookmarksManager.data();
}
DownloadsWidget *Browser::downloads()
{
if(!m_downloadManager) {
m_downloadManager = QSharedPointer(new DownloadsWidget(settings()->value("downloads.path").toString()), &QObject::deleteLater);
}
return m_downloadManager.data();
}
BlockerManager *Browser::blocklists()
{
if(!m_blocklistManager) {
m_blocklistManager = new BlockerManager();
}
return m_blocklistManager;
}
void Browser::loadSettings(const QString &path)
{
QString configLocation, defaultsLocation;
// set custom config path if any
if(!path.isEmpty()) {
configLocation = path;
} else {
// no custom config has been set
// check if config file exists for this user
QString cpath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/poi.conf";
if(QFile::exists(cpath)) {
configLocation = cpath;
}
// else there is no user overrides
}
// set defaults location
// check system-specific locations
#ifdef Q_OS_LINUX
if(QFile::exists("/usr/share/smolbote/poi.conf")) {
defaultsLocation = "/usr/share/smolbote/poi.conf";
} else if(QFile::exists("/usr/local/share/smolbote/poi.conf")) {
defaultsLocation = "/usr/local/share/smolbote/poi.conf";
}
#endif
// if no default config is found, then use the built-in one
if(defaultsLocation.isEmpty()) {
defaultsLocation = ":/poi.toml";
}
m_settings = std::unique_ptr(new Settings(configLocation, defaultsLocation));
#ifdef QT_DEBUG
if(m_settings->isEmpty()) {
// There are no keys in the settings
QMessageBox::information(0,
tr("Configuration is empty"),
tr("The configuration file %1 is empty.
"
"Using default values from %2.").arg(configLocation, defaultsLocation));
}
#endif
}
MainWindow *Browser::activeWindow()
{
if(m_windows.empty()) {
return nullptr;
}
for(auto it = m_windows.cbegin(); it != m_windows.cend(); it++) {
if(it->data()->isActiveWindow()) {
return it->data();
}
}
return m_windows.first().data();
}
MainWindow *Browser::createWindow(const QHash options)
{
Q_ASSERT(options.contains("urls"));
MainWindow *w = new MainWindow();
m_windows.append(QPointer(w));
connect(w, &MainWindow::destroyed, this, [&]() {
clean();
});
QString profileName;
if(options.contains("profile")) {
profileName = options.value("profile").toString();
}
const QStringList urls = options.value("urls").toStringList();
if(urls.isEmpty()) {
w->newTab(profile(profileName)->homepage());
} else {
for(const QString url : urls) {
w->newTab(QUrl::fromUserInput(url));
}
}
w->show();
return w;
}
void Browser::clean()
{
for(int i = m_windows.count() - 1; i >= 0; i--) {
if(m_windows[i].isNull()) {
m_windows.removeAt(i);
#ifdef QT_DEBUG
qDebug("Removed deleted window from window list");
#endif
}
}
}
WebEngineProfile* Browser::profile(const QString name)
{
if(!m_profiles.contains(name)) {
if(name.isEmpty()) {
// Create off-the-record profile
m_profiles.insert(name, new WebEngineProfile(this));
} else {
// Create regular profile
m_profiles.insert(name, new WebEngineProfile(name, this));
}
if(!m_urlRequestInterceptor) {
m_urlRequestInterceptor = new UrlRequestInterceptor(this);
m_urlRequestInterceptor->setSubscription(blocklists());
}
m_profiles[name]->setRequestInterceptor(m_urlRequestInterceptor);
connect(m_profiles[name], SIGNAL(downloadRequested(QWebEngineDownloadItem*)), downloads(), SLOT(addDownload(QWebEngineDownloadItem*)));
}
return m_profiles[name];
}
QStringList Browser::profiles()
{
QStringList l;
const QStringList keys = m_profiles.keys();
for(const QString &key : keys) {
l.append(key);
}
return l;
}
QObject *Browser::plugin(const QString name)
{
return m_plugin;
}