</method>
<signal name="alert">
- <arg type="(ssuuuuuuuut)" name="info" direction="out"/>
+ <arg type="(ssuuuuuuuutt)" name="info" direction="out"/>
<annotation name="com.trolltech.QtDBus.QtTypeName.In0"
value="qtrapids::TorrentState"/>
<arg type="a{ss}" name="other_info" direction="out"/>
./PreferencesDialog.h
./proxy.h
./SeedView.h
+ ./ColumnSelectorDialog.h
)
SET(SRC
./PreferencesDialog.cpp
./proxy.cpp
./SeedView.cpp
+ ./ColumnSelectorDialog.cpp
)
QT4_WRAP_CPP(SRC ${MOC_HEADERS})
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2009 by Lassi Väätämöinen *
+ * lassi.vaatamoinen@ixonos.com *
+ * *
+ * 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. *
+ * *
+ * 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include <QGridLayout>
+#include <QTreeWidgetItem>
+#include <QCheckBox>
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+
+#include "ColumnSelectorDialog.h"
+
+
+ColumnSelectorDialog::ColumnSelectorDialog(QTreeWidget *treewidget, QWidget* parent, Qt::WindowFlags f) :
+ QDialog(parent, f), // Superclass construct
+ dialogButtons_(0),
+ grid_(0),
+ treeWidget_(treewidget),
+ checkBoxes_()
+{
+ QBoxLayout *verticalBox = new QBoxLayout(QBoxLayout::TopToBottom);
+ grid_ = new QGridLayout;
+ QCheckBox *cbox = NULL;
+
+ setLayout(verticalBox);
+ verticalBox->addLayout(grid_);
+
+ if (treeWidget_ != NULL) {
+ QTreeWidgetItem *item = treeWidget_->headerItem();
+
+ for (unsigned i = 0; i < item->columnCount(); ++i) {
+ cbox = new QCheckBox(item->text(i));
+ grid_->addWidget(cbox, i, 0);
+ treeWidget_->isColumnHidden(i) ? cbox->setCheckState(Qt::Unchecked) : cbox->setCheckState(Qt::Checked);
+ checkBoxes_.push_back(cbox);
+ cbox = NULL;
+ }
+ }
+
+ dialogButtons_ = new QDialogButtonBox(this);
+ dialogButtons_->setStandardButtons(QDialogButtonBox::Ok
+ | QDialogButtonBox::Cancel);
+
+ verticalBox->addWidget(dialogButtons_);
+
+ connect(dialogButtons_, SIGNAL(clicked(QAbstractButton*)),
+ this, SLOT(on_buttonClicked(QAbstractButton*)));
+}
+
+
+ColumnSelectorDialog::~ColumnSelectorDialog()
+{
+}
+
+
+void ColumnSelectorDialog::on_buttonClicked(QAbstractButton *button)
+{
+ switch (dialogButtons_->buttonRole ( button ) ) {
+ case QDialogButtonBox::AcceptRole :
+ ApplySettings();
+ done(QDialog::Accepted);
+ break;
+ case QDialogButtonBox::ApplyRole :
+ ApplySettings();
+ done(QDialog::Accepted);
+ break;
+ case QDialogButtonBox::RejectRole :
+ done(QDialog::Rejected);
+ break;
+ default:
+ return;
+ }
+}
+
+
+void ColumnSelectorDialog::ApplySettings()
+{
+ if (treeWidget_ != NULL) {
+ QTreeWidgetItem *item = treeWidget_->headerItem();
+ QCheckBox *cbox = NULL;
+
+ for (unsigned i = 0; i < checkBoxes_.size(); ++i) {
+ cbox = checkBoxes_.at(i);
+ cbox->isChecked() ? treeWidget_->showColumn(i) : treeWidget_->hideColumn(i);
+ cbox = NULL;
+ }
+ }
+}
+
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2009 by Lassi Väätämöinen *
+ * lassi.vaatamoinen@ixonos.com *
+ * *
+ * 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. *
+ * *
+ * 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, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef COLUMNSELECTORDIALOG_H
+#define COLUMNSELECTORDIALOG_H
+
+#include <vector>
+#include <QDialog>
+#include <QSettings>
+
+class QTreeWidget;
+class QDialogButtonBox;
+class QGridLayout;
+class QTreeWidget;
+class QCheckBox;
+class QAbstractButton;
+
+/**
+ @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+ @brief Dialog for selecting columns in QTreeViewWidget
+*/
+class ColumnSelectorDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ ColumnSelectorDialog(QTreeWidget *treewidget, QWidget* parent = 0, Qt::WindowFlags f = 0);
+ virtual ~ColumnSelectorDialog();
+
+ private slots:
+ void on_buttonClicked(QAbstractButton *button);
+
+ private:
+ QDialogButtonBox *dialogButtons_;
+ QGridLayout *grid_;
+ QTreeWidget *treeWidget_;
+ std::vector<QCheckBox*> checkBoxes_;
+
+ private:
+ void ApplySettings();
+
+};
+
+#endif
DownloadView::DownloadView(QWidget* parent) :
QTreeWidget(parent),
- items_()
+ items_(),
+ settings_()
{
setRootIsDecorated(false); // Hide branch lines, making one-level treeview (similar to list)
setHeaderItem(DownloadViewItem::getHeaderItem());
QVariant(formatSize(info.up_rate)));
item->setData(6, Qt::DisplayRole,
QString::number(info.seeds) + "/" + QString::number(info.leeches));
-
+ item->setData(7, Qt::DisplayRole, QString::number(info.ratio));
+
+ // Calculate ETA
+ if (info.down_rate > 0) {
+ qulonglong eta = (info.total_size - info.total_done) / info.down_rate;
+ item->setData(8, Qt::DisplayRole, formatElapsedTime(eta));
+ } else {
+ item->setData(8, Qt::DisplayRole, "N/A");
+ }
+
+ // Set color for status text
QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
item->setForeground(2, brushTmp);
}
}
+void DownloadView::saveView()
+{
+ QTreeWidgetItem *item = headerItem();
+ QList<QVariant> columns;
+
+ for (int i = 0; i < item->columnCount(); ++i) {
+ isColumnHidden(i) ? columns.push_back(QVariant(false)) : columns.push_back(QVariant(true));
+ }
+
+ settings_.setValue("downloadview_columns", QVariant(columns));
+}
+
+
+void DownloadView::restoreView()
+{
+ QTreeWidgetItem *item = headerItem();
+ QVariant columns(settings_.value("downloadview_columns"));
+ QList<QVariant> columnList = columns.toList();
+
+ for (int i = 0; i < columnList.size(); ++i) {
+ columnList.at(i).toBool() ? setColumnHidden(i, false) : setColumnHidden(i, true);
+ }
+}
+
+
QString DownloadView::GetStatusString(TorrentStatus::Id status)
{
switch (status) {
void updateItem(TorrentState const& info, ParamsMap_t other_info);
QString prepareRemoveSelected();
-
+
+ /// Saves current view settings via QSettings
+ void saveView();
+ /// Reads view settigns via QSettings
+ void restoreView();
+
private slots:
void on_itemClicked(QTreeWidgetItem * item, int column);
+
private:
+ // Maps torrent to downloadview item.
+ // Key: SHA1 info hash of torrent. Data: View item corresponding to torrent.
+ DownloadItems_t items_;
+ // Used for saving view settings
+ QSettings settings_;
+
+private:
+ // Private functions.
void addItem_(TorrentState const& info, ParamsMap_t other_info);
void updateItem_(DownloadViewItem *item
, TorrentState const& info, ParamsMap_t other_info);
void removeItem_(DownloadViewItem *item, TorrentState const& info);
- // Maps torrent to downloadview item.
- // Key: SHA1 info hash of torrent. Data: View item corresponding to torrent.
- DownloadItems_t items_;
- // Private functions.
static QString GetStatusString(TorrentStatus::Id status);
static QColor GetStatusColor(TorrentStatus::Id status);
+
};
#include <QAction>
#include <QFileDialog>
#include <QMessageBox>
+//#include <QTreeWidgetItem>
#include <QApplication>
#include <QPluginLoader>
#include "DownloadView.h"
#include "SeedView.h"
#include "PreferencesDialog.h"
+#include "ColumnSelectorDialog.h"
#include "MainWindow.h"
"\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"
+ "\nDenis Zalevskiy, denis.zalewsky@gmail.com"
"\n\nIxonos Plc, Finland\n"));
const QString PLUGINS_DIR = "plugins";
removeAction->setEnabled(false);
QAction *quitAction = tempMenu->addAction(tr("&Quit"));
+ tempMenu = menuBar->addMenu(tr("&View"));
+ QAction *columnsAction = tempMenu->addAction(tr("&Columns"));
+
tempMenu = menuBar->addMenu(tr("&Settings"));
QAction *preferencesAction = tempMenu->addAction(tr("&Preferences"));
connect(removeAction, SIGNAL(triggered()), this, SLOT(on_removeAction_clicked()));
connect(this, SIGNAL(itemSelected(bool)), removeAction, SLOT(setEnabled(bool)));
connect(quitAction, SIGNAL(triggered()), this, SLOT(on_quitAction_clicked()));
+ connect(columnsAction, SIGNAL(triggered()), this, SLOT(on_columnsAction_clicked()));
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()));
restoreGeometry(geometry.toByteArray());
}
+ // Restore DownloadView columns:
+ dlView_->restoreView();
+
// Restore torrent session settings to server:
qtrapids::ParamsMap_t options;
options["net/downloadRate"] = settings_.value("net/downloadRate").toString();
try {
server_.removeTorrent(hash);
} catch (...) {
- qDebug() << "Exception removing torrent";
+ qDebug() << "Exception while removing torrent";
}
}
}
+void MainWindow::on_columnsAction_clicked()
+{
+ ColumnSelectorDialog *dialog = new ColumnSelectorDialog(dlView_);
+ dialog->show();
+ dialog->exec();
+// dialog->raise();
+// dialog->activateWindow();
+ qDebug() << "dialog exit";
+
+ if (dialog->result() == QDialog::Accepted) {
+ qDebug() << "saved";
+ dlView_->saveView();
+ }
+}
+
+
void MainWindow::on_preferencesAction_clicked()
{
if (!preferencesDialog_) {
void on_openAction_clicked();
void on_removeAction_clicked();
void on_quitAction_clicked();
+ void on_columnsAction_clicked();
void on_preferencesAction_clicked();
void on_aboutAction_clicked();
void on_aboutQtAction_clicked();
, seeds(0)
, leeches(0)
, ratio(0)
- , total_size(0) { }
+ , total_size(0)
+ , total_done(0){ }
QString hash;
QString name;
uint leeches;
uint ratio;
qulonglong total_size;
+ qulonglong total_done;
};
typedef QHash<QString, QString> ParamsMap_t;
argument.beginStructure();
argument << state.hash << state.name << (uint)(state.action) << state.state << state.progress
<< state.down_rate << state.up_rate << state.seeds
- << state.leeches << state.ratio << state.total_size;
+ << state.leeches << state.ratio << state.total_size << state.total_done;
argument.endStructure();
return argument;
}
uint action;
argument >> state.hash >> state.name >> action >> state.state >> state.progress
>> state.down_rate >> state.up_rate >> state.seeds
- >> state.leeches >> state.ratio >> state.total_size;
+ >> state.leeches >> state.ratio >> state.total_size >> state.total_done;
state.action = (TorrentState::torrent_action)action;
argument.endStructure();
return argument;
#include <qtrapids/info.hpp>
#include <QtCore/QString>
-
+#include <QDebug>
namespace qtrapids
{
"KB",
"B"
};
+
+const qulonglong SECONDS_IN_DAY = 60*60*24;
}
static inline QString formatSize(qulonglong size)
}
+inline QString formatElapsedTime(qulonglong seconds)
+{
+ qulonglong hours = 0, minutes = 0, secsLeft = 0;
+ QString dayStr, hourStr, minStr, secStr;
+ dayStr = hourStr = minStr = secStr = QString::number(0);
+
+ //result.reserve(8);
+
+ hours = seconds / 3600;
+ secsLeft = seconds % 3600;
+ minutes = secsLeft / 60;
+ secsLeft = secsLeft % 60;
+
+ // If more than 24 hours, format time as days, hours.
+ // Otherwise hours : mins : secs
+ if (hours >= 24) {
+ dayStr = QString::number(hours / 24);
+ hourStr = QString::number(hours % 24);
+ return dayStr + 'd' + ' ' + hourStr + 'h';
+ } else if (hours < 10) {
+ hourStr.append(QString::number(hours));
+ } else {
+ hourStr = QString::number(hours);
+ }
+
+ if (minutes < 10) {
+ minStr.append(QString::number(minutes));
+ } else {
+ minStr = QString::number(minutes);
+ }
+
+ if (secsLeft < 10) {
+ secStr.append(QString::number(secsLeft));
+ } else {
+ secStr = QString::number(secsLeft);
+ }
+
+ return hourStr + ':' + minStr + ':' + secStr;
+}
+
} // namespace qtrapids
#endif // _QTRAPIDS_FORMAT_HPP_
return static_cast<size_t> (info.total_size());
}
+size_t TorrentHandle::getTotalDone() const
+{
+ TorrentStatus_t statusTmp = status();
+ return static_cast<size_t> (statusTmp.total_done);
+}
TorrentStatus::Id TorrentHandle::state() const
{
QString name() const;
size_t getTotalSize() const;
+ size_t getTotalDone() const;
TorrentStatus::Id state() const;
float progress() const;
float uploadRate() const;
state.up_rate = handle.uploadRate();
state.seeds = handle.numSeeds();
state.leeches = handle.numLeeches();
-
+ state.total_size = handle.getTotalSize();
+ state.total_done = handle.getTotalDone();
+
ParamsMap_t params;
emit alert(state, params);
}