MainWindow::MainWindow(Browser *instance, QUrl defaultUrl, QWidget *parent) :
QMainWindow(parent),
downloadManager(new DownloadDialog(this)),
blocklistManager(new BlockerDialog(this)),
ui(new Ui::MainWindow),
navigationToolBar(new QToolBar(tr("Navigation"), this)),
tabToolBar(new QToolBar(tr("Tab bar"), this)),
tabBar(new WebViewTabBar(this)),
urlLineEdit(new UrlLineEdit(navigationToolBar)),
progressBar(new LoadingBar(this))
{
browserInstance = instance;
Settings settings;
// Load profile and connect its signals
loadProfile(settings.value("defaults/profile").toString());
ui->setupUi(this);
resize(settings.value("window/width", 800).toInt(), settings.value("window/height", 600).toInt());
// Browser menu
QMenu *browserMenu = new QMenu(qApp->applicationName(), ui->menuBar);
ui->menuBar->addMenu(browserMenu);
browserMenu->addAction(tr("New Window"), this, SLOT(handleNewWindow()), QKeySequence(tr("Ctrl+N")));
browserMenu->addAction(tr("New Tab"), this, SLOT(createNewTab()), QKeySequence(tr("Ctrl+T")));
browserMenu->addSeparator();
browserMenu->addAction(tr("About"), this, SLOT(about()), QKeySequence(tr("F1")));
browserMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt()));
browserMenu->addAction(tr("Quit"), qApp, SLOT(quit()), QKeySequence(tr("Ctrl+Q")));
// Tools menu
QMenu *toolsMenu = new QMenu(tr("Tools"), ui->menuBar);
ui->menuBar->addMenu(toolsMenu);
toolsMenu->addAction(tr("Downloads"), downloadManager, SLOT(show()));
toolsMenu->addAction(tr("Blocker"), blocklistManager, SLOT(show()));
// Profile menu
QMenu *profileMenu = new QMenu(tr("Profile"), ui->menuBar);
ui->menuBar->addMenu(profileMenu);
profileMenu->addAction(tr("View profile"), this, SLOT(execProfileEditor()));
profileMenu->addAction(tr("Load profile"), this, SLOT(loadProfileGUI()));
//profileMenu->addAction(tr("Settings"));
//profileMenu->addAction(tr("Cookies"));
this->addToolBar(Qt::TopToolBarArea, navigationToolBar);
this->addToolBarBreak(Qt::TopToolBarArea);
this->addToolBar(Qt::TopToolBarArea, tabToolBar);
navigationToolBar->addWidget(urlLineEdit);
connect(urlLineEdit, SIGNAL(returnPressed()), this, SLOT(handleUrlChanged()));
tabToolBar->addWidget(tabBar);
connect(tabBar, SIGNAL(currentTabChanged(WebView*)), this, SLOT(handleTabChanged(WebView*)));
ui->statusBar->addPermanentWidget(progressBar);
if(!defaultUrl.isEmpty()) {
createNewTab(defaultUrl);
} else {
createNewTab(settings.value("defaults/url", QUrl("http://duckduckgo.com")).toUrl());
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createNewTab(const QUrl &url)
{
tabBar->addTab(profile, url);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(tabBar->count() > 1) {
int ret = QMessageBox::warning(this, tr("Close window?"), tr("Close multiple tabs?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if(ret == QMessageBox::No) {
event->ignore();
return;
}
}
QMainWindow::closeEvent(event);
}
void MainWindow::about()
{
QMessageBox::about(this, tr("About"), tr("smolbote %1
"
"yet another Qute browser
"
"Copyright (C) 2017 Xian Nox
"
"This program comes with ABSOLUTELY NO WARRANTY. "
"This is free software, and you are welcome to redistribute it under the conditions set by the GNU GPLv3.
")
.arg(qApp->applicationVersion()));
}
void MainWindow::loadProfile(const QString &name)
{
if(profile) {
profile->deleteLater();
}
if(name.isEmpty()) {
qDebug("Creating off-the-record profile");
profileName = tr("Off the record");
profile = new WebEngineProfile(this);
} else {
profileName = name;
qDebug("Using profile: %s", qUtf8Printable(profileName));
profile = new WebEngineProfile(profileName, this);
}
UrlRequestInterceptor *interceptor = new UrlRequestInterceptor(this);
interceptor->setSubscription(blocklistManager->subscription());
profile->setRequestInterceptor(interceptor);
connect(profile, SIGNAL(downloadRequested(QWebEngineDownloadItem*)), downloadManager, SLOT(addDownload(QWebEngineDownloadItem*)));
}
void MainWindow::loadProfileGUI()
{
bool ok;
QString name = QInputDialog::getText(this, tr("Load Profile"), tr("Enter Profile name"), QLineEdit::Normal, QString(""), &ok);
if(ok) {
loadProfile(name);
tabBar->setProfile(profile);
}
}
void MainWindow::handleNewWindow(const QUrl &url)
{
browserInstance->addWindow(new MainWindow(browserInstance, url));
}
void MainWindow::handleTabChanged(WebView *view)
{
// clear the parent of the central widget so it doesn't get deleted
centralWidget()->setParent(0);
// disconnect signals
disconnect(centralWidget());
// set new central widget
setCentralWidget(view);
// connect signals
connect(view, SIGNAL(urlChanged(QUrl)), urlLineEdit, SLOT(setUrl(QUrl)));
connect(view, SIGNAL(titleChanged(QString)), this, SLOT(handleTitleUpdated(QString)));
connect(view, SIGNAL(linkHovered(QString)), ui->statusBar, SLOT(showMessage(QString)));
progressBar->connectWebView(view);
// update UI
urlLineEdit->setUrl(view->url());
this->handleTitleUpdated(view->title());
centralWidget()->setFocus();
}
void MainWindow::handleUrlChanged()
{
tabBar->currentView()->load(urlLineEdit->url());
}
void MainWindow::handleTitleUpdated(const QString &title)
{
// For some reason, the long dash gets garbled if read from the settings
//setWindowTitle(title + settings.value("window/title").toString());
setWindowTitle(title + tr(" — smolbote"));
}
void MainWindow::execProfileEditor()
{
ProfileDialog *dialog = new ProfileDialog(profile, this);
dialog->exec();
}