/* Copyright (C) 2012 Sebastian Herbord. All rights reserved. This file is part of Mod Organizer. Mod Organizer 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. Mod Organizer 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 Mod Organizer. If not, see . */ #include "nexusdialog.h" #include "ui_nexusdialog.h" #include "messagedialog.h" #include "report.h" #include "json.h" #include #include #include #include #include #include #include using namespace MOBase; using namespace MOShared; NexusDialog::NexusDialog(NXMAccessManager *accessManager, QWidget *parent) : QDialog(parent), ui(new Ui::NexusDialog), m_ModUrlExp(QString("http://([a-zA-Z0-9]*).nexusmods.com/mods/(\\d+)"), Qt::CaseInsensitive), m_AccessManager(accessManager), m_Tutorial(this, "NexusDialog") { ui->setupUi(this); Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint; Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint; flags = flags & (~helpFlag); setWindowFlags(flags); m_Tabs = this->findChild("browserTabWidget"); m_View = new NexusView(this); initTab(m_View); m_LoadProgress = this->findChild("loadProgress"); connect(m_Tabs, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int))); m_Tutorial.registerControl(); } NexusDialog::~NexusDialog() { delete ui; } void NexusDialog::closeEvent(QCloseEvent *event) { // m_AccessManager->showCookies(); QDialog::closeEvent(event); } void NexusDialog::initTab(NexusView *newView) { newView->page()->setNetworkAccessManager(m_AccessManager); newView->page()->setForwardUnsupportedContent(true); connect(newView, SIGNAL(loadProgress(int)), this, SLOT(progress(int))); connect(newView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString))); connect(newView, SIGNAL(initTab(NexusView*)), this, SLOT(initTab(NexusView*))); connect(newView, SIGNAL(startFind()), this, SLOT(startSearch())); connect(newView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl))); connect(newView, SIGNAL(openUrlInNewTab(QUrl)), this, SLOT(openInNewTab(QUrl))); connect(newView->page(), SIGNAL(downloadRequested(QNetworkRequest)), this, SLOT(downloadRequested(QNetworkRequest))); connect(newView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(unsupportedContent(QNetworkReply*))); connect(m_AccessManager, SIGNAL(requestNXMDownload(QString)), this, SLOT(requestNXMDownload(QString))); ui->backBtn->setEnabled(false); ui->fwdBtn->setEnabled(false); m_Tabs->addTab(newView, tr("new")); m_View->settings()->setAttribute(QWebSettings::PluginsEnabled, true); m_View->settings()->setAttribute(QWebSettings::AutoLoadImages, true); } void NexusDialog::openInNewTab(const QUrl &url) { NexusView *newView = new NexusView(this); initTab(newView); newView->setUrl(url); } NexusView *NexusDialog::getCurrentView() { return qobject_cast(m_Tabs->currentWidget()); } void NexusDialog::urlChanged(const QUrl &url) { NexusView *sendingView = qobject_cast(sender()); NexusView *currentView = getCurrentView(); if ((m_ModUrlExp.indexIn(url.toString()) != -1) && (sendingView == currentView)) { ui->modIDEdit->setText(m_ModUrlExp.cap(2)); } if (currentView != NULL) { ui->backBtn->setEnabled(currentView->history()->canGoBack()); ui->fwdBtn->setEnabled(currentView->history()->canGoForward()); } } void NexusDialog::openUrl(const QString &url) { m_Url = url; if (m_Url.startsWith("www")) { m_Url.prepend("http://"); } } void NexusDialog::login(const QString &username, const QString &password) { m_AccessManager->login(username, password); connect(m_AccessManager, SIGNAL(loginSuccessful(bool)), this, SLOT(loginFinished(bool)), Qt::UniqueConnection); connect(m_AccessManager, SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)), Qt::UniqueConnection); } void NexusDialog::loginFailed(const QString &message) { if (this->isVisible()) { MessageDialog::showMessage(tr("login failed: %1").arg(message), this); } } void NexusDialog::loginFinished(bool necessary) { if (necessary && this->isVisible()) { MessageDialog::showMessage(tr("login successful"), this); } loadNexus(); emit loginSuccessful(necessary); } void NexusDialog::loadNexus() { if (m_View != NULL) { m_View->load(QUrl(m_Url)); } } void NexusDialog::progress(int value) { m_LoadProgress->setValue(value); m_LoadProgress->setVisible(value != 100); } void NexusDialog::titleChanged(const QString &title) { NexusView *view = qobject_cast(sender()); for (int i = 0; i < m_Tabs->count(); ++i) { if (m_Tabs->widget(i) == view) { m_Tabs->setTabText(i, title.mid(0, 15)); m_Tabs->setTabToolTip(i, title); } } } QString NexusDialog::guessFileName(const QString &url) { QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$")); if (uploadsExp.indexIn(url) != -1) { // these seem to be premium downloads return uploadsExp.cap(1); } QRegExp filesExp(QString("http://.+\\?file=([^&]+)")); if (filesExp.indexIn(url) != -1) { // a regular manual download? return filesExp.cap(1); } return "unknown"; } void NexusDialog::unsupportedContent(QNetworkReply *reply) { try { QWebPage *page = qobject_cast(sender()); if (page == NULL) { qCritical("sender not a page"); return; } NexusView *view = qobject_cast(page->view()); if (view == NULL) { qCritical("no view?"); return; } int modID = 0; QString fileName = guessFileName(reply->url().toString()); qDebug("unsupported: %s - %s", view->url().toString().toUtf8().constData(), reply->url().toString().toUtf8().constData()); QRegExp sourceExp(QString("http://[a-zA-Z0-9.]*.nexusmods.com/.*"), Qt::CaseInsensitive); QRegExp modidExp(QString("http://([a-zA-Z0-9]*).nexusmods.com/downloads/file.php\\?id=(\\d+)"), Qt::CaseInsensitive); QRegExp modidAltExp(QString("http://([a-zA-Z0-9]*).nexusmods.com/mods/(\\d+)"), Qt::CaseInsensitive); if (sourceExp.indexIn(reply->url().toString()) != -1) { if (modidExp.indexIn(view->url().toString()) != -1) { modID = modidExp.cap(2).toInt(); } else if (modidAltExp.indexIn(view->url().toString()) != -1) { modID = modidAltExp.cap(2).toInt(); } else { modID = view->getLastSeenModID(); } } else { qDebug("not a nexus download: %s", reply->url().toString().toUtf8().constData()); return; } emit requestDownload(reply, modID, fileName); } catch (const std::exception &e) { if (isVisible()) { MessageDialog::showMessage(tr("failed to start download"), this); } qCritical("exception downloading unsupported content: %s", e.what()); } } void NexusDialog::downloadRequested(const QNetworkRequest &request) { qCritical("download request %s ignored", request.url().toString().toUtf8().constData()); } void NexusDialog::requestNXMDownload(const QString&) { if (isVisible()) { MessageDialog::showMessage(tr("Download started"), this); } } void NexusDialog::tabCloseRequested(int index) { if (m_Tabs->count() == 1) { this->close(); } else { m_Tabs->widget(index)->deleteLater(); m_Tabs->removeTab(index); } } void NexusDialog::on_browserTabWidget_customContextMenuRequested(const QPoint&) { } void NexusDialog::on_backBtn_clicked() { NexusView *currentView = getCurrentView(); if (currentView != NULL) { currentView->back(); } } void NexusDialog::on_fwdBtn_clicked() { NexusView *currentView = getCurrentView(); if (currentView != NULL) { currentView->forward(); } } void NexusDialog::startSearch() { ui->searchEdit->setFocus(); } void NexusDialog::on_modIDEdit_returnPressed() { QString url = ToQString(GameInfo::instance().getNexusPage()).append("/downloads/file.php?id=%1").arg(ui->modIDEdit->text()); NexusView *currentView = getCurrentView(); if (currentView != NULL) { currentView->load(QUrl(url)); } } void NexusDialog::on_searchEdit_returnPressed() { NexusView *currentView = getCurrentView(); if (currentView != NULL) { currentView->findText(ui->searchEdit->text(), QWebPage::FindWrapsAroundDocument); } } void NexusDialog::on_browserTabWidget_currentChanged(QWidget *current) { NexusView *currentView = qobject_cast(current); if (currentView != NULL) { ui->backBtn->setEnabled(currentView->history()->canGoBack()); ui->fwdBtn->setEnabled(currentView->history()->canGoForward()); } if (m_ModUrlExp.indexIn(currentView->url().toString()) != -1) { ui->modIDEdit->setText(m_ModUrlExp.cap(2)); } } void NexusDialog::on_refreshBtn_clicked() { getCurrentView()->reload(); }