X-Git-Url: http://git.maemo.org/git/?p=qtrapids;a=blobdiff_plain;f=src%2Fgui%2FMainWindow.cpp;h=b1ec1a32374a727d06d9b870247ae90acee973be;hp=a3262e1b712b80d60dce39cd06576e629cc17d4b;hb=1d97c0a567b80cf9fc67791669debfe3aa9c4c84;hpb=f576091800144d69317250a69d40c711505a4f34 diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index a3262e1..b1ec1a3 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1,11 +1,9 @@ /*************************************************************************** - * 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 * @@ -26,6 +24,8 @@ #include #include #include +#include +#include #include "DownloadView.h" #include "SeedView.h" @@ -33,43 +33,46 @@ #include "MainWindow.h" -const QString ABOUT_TEXT - = QString(QObject::trUtf8("QtRapids, a simple BitTorrent client based on" - "\nQt and Libtorrent." - "\n\nURL: http://qtrapids.garage.maemo.org/" - "\n\nAuthors:\nLassi Väätämöinen, lassi.vaatamoinen@ixonos.com" - "\nDenis Zalievsky, denis.zalewsky@ixonos.com" - "\n\nIxonos Plc, Finland\n")); +const QString ABOUT_TEXT += QString(QObject::trUtf8("QtRapids, a simple BitTorrent client based on" + "\nQt and Libtorrent." + "\n\nURL: http://qtrapids.garage.maemo.org/" + "\n\nAuthors:\nLassi Väätämöinen, lassi.vaatamoinen@ixonos.com" + "\nDenis Zalevskiy, denis.zalewsky@ixonos.com" + "\n\nIxonos Plc, Finland\n")); +const QString PLUGINS_DIR = "plugins"; // Consturctor MainWindow::MainWindow(): - QMainWindow(), // Superclass - tabWidget_(NULL), - dlView_(NULL), - seedView_(NULL), - preferencesDialog_(NULL), - settings_(), + QMainWindow(), // Superclass + tabWidget_(NULL), + dlView_(NULL), + seedView_(NULL), + searchWidget_(NULL), + preferencesDialog_(NULL), + settings_(), + pluginDirs_(), // torrentHandles_(), - btSession_() + btSession_() { - // MENUBAR + // MENUBAR QMenuBar *menuBar = new QMenuBar(); QMenu *tempMenu = NULL; - + tempMenu = menuBar->addMenu(tr("&File")); QAction *openAction = tempMenu->addAction(tr("&Open")); QAction *removeAction = tempMenu->addAction(tr("&Remove")); removeAction->setEnabled(false); QAction *quitAction = tempMenu->addAction(tr("&Quit")); - + tempMenu = menuBar->addMenu(tr("&Settings")); QAction *preferencesAction = tempMenu->addAction(tr("&Preferences")); - + tempMenu = menuBar->addMenu(tr("&Help")); QAction *aboutAction = tempMenu->addAction(tr("&About")); QAction *aboutQtAction = tempMenu->addAction(tr("About &Qt")); - + setMenuBar(menuBar); connect(openAction, SIGNAL(triggered()), this, SLOT(on_openAction_clicked())); connect(removeAction, SIGNAL(triggered()), this, SLOT(on_removeAction_clicked())); @@ -78,38 +81,43 @@ MainWindow::MainWindow(): connect(preferencesAction, SIGNAL(triggered()), this, SLOT(on_preferencesAction_clicked())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(on_aboutAction_clicked())); connect(aboutQtAction, SIGNAL(triggered()), this, SLOT(on_aboutQtAction_clicked())); - + // TABWIDGET (central widget) tabWidget_ = new QTabWidget(); - + tabWidget_->setTabsClosable(true); + /// @todo Exception handling dlView_ = new DownloadView(this); seedView_ = new SeedView(this); tabWidget_->addTab(dlView_, tr("Downloads")); tabWidget_->addTab(seedView_, tr("Seeds")); connect(dlView_, SIGNAL(itemSelectionChanged()), this, - SLOT(on_downloadItemSelectionChanged())); + SLOT(on_downloadItemSelectionChanged())); connect(seedView_, SIGNAL(itemSelectionChanged()), this, - SLOT(on_seedItemSelectionChanged())); + SLOT(on_seedItemSelectionChanged())); + - // Tab widget as central widget. setCentralWidget(tabWidget_); - + // TOOLBAR QToolBar *toolBar = new QToolBar(); toolBar->addAction(tr("Open")); removeAction = toolBar->addAction(tr("Remove")); removeAction->setEnabled(false); addToolBar(Qt::TopToolBarArea, toolBar); - + connect(this, SIGNAL(itemSelected(bool)), removeAction, - SLOT(setEnabled(bool))); + SLOT(setEnabled(bool))); connect(toolBar, SIGNAL(actionTriggered(QAction*)), this, - SLOT(handleToolBarAction(QAction*))); + SLOT(handleToolBarAction(QAction*))); + connect (tabWidget_, SIGNAL(tabCloseRequested(int)), this, SLOT(on_tabWidget_tabCloseRequested(int))); connect(&btSession_, SIGNAL(alert(std::auto_ptr)), - this, SLOT(on_alert(std::auto_ptr))); + this, SLOT(on_alert(std::auto_ptr))); + + LoadPlugins(); + RestoreSettings(); } @@ -117,49 +125,237 @@ MainWindow::~MainWindow() { } -// =========================== SLOTS ================================= +// ===================== Implements PluginInterface ========================= +/// @todo add PluginInterface parameter to request plugin name +bool MainWindow::setGui(QWidget* widget, PluginWidgetType type, qtrapids::PluginInterface* plugin) +{ +#ifdef QTRAPIDS_DEBUG + qDebug() << "MainWindow::setGui():" << dlView_->currentItem(); +#endif + + if (plugin && plugin->identifier() == "SearchPlugin") { + searchWidget_ = widget; + } else { + return false; + } + + tabWidget_->addTab(widget, tr("Search")); + return true; +} + +/// @todo Add PluginInterface parameter to check which plugin gives the widget, to handle appropriately +void MainWindow::addPluginWidget(QWidget* widget, PluginWidgetType type) +{ +#ifdef QTRAPIDS_DEBUG + qDebug() << "MainWindow::addPluginWidget():" << dlView_->currentItem(); +#endif + + if (type == qtrapids::PluginHostInterface::TAB_PAGE) { + int index = tabWidget_->addTab(widget, tr("Results")); + tabWidget_->setCurrentIndex(index); + //layout_->addWidget(widget); + } +} +void MainWindow::addToolbar(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addToolItem(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addMenu(QWidget* widget, PluginWidgetType type) +{ +} + +void MainWindow::addMenuItem(QWidget* widget, PluginWidgetType type) +{ +} + +bool MainWindow::eventRequest(QVariant param, PluginRequest req) +{ + if (req == qtrapids::PluginHostInterface::OPEN_FILE) { + QString sourceFile = param.toString(); + + // Get the source files name from the full path: + QFileInfo fInfo(sourceFile); + QString targetFile = fInfo.fileName(); + targetFile = settings_.value("download/directory").toString() + "/" + targetFile; + + // Copy temoporary file to Downloads directory... + if (!QFile::copy(sourceFile, targetFile)) { + qDebug() << "File copying failed"; + return false; + } else { + // If copying was successful, remove the original temporary file. + QFile::remove(sourceFile); + } + + /// @todo Torrent bencoding validity should be checked before starting(?) + // ...and start the torrent: + on_torrentFileSelected(targetFile); + + } else if (req == qtrapids::PluginHostInterface::READ_BUFFER) { + // Create torrent information from char* buffer and start. + StartTorrentFromBufferData(param.toByteArray().constData(), param.toByteArray().size()); + } + + return true; +} + + +//=========================== PRIVATE ================================ + +void MainWindow::LoadPlugins() +{ + // Get plugin directories from + QStringList pluginDirsTmp = settings_.value("plugins/path").toStringList(); + QStringList nameFilters("*.so"); + + /// @todo enable "application directory" for plugin search in development/debug mode only. In release version + /// search plugins directory under $HOME/.qtrapids or system library paths + pluginDirsTmp << qApp->applicationDirPath(); + pluginDirsTmp.removeDuplicates(); + + foreach (QString dir, pluginDirsTmp) { + pluginDirs_.append(QDir(dir)); + } + + foreach (QDir dir, pluginDirs_) { + + if (dir.cd(PLUGINS_DIR)) { + + foreach (QString fileName, dir.entryList(nameFilters, QDir::Files)) { + QPluginLoader pluginLoader(dir.absoluteFilePath(fileName)); + + // If plugin not loaded from another directory, then load + if (!pluginFileNames_.contains(fileName) && QLibrary::isLibrary(fileName)) { + + if (pluginLoader.load()) { + qDebug() << "Plugin loaded: " << fileName; + } else { + qWarning() << "Plugin load failed: " << pluginLoader.errorString(); + } + + QObject *baseInstance = pluginLoader.instance(); + if (!baseInstance) { + qDebug() << "Base instance = NULL."; + } + + qtrapids::PluginInterface *plugin = qobject_cast(baseInstance); + + if (!plugin) { + qDebug() << "Cast failed."; + } else { + qtrapids::PluginInterface::Info info; + info.directory = dir.path(); + qDebug() << dir.path(); + plugin->initialize(this, info); + pluginFileNames_ += fileName; + } + } else { + qWarning() << "Plugin " + << fileName + << " already loaded from another directory, or not a valid library file"; + } + } + + } else { + qWarning() << PLUGINS_DIR << "directory not accessible or does not exist in " << dir.path(); + } + } +} + + +void MainWindow::RestoreSettings() +{ + btSession_.setUploadRateLimit(settings_.value("network/uploadRate").toInt()); + btSession_.setDownloadRateLimit(settings_.value("network/downloadRate").toInt()); +} + + +// Opens torrent information from buffer data and adds torrent to session +void MainWindow::StartTorrentFromBufferData(char const* data, int size) +{ + // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent + /// @todo Should typedef libtorrent::torrent_info to something + AddTorrentParams addParams; + boost::intrusive_ptr tiTmp = + new libtorrent::torrent_info(data, size); + addParams.ti = tiTmp; + // save_path is the only mandatory parameter, rest are optional. + addParams.save_path = boost::filesystem::path(settings_.value("download/directory").toString().toStdString()); + //addParams.storage_mode = libtorrent::storage_mode_allocate; + qtrapids::QTorrentHandle handle = btSession_.addTorrent(addParams); + dlView_->newItem(handle); +// torrentHandles_.push_back(handlePtr); +#ifdef QTRAPIDS_DEBUG + qDebug() << "Is valid: " << handle.isValid(); +#endif +} + +// =========================== PRIVATE SLOTS ================================= void MainWindow::on_openAction_clicked() { QFileDialog *dialog = new QFileDialog( this, "Open torrent file", QString(), tr("Torrent files (*.torrent)")); dialog->setFileMode(QFileDialog::ExistingFile); connect(dialog, SIGNAL(fileSelected(const QString&)), this, SLOT(on_torrentFileSelected(const QString&))); dialog->show(); - } void MainWindow::on_removeAction_clicked() { - QTorrentHandle handle = dlView_->removeSelected(); + qtrapids::QTorrentHandle handle = dlView_->removeSelected(); btSession_.removeTorrent(handle); } + void MainWindow::on_quitAction_clicked() { close(); } + void MainWindow::on_preferencesAction_clicked() { if (!preferencesDialog_) { - preferencesDialog_ = new PreferencesDialog(this); + preferencesDialog_ = new PreferencesDialog(this, NULL, &btSession_); } + preferencesDialog_->show(); preferencesDialog_->raise(); preferencesDialog_->activateWindow(); } + void MainWindow::on_aboutAction_clicked() { - QMessageBox::about(this, tr("About QtRapids"), ABOUT_TEXT); + QMessageBox::about(this, tr("About QtRapids"), ABOUT_TEXT); } - - + + void MainWindow::on_aboutQtAction_clicked() { QMessageBox::aboutQt (this, tr("About Qt")); } +void MainWindow::on_tabWidget_tabCloseRequested(int index) +{ + + int searchWidgetIndex = tabWidget_->indexOf(searchWidget_); + + // Allow closing other tabs than the first two + // TODO The first two may well be closable, just add "show tabs" action for these in the menu + if (index != 0 && index != 1 && index != searchWidgetIndex) { + QWidget *remove = tabWidget_->widget(index); + tabWidget_->removeTab(index); + delete remove; + remove = NULL; + } +} + + void MainWindow::on_downloadItemSelectionChanged() { #ifdef QTRAPIDS_DEBUG @@ -172,6 +368,7 @@ void MainWindow::on_downloadItemSelectionChanged() } } + void MainWindow::on_seedItemSelectionChanged() { #ifdef QTRAPIDS_DEBUG @@ -183,7 +380,8 @@ void MainWindow::on_seedItemSelectionChanged() emit(itemSelected(false)); } } - + + void MainWindow::handleToolBarAction(QAction* action) { if (action->text() == "Open") { @@ -193,6 +391,7 @@ void MainWindow::handleToolBarAction(QAction* action) } } + void MainWindow::on_torrentFileSelected(const QString& file) { #ifdef QTRAPIDS_DEBUG @@ -202,17 +401,18 @@ void MainWindow::on_torrentFileSelected(const QString& file) if (file == "") { return; } - + // Otherwise add torrent // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent + /// @todo Should typedef libtorrent::torrent_info to something AddTorrentParams addParams; - boost::intrusive_ptr tiTmp = - new libtorrent::torrent_info(boost::filesystem::path(file.toStdString())); + boost::intrusive_ptr tiTmp = + new libtorrent::torrent_info(boost::filesystem::path(file.toStdString())); addParams.ti = tiTmp; // save_path is the only mandatory parameter, rest are optional. - addParams.save_path = boost::filesystem::path(settings_.value("download/directory").toString().toStdString()); + addParams.save_path = boost::filesystem::path(settings_.value("download/directory").toString().toStdString()); //addParams.storage_mode = libtorrent::storage_mode_allocate; - QTorrentHandle handle = btSession_.addTorrent(addParams); + qtrapids::QTorrentHandle handle = btSession_.addTorrent(addParams); dlView_->newItem(handle); // torrentHandles_.push_back(handlePtr); #ifdef QTRAPIDS_DEBUG @@ -220,35 +420,29 @@ void MainWindow::on_torrentFileSelected(const QString& file) #endif } - void MainWindow::on_alert(std::auto_ptr al) { - - if (al.get() != NULL) { -// qDebug() -// << "MainWindow::on_torrentAlert(): " +// qDebug() +// << "MainWindow::on_torrentAlert(): " // << QString::fromStdString(al->message()); - TorrentAlert *torrentAlert - = dynamic_cast (al.get()); + TorrentAlert *torrentAlert + = dynamic_cast (al.get()); if (torrentAlert) { - QTorrentHandle torrentHandle = QTorrentHandle(torrentAlert->handle); - dlView_->updateItem(QTorrentHandle(torrentAlert->handle)); + qtrapids::QTorrentHandle torrentHandle = qtrapids::QTorrentHandle(torrentAlert->handle); + dlView_->updateItem(qtrapids::QTorrentHandle(torrentAlert->handle)); } - + } - - - } /* -bool MainWindow::IsNewTorrent(std::auto_ptr handlePtr) +bool MainWindow::IsNewTorrent(std::auto_ptr handlePtr) { for (unsigned i = 0; i < torrentHandles_.size(); ++i) { - if (torrentHandles_.at(i).get() == handlePtr.get()) { + if (torrentHandles_.at(i).get() == handlePtr.get()) { return false; } else { return true;