MoeNavigator is an attempt to write a web browser that is highly configurable, secure, anonymous and fast.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

617 lines
16 KiB

/*
This file is part of MoeNavigator
Copyright (C) 2012-2020 Moritz Strohm <ncc1988@posteo.de>
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 <http://www.gnu.org/licenses/>.
*/
#include "moenavigatormain.h"
MoeNavigatorMain::MoeNavigatorMain(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MoeNavigatorMain)
{
QApplication::setApplicationName("MoeNavigator");
this->configPath = QDir::homePath()+"/.config/MoeNavigator/";
//read the application settings:
this->settings = new QSettings(
this->configPath + "MoeNavigator.ini",
QSettings::IniFormat
);
ui->setupUi(this);
this->configWindow = new ConfigurationWindow();
this->aboutDialog = new MoeNavigatorAboutDialog();
this->uiHandler = new GUIHandler();
//connect signals:
//from GUI to GUI or engine:
//configuration window:
this->connect(
ui->actionSettings,
SIGNAL(triggered()),
this,
SLOT(ShowConfigWindow())
);
//about dialog:
this->connect(
ui->actionAbout,
SIGNAL(triggered()),
this,
SLOT(ShowAboutDialog())
);
this->connect(
this->aboutDialog,
SIGNAL(URLClicked(QString)),
this,
SLOT(openNewTab(QString))
);
//address bar:
this->connect(
ui->addressBar,
SIGNAL(returnPressed()),
this,
SLOT(LoadNewURL())
);
//address bar buttons:
this->connect(
ui->prevButton,
SIGNAL(clicked()),
this,
SLOT(PreviousURL())
);
this->connect(
ui->nextButton,
SIGNAL(clicked()),
this,
SLOT(NextURL())
);
this->connect(
ui->reloadButton,
SIGNAL(clicked()),
this,
SLOT(ReloadPage())
);
this->connect(
ui->newTabButton,
SIGNAL(clicked()),
this,
SLOT(openNewTab())
);
//menu items:
this->connect(
ui->actionMoeNavigatorEngine,
SIGNAL(toggled(bool)),
this,
SLOT(switchEngine(bool))
);
//page buttons:
this->connect(
ui->torToggleButton,
SIGNAL(toggled(bool)),
this,
SLOT(UpdateTorStatus(bool))
);
this->connect(
ui->imagesToggleButton,
SIGNAL(toggled(bool)),
this,
SLOT(UpdateImageDisplayStatus(bool))
);
this->connect(
ui->scriptToggleButton,
SIGNAL(toggled(bool)),
this,
SLOT(UpdateJavaScriptStatus(bool))
);
this->connect(
ui->cookiesToggleButton,
SIGNAL(toggled(bool)),
this,
SLOT(UpdateCookieStatus(bool))
);
this->connect(
ui->radioButtonDomain,
SIGNAL(toggled(bool)),
this,
SLOT(ToggleDomainSettings(bool))
);
//from engine to GUI (the reverse way):
this->connect(
this->uiHandler,
SIGNAL(URLChanged(QObject*, QUrl)),
this,
SLOT(UpdateURLFields(QObject*, QUrl))
);
this->connect(
this->uiHandler,
SIGNAL(URLChanged(QObject*, QUrl)),
this,
SLOT(UpdatePageButtons())
);
this->connect(
this->uiHandler,
SIGNAL(URLHovered(QString)),
ui->statusbar,
SLOT(showMessage(QString))
);
this->connect(
this->uiHandler,
SIGNAL(LoadStatusChanged(QObject*,GUIHandler::LoadingStatus)),
this,
SLOT(UpdateLoadingStatus(QObject*,GUIHandler::LoadingStatus))
);
this->connect(
this->uiHandler,
SIGNAL(NewTabRequest(QString)),
this,
SLOT(openNewTab(QString))
);
//Set up the tab widget with a new browser tab:
this->tab_widget = new QTabWidget(ui->tabWidgetContainer);
if (!this->tab_widget.isNull()) {
this->tab_widget->setTabsClosable(true);
ui->tabWidgetLayout->addWidget(this->tab_widget);
//Connect tab wiget signals:
this->connect(
this->tab_widget,
SIGNAL(currentChanged(int)),
this,
SLOT(SwitchTab())
);
this->connect(
this->tab_widget,
SIGNAL(tabCloseRequested(int)),
this,
SLOT(CloseTab(int))
);
this->openNewTab();
}
}
void MoeNavigatorMain::openNewTab(QString tab_url)
{
this->openNewTab();
if (tab_url != "") {
this->current_tab->engine->OpenURL(tab_url);
}
}
void MoeNavigatorMain::openNewTab()
{
BrowserTabWidget* new_tab = new BrowserTabWidget(
this->tab_widget,
this->uiHandler
);
this->tab_widget->addTab(
new_tab,
"(empty)"
);
this->current_tab = new_tab;
this->current_tab->show();
}
void MoeNavigatorMain::OpenURL(QString URL)
{
//first we have to check if this is an URL:
//if(URL.contains(QRegExp("\w{1,}\.(\w{1,}\/\w*)*\ ")))
//if(URL.contains(QRegExp("\w{1,}(\.\w{1,}){1,}\/?\w*")))
if(!URL.contains(" "))
{
//no white spaces allowed!
//pattern: if a blank space is between domain.tld and another word word it means this is a search expression
// if domain.tld/ a blank space and a word is given (note the slash) it is an URL without protocol specification
//if this is executed we have a domain name:
if(!URL.contains("://"))
{
//no protocol specified!
//place https:// in front of it
//std::cerr << "DEBUG: URL without protocol prefix: " << URL.toStdString() << std::endl;
URL = "https://"+URL;
//std::cerr << " changed URL to: " << URL.toStdString() << std::endl;
}
}
else
{
//the above regex didn't match the string: we have a search request
this->Search(URL);
}
//std::cerr << "DEBUG: Opening URL " << URL.toStdString() << std::endl;
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->OpenURL(URL);
}
this->current_tab->urlText = URL;
}
void MoeNavigatorMain::Search(QString URL)
{
//TODO: build search engine configuration module!
//it has to include the choice betweeen HTTP GET and POST (startpage.com uses POST)
std::cerr << "DEBUG: searching for \"" << URL.toStdString() << "\"" << std::endl;
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->OpenURL("https://startpage.com/do/search", "cmd=process_search&query="+URL);
}
}
void MoeNavigatorMain::LoadMarkup(std::string markup)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->DrawMarkupString(markup);
}
}
void MoeNavigatorMain::SwitchTab()
{
if (this->tab_widget.isNull()) {
return;
}
//first set the new current tab:
this->current_tab = dynamic_cast<BrowserTabWidget*>(
this->tab_widget->currentWidget()
);
if (current_tab.isNull()) {
//The tab is invalid.
return;
}
//now set the address bar:
ui->addressBar->setText(this->current_tab->urlText);
if (this->current_tab->engine != nullptr) {
//set the window title:
QString newTitle = this->current_tab->engine->GetCurrentTitle();
if(newTitle.length() > 64) {
this->setWindowTitle(newTitle.left(64) + "... - MoeNavigator");
} else {
this->setWindowTitle(newTitle + " - MoeNavigator");
}
//and set the quick settings buttons:
ui->torToggleButton->setChecked(
this->current_tab->engine->GetStatus(
EngineInterface::STATUS_TOR_ENABLED
)
);
ui->imagesToggleButton->setChecked(
this->current_tab->engine->GetStatus(
EngineInterface::STATUS_IMAGES_ENABLED
)
);
ui->scriptToggleButton->setChecked(
this->current_tab->engine->GetStatus(
EngineInterface::STATUS_JAVASCRIPT_ENABLED
)
);
ui->cookiesToggleButton->setChecked(
this->current_tab->engine->GetStatus(
EngineInterface::STATUS_STORAGE_ENABLED
)
);
}
}
void MoeNavigatorMain::CloseTab(int tabId)
{
if (this->tab_widget.isNull()) {
return;
}
QPointer<BrowserTabWidget> closing_tab = qobject_cast<BrowserTabWidget*>(
this->tab_widget->widget(tabId)
);
if (closing_tab.isNull()) {
//no such tab.
return;
}
delete closing_tab;
//Set the current_tab pointer to another tab, if any:
this->current_tab = qobject_cast<BrowserTabWidget*>(
this->tab_widget->currentWidget()
);
if (this->current_tab.isNull()) {
//No tab available: close the browser
this->close();
}
}
void MoeNavigatorMain::UpdateTorStatus(bool enabled)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->SetTorStatus(enabled);
}
}
void MoeNavigatorMain::UpdateImageDisplayStatus(bool enabled)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->SetImageDisplayStatus(enabled);
}
}
void MoeNavigatorMain::UpdateJavaScriptStatus(bool enabled)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->SetScriptEngineStatus(enabled);
}
}
void MoeNavigatorMain::UpdateCookieStatus(bool enabled)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->SetWebsiteStorageStatus(enabled);
}
}
void MoeNavigatorMain::UpdateWebStorageStatus(bool enabled)
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->SetCookieStatus(enabled);
this->current_tab->engine->SetLocalStorageStatus(enabled);
}
}
void MoeNavigatorMain::ToggleDomainSettings(bool enabled)
{
//std::cerr << "Domain specific settings enabled: " << enabled << std::endl;
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->UseDomainSpecificSettings(enabled);
}
this->UpdatePageButtons();
}
MoeNavigatorMain::~MoeNavigatorMain()
{
delete this->tab_widget;
delete ui;
}
void MoeNavigatorMain::LoadNewURL()
{
this->OpenURL(ui->addressBar->text());
}
/*
void MoeNavigatorMain::UpdateTitleFields(QObject* newTitleSender, QString newTitle)
{
//we have to make sure that the title for the main window is only set
//when the title has changed in the current (active) tab:
if(this->current_tab->engine->EngineIsObject(newTitleSender))
{
//std::cerr << "DEBUG: Current tab title change!" << std::endl;
if(newTitle.length() > 64)
{
this->setWindowTitle(newTitle.left(64) + "... - MoeNavigator");
}
else
{
this->setWindowTitle(newTitle + " - MoeNavigator");
}
//also, if it is the current tab we don't have to search all the tabs
//to find out from which tab the sending QObject is from.
//Thus we can set the current tab's title directly:
int currentTabIndex = ui->browserTabs->indexOf(this->current_tab->widget);
if(currentTabIndex > -1)
{
if(newTitle.length() > 48)
{
ui->browserTabs->setTabText(currentTabIndex, newTitle.left(48) + "...");
}
else
{
ui->browserTabs->setTabText(currentTabIndex, newTitle);
}
}
}
else
{
std::cerr << "DEBUG: Other tab title change!" << std::endl;
//the title of an inactive (not the current) tab has changed:
//we have to walk over all tabs and check if the sender is an engine
//inside one of those tabs.
QWidget* foundTabWidget = NULL;
for(size_t i = 0; i < this->tabs.size(); i++)
{
if(this->tabs[i]->engine->EngineIsObject(newTitleSender))
{
foundTabWidget = this->tabs[i]->widget;
}
}
int tabIndex = ui->browserTabs->indexOf(foundTabWidget);
if(tabIndex > -1)
{
ui->browserTabs->setTabText(tabIndex, newTitle);
}
}
}
*/
void MoeNavigatorMain::UpdateURLFields(QObject* sender, QUrl newURL)
{
if (this->current_tab->engine == nullptr) {
return;
}
//check if updated URL is coming from current tab and if so
//then update the address bar text:
if (this->current_tab->engine->EngineIsObject(sender)) {
ui->addressBar->setText(newURL.toString());
}
//set the URL text attribute, no matter from which tab the sender comes from:
/*
for(size_t i = 0; i < this->tabs.size(); i++)
{
if(this->tabs[i]->engine->EngineIsObject(sender))
{
//TODO: add a check: only set the new text if the new URL was set without problems
//this should avoid a blank URL when a page cannot be loaded.
this->tabs[i]->urlText = newURL.toString();
}
}
*/
}
void MoeNavigatorMain::UpdateStatusBar(QString new_url, QString new_title, QString new_content)
{
ui->statusbar->setStatusTip(new_url);
}
void MoeNavigatorMain::UpdateLoadingStatus(
QObject *sender,
GUIHandler::LoadingStatus loadingStatus
)
{
if (this->current_tab->engine == nullptr) {
return;
}
if (this->current_tab->engine->EngineIsObject(sender))
{
QString loadingLabelText = "";
//set the loading label:
if(loadingStatus == GUIHandler::LOAD_STATUS_STARTED)
{
loadingLabelText = "loading...";
}
else if(loadingStatus == GUIHandler::LOAD_STATUS_ERROR)
{
loadingLabelText = "Error loading page!";
}
ui->loadingStatusLabel->setText(loadingLabelText);
}
}
void MoeNavigatorMain::switchEngine(bool use_mne)
{
if (use_mne) {
this->current_tab->setEngine("mne");
} else {
this->current_tab->setEngine("webkit");
}
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->OpenURL(this->current_tab->urlText);
}
}
void MoeNavigatorMain::UpdatePageButtons()
{
if (this->current_tab->engine == nullptr) {
return;
}
if(this->current_tab->engine->SettingsAreDomainSpecific())
{
ui->radioButtonDomain->setChecked(true);
//ui->radioButtonSession->setChecked(false);
}
else
{
ui->radioButtonDomain->setChecked(false);
//ui->radioButtonSession->setChecked(true);
}
ui->torToggleButton->setChecked(
this->current_tab->engine->GetStatus(EngineInterface::STATUS_TOR_ENABLED)
);
ui->imagesToggleButton->setChecked(
this->current_tab->engine->GetStatus(EngineInterface::STATUS_IMAGES_ENABLED)
);
ui->scriptToggleButton->setChecked(
this->current_tab->engine->GetStatus(EngineInterface::STATUS_JAVASCRIPT_ENABLED)
);
ui->cookiesToggleButton->setChecked(
this->current_tab->engine->GetStatus(EngineInterface::STATUS_STORAGE_ENABLED)
);
}
void MoeNavigatorMain::NextURL()
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->NextURL();
}
}
void MoeNavigatorMain::PreviousURL()
{
if (this->current_tab->engine != nullptr) {
this->current_tab->engine->PreviousURL();
}
}
void MoeNavigatorMain::ReloadPage()
{
if (this->current_tab->engine != nullptr) {
QString currentURL = this->current_tab->engine->GetCurrentURL();
this->current_tab->engine->OpenURL(currentURL);
}
}
void MoeNavigatorMain::ShowConfigWindow()
{
this->configWindow->show();
}
void MoeNavigatorMain::ShowAboutDialog()
{
this->aboutDialog->show();
}
void MoeNavigatorMain::UpdateConfiguration()
{
//TODO: check configWindow GUI variables and set the corresponding configuration options
//this->engine->SetConfiguration();
}