/***************************************************************************
- * Copyright (C) 2009 by Lassi Väätämöinen *
- * lassi.vaatamoinen@ixonos.com *
+ * Copyright (C) 2010 by Ixonos Plc *
* *
* 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 2 of the License, or *
- * (at your option) any later version. *
+ * the Free Software Foundation; version 2 of the License. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#include <QLineEdit>
#include <QPushButton>
#include <QUrl>
+#include <QDir>
+#include <QFileInfo>
#include <QWebView>
-
+#include <QWebPage>
+#include <QNetworkReply>
+#include <QDomDocument>
#include "SearchPlugin.h"
+#include "DownloadManager.h"
namespace qtrapids
{
-<<<<<<< .mine
-SearchPlugin::SearchPlugin() :
- comboBox_(NULL), searchLine_(NULL), searchButton_(NULL), host_(NULL)
-{
- // TODO: Parse engine descriptions.
- // -Add engines to model
- // -Show model in comboBox
-
-}
-
-void SearchPlugin::initialize(PluginHostInterface* host)
-{
- host_ = host;
-
- if (host_ != NULL) {
-
- QWidget *pluginWidget = new QWidget;
- QVBoxLayout *vbox = new QVBoxLayout;
- QHBoxLayout *hbox = new QHBoxLayout;
- comboBox_ = new QComboBox;
- searchLine_ = new QLineEdit;
- searchButton_ = new QPushButton("Search");
-
- hbox->addWidget(searchLine_);
- hbox->addWidget(searchButton_);
- vbox->addWidget(comboBox_);
- vbox->addLayout(hbox);
- pluginWidget->setLayout(vbox);
-
- connect(searchButton_, SIGNAL(clicked()), this, SLOT(on_searchButton_clicked()));
- //connect(this, SIGNAL(searchResult(QWidget*)), this, SLOT(on_searchResult(QWidget*)));
-
- host_->setGui(this, pluginWidget);
+ const QString ENGINES_DIR = "engines";
+ const QString DESCRIPTION_FILENAME = "opensearch.xml";
+ const QString SEARCH_TERMS_STRING = "{searchTerms}";
+ const QString SEARCHPLUGIN_ID = "SearchPlugin";
+
+ SearchPlugin::SearchPlugin() :
+ comboBox_(NULL), searchLine_(NULL),
+ searchButton_(NULL), result_(NULL),
+ dlManager_(NULL), host_(NULL)
+ {
+ // TODO: Add back/forward/refresh -buttons to widget to allow some browsing functionality
}
-}
-
-QWidget* SearchPlugin::getGui()
-{
- return NULL;
-}
-
-void SearchPlugin::on_searchButton_clicked()
-{
- QUrl searchUrl(QString("http://www.google.fi/search?q="
- + searchLine_->text()));
- qDebug() << searchUrl;
- QWebView *result = new QWebView;
- result->load(searchUrl);
-
- on_searchResult((QWidget*)result);
-}
-
-void SearchPlugin::on_searchResult(QWidget* resultWidget)
-{
- qDebug() << "on_searchResult()";
- if (host_) {
- host_->addPluginWidget(this, resultWidget);
+
+
+ void SearchPlugin::initialize(PluginHostInterface* host, Info info)
+ {
+ host_ = host;
+
+ if (host_ != NULL) {
+
+ // Build up the plugin widget:
+ QWidget *pluginWidget = new QWidget;
+ QVBoxLayout *vbox = new QVBoxLayout;
+ QHBoxLayout *hbox = new QHBoxLayout;
+ comboBox_ = new QComboBox;
+ searchLine_ = new QLineEdit;
+ searchButton_ = new QPushButton("Search");
+
+ hbox->addWidget(searchLine_);
+ hbox->addWidget(searchButton_);
+ vbox->addWidget(comboBox_);
+ vbox->addLayout(hbox);
+ pluginWidget->setLayout(vbox);
+
+ connect(searchButton_, SIGNAL(clicked()), this, SLOT(on_searchButton_clicked()));
+ //connect(this, SIGNAL(searchResult(QWidget*)), this, SLOT(on_searchResult(QWidget*)));
+ qDebug() << info.directory;
+ QDir dir(info.directory);
+ if (dir.cd(ENGINES_DIR)) {
+ ParseSearchEngineDescriptions(dir);
+ }
+
+ host_->setGui(pluginWidget, qtrapids::PluginHostInterface::BASE_WIDGET, this);
+ }
+ }
+
+ QWidget* SearchPlugin::getGui()
+ {
+ return NULL;
+ }
+
+ QString SearchPlugin::identifier()
+ {
+ return SEARCHPLUGIN_ID;
}
-}
-=======
- SearchPlugin::SearchPlugin() :
- comboBox_(NULL), searchLine_(NULL), searchButton_(NULL), host_(NULL)
-{
- // TODO: Parse engine descriptions.
- // -Add engines to model
- // -Show model in comboBox
- >>>>>>> .r31
-
-}
-
-void SearchPlugin::initialize(PluginHostInterface* host)
-{
- host_ = host;
-
- if (host_ != NULL) {
-
- QWidget *pluginWidget = new QWidget;
- QVBoxLayout *vbox = new QVBoxLayout;
- QHBoxLayout *hbox = new QHBoxLayout;
- comboBox_ = new QComboBox;
- searchLine_ = new QLineEdit;
- searchButton_ = new QPushButton("Search");
-
- hbox->addWidget(searchLine_);
- hbox->addWidget(searchButton_);
- vbox->addWidget(comboBox_);
- vbox->addLayout(hbox);
- pluginWidget->setLayout(vbox);
- connect(searchButton_, SIGNAL(clicked()), this, SLOT(on_searchButton_clicked()));
- //connect(this, SIGNAL(searchResult(QWidget*)), this, SLOT(on_searchResult(QWidget*)));
- host_->setGui(pluginWidget);
+ void SearchPlugin::on_searchButton_clicked()
+ {
+ int i = comboBox_->currentIndex();
+ QString tmp = engineTemplates_.at(i);
+
+ i = tmp.indexOf(SEARCH_TERMS_STRING);
+ tmp.replace(i, SEARCH_TERMS_STRING.length(), searchLine_->text());
+
+ QUrl searchUrl(tmp);
+ qDebug() << searchUrl;
+ result_ = new QWebView;
+
+ // Get underlying QWebPage and change link delegation, so we can meddle with links in on_linkClicked().
+ QWebPage *resultPage = result_->page();
+ resultPage->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks);
+
+ // Get the network access manager for examining HTTP replies.
+ QNetworkAccessManager *netwAccessManager_ = resultPage->networkAccessManager();
+
+ connect(resultPage, SIGNAL(linkClicked(const QUrl&)), this, SLOT(on_linkClicked(const QUrl&)));
+ connect(result_, SIGNAL(loadFinished(bool)), this, SLOT(on_loadFinished(bool)));
+ connect(netwAccessManager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_networkReplyFinished(QNetworkReply*)));
+
+ result_->load(searchUrl);
+
+ on_searchResult((QWidget*)result_);
+ }
+
+
+ void SearchPlugin::on_loadFinished(bool ok)
+ {
+#ifdef QTRAPIDS_DEBUG
+ if (ok) {
+ qDebug() << "on_loadFinished(): success";
+ }
+#endif
+ }
+
+
+ void SearchPlugin::on_networkReplyFinished(QNetworkReply* reply)
+ {
+
+ qDebug() << "on_networkReplyFinished()";
+ QString contentType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
+ QString filename;
+ QByteArray replyData;
+ QUrl url = reply->url();
+
+ qDebug() << "on_networkReplyFinished():" << url;
+
+ // If content type is torrent data, read reply data:
+ if (contentType == "application/x-bittorrent") {
+
+ // If HTTP-response has Content-Disposition: -header, then we must use that as filename.
+ if (reply->hasRawHeader("Content-Disposition")) { // NOTE this code block taken from kwebpage.cpp
+ const QString value = QLatin1String(reply->rawHeader("Content-Disposition"));
+ const int pos = value.indexOf(QLatin1String("filename="));
+ if (pos != -1) {
+ QString name = value.mid(pos + 9);
+ if (name.startsWith(QLatin1Char('"')) && name.endsWith(QLatin1Char('"')))
+ name = name.mid(1, name.size() - 2);
+ filename = name;
+ }
+ // No content-disposition header, use last part (the filename) of URL as filename:
+ } else {
+ QString path = url.path();
+ QFileInfo fInfo(path);
+ filename = fInfo.fileName();
+ }
+
+ // Destroy ongoing download, if any.
+ if (dlManager_) {
+ delete dlManager_;
+ dlManager_ = NULL;
+ }
+
+ /// @todo Is this a bit of a hack now; we get the reply and check Content-Type,
+ /// The download is then started afterwards, so we get unecessarily one extra
+ /// HTTP-response here.
+ /// @todo Could this whole content-type checking be logically moved to DownloadManager?
+ // Start downloading Torrent file.
+ dlManager_ = new DownloadManager(url, "/tmp/" + filename);
+ connect(dlManager_, SIGNAL(finished(QString)), this, SLOT(on_downloadFinished(QString)));
+ dlManager_->start();
+
+ }
+ }
+
+
+ void SearchPlugin::on_searchResult(QWidget* resultWidget)
+ {
+#ifdef QTRAPIDS_DEBUG
+ qDebug() << "on_searchResult()";
+#endif
+ if (host_) {
+ host_->addPluginWidget(resultWidget, qtrapids::PluginHostInterface::TAB_PAGE);
+ }
}
-}
-QWidget* SearchPlugin::getGui()
-{
- return NULL;
-}
-void SearchPlugin::on_searchButton_clicked()
-{
- QUrl searchUrl(QString("http://www.google.fi/search?q="
- + searchLine_->text()));
- qDebug() << searchUrl;
- QWebView *result = new QWebView;
- result->load(searchUrl);
+ /// @todo It may be that we don't actually need link delegation, because we check response Content-Type header
+ /// on_linkClicked() in that case unnecessary function
+ void SearchPlugin::on_linkClicked(const QUrl& url)
+ {
+ qDebug() << "on_linkClicked():" << url;
+
+ if (url.isValid()) {
+ result_->load(url);
+ }
+ }
+
+
+ void SearchPlugin::on_downloadFinished(QString filepath)
+ {
+#ifdef QTRAPIDS_DEBUG
+ qDebug() << "TORRENT DOWNLOADED: " << filepath;
+#endif
+ delete dlManager_;
+ dlManager_ = NULL;
+ if (host_) {
+ host_->eventRequest(QVariant(filepath), qtrapids::PluginHostInterface::OPEN_FILE);
+ }
+ }
- on_searchResult((QWidget*)result);
-}
-void SearchPlugin::on_searchResult(QWidget* resultWidget)
-{
- qDebug() << "on_searchResult()";
- if (host_) {
- host_->addPluginWidget(resultWidget);
+ void SearchPlugin::ParseSearchEngineDescriptions(const QDir& dir)
+ {
+ foreach (QString dirName, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+
+ QFile file(dir.path() + "/" + dirName + "/" + DESCRIPTION_FILENAME);
+
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qWarning() << "Unable to open " << DESCRIPTION_FILENAME << " for reading in " << dir.path();
+ continue;
+ }
+
+ // Parse the XML file to DOM document.
+ QDomDocument document;
+
+ // Second parameter: nameSpaceProcessing = false
+ if (!document.setContent(&file, false)) {
+ qWarning() << "Unable to parse " << DESCRIPTION_FILENAME << " in " << dirName;
+ } else {
+ QDomNodeList urlElements = document.elementsByTagName("Url");
+ QDomNodeList shortNameElements = document.elementsByTagName("ShortName");
+
+ QDomNode n = urlElements.item(0);
+ QDomNode m;
+ QDomNamedNodeMap attribMap;
+ if (n.hasAttributes()) {
+ attribMap = n.attributes();
+ m = attribMap.namedItem("template");
+ engineTemplates_.push_back(m.nodeValue());
+ }
+
+ n = shortNameElements.item(0);
+ if (n.hasChildNodes()) {
+ m = n.firstChild();
+ comboBox_->addItem(m.nodeValue());
+ }
+ }
+ }
+ /// @todo save parsed xml elements <Shortname> and <Url template="<foo>"> to a model which is displayed in combobox.
}
-}
} // namespace qtrapids