Reverted invalid commit 82
authorlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Sun, 29 Jan 2012 14:27:46 +0000 (14:27 +0000)
committerlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Sun, 29 Jan 2012 14:27:46 +0000 (14:27 +0000)
git-svn-id: file:///svnroot/qtrapids/trunk@83 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda

38 files changed:
CMakeLists.txt
src/client/CMakeLists.txt
src/client/models/Plugin.cpp [deleted file]
src/client/models/Plugin.h [deleted file]
src/client/models/QDeclarativeDownloadListModel.cpp [deleted file]
src/client/models/QDeclarativeDownloadListModel.h [deleted file]
src/client/models/QDeclarativeDownloadListModel_p.h [deleted file]
src/client/models/qmldir [deleted file]
src/client/qml/DownloadView.qml [deleted file]
src/client/qml/MainPage.qml [deleted file]
src/client/qml/SeedView.qml [deleted file]
src/client/qml/main.qml [deleted file]
src/client/qml/qml.qrc [deleted file]
src/qml-client/CMakeLists.txt [new file with mode: 0644]
src/qml-client/ColumnSelectorDialog.cpp [new file with mode: 0644]
src/qml-client/ColumnSelectorDialog.h [new file with mode: 0644]
src/qml-client/DownloadView.cpp [new file with mode: 0644]
src/qml-client/DownloadView.h [new file with mode: 0644]
src/qml-client/MainWindow.cpp [new file with mode: 0644]
src/qml-client/MainWindow.h [new file with mode: 0644]
src/qml-client/PreferencesDialog.cpp [new file with mode: 0644]
src/qml-client/PreferencesDialog.h [new file with mode: 0644]
src/qml-client/SeedView.cpp [new file with mode: 0644]
src/qml-client/SeedView.h [new file with mode: 0644]
src/qml-client/main.cpp [new file with mode: 0644]
src/qml-client/models/Plugin.cpp [new file with mode: 0644]
src/qml-client/models/Plugin.h [new file with mode: 0644]
src/qml-client/models/QDeclarativeDownloadListModel.cpp [new file with mode: 0644]
src/qml-client/models/QDeclarativeDownloadListModel.h [new file with mode: 0644]
src/qml-client/models/QDeclarativeDownloadListModel_p.h [new file with mode: 0644]
src/qml-client/models/qmldir [new file with mode: 0644]
src/qml-client/proxy.cpp [new file with mode: 0644]
src/qml-client/proxy.h [new file with mode: 0644]
src/qml-client/qml/DownloadView.qml [new file with mode: 0644]
src/qml-client/qml/MainPage.qml [new file with mode: 0644]
src/qml-client/qml/SeedView.qml [new file with mode: 0644]
src/qml-client/qml/main.qml [new file with mode: 0644]
src/qml-client/qml/qml.qrc [new file with mode: 0644]

index 5ac910a..8e9c71e 100644 (file)
@@ -4,7 +4,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON)
 
 # Check if we are building under scratchbox and link with QtMaemo5 only in that case.
 # Thus, we maintain desktop build-ability also
 
 # Check if we are building under scratchbox and link with QtMaemo5 only in that case.
 # Thus, we maintain desktop build-ability also
-set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
+#set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
 
 if (SCRATCHBOX_UNAME)
        MESSAGE("Configuring for building under Scratchbox..")
 
 if (SCRATCHBOX_UNAME)
        MESSAGE("Configuring for building under Scratchbox..")
@@ -19,5 +19,6 @@ find_package(Qt4 REQUIRED)
 add_subdirectory(./dbus)
 add_subdirectory(./src/client)
 add_subdirectory(./src/server)
 add_subdirectory(./dbus)
 add_subdirectory(./src/client)
 add_subdirectory(./src/server)
+add_subdirectory(./src/qml-client)
 #add_subdirectory(./src/utest)
 
 #add_subdirectory(./src/utest)
 
index 873b699..da3d8b5 100644 (file)
@@ -1,12 +1,6 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-
-set(QT_USE_QTDECLARATIVE 1)
-
-FIND_PACKAGE(Qt4 REQUIRED)
-
 INCLUDE(${QT_USE_FILE})
 
 INCLUDE(${QT_USE_FILE})
 
-INCLUDE_DIRECTORIES(${qtrapids_SOURCE_DIR}/src/include ${qtrapids_SOURCE_DIR}/src/plugins)
+INCLUDE_DIRECTORIES(../include ../plugins)
 
 FIND_LIBRARY(BOOST_SYSTEM boost_system-mt)
 IF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
 
 FIND_LIBRARY(BOOST_SYSTEM boost_system-mt)
 IF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
@@ -18,48 +12,32 @@ INCLUDE_DIRECTORIES(
    ${QT_QTTEST_INCLUDE_DIR}
    ${QT_QTDBUS}
    ${QT_QTGUI}
    ${QT_QTTEST_INCLUDE_DIR}
    ${QT_QTDBUS}
    ${QT_QTGUI}
-   ${QT_QTDECLARATIVE_INCLUDE_DIR}
 )
 
 SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/proxy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/proxy.h PROPERTIES GENERATED 1)
 
 SET(MOC_HEADERS
 )
 
 SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/proxy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/proxy.h PROPERTIES GENERATED 1)
 
 SET(MOC_HEADERS
-    ./models/QDeclarativeDownloadListModel.h
-    ./models/QDeclarativeDownloadListModel_p.h
-#     ./DownloadView.h
-#     ./models/Plugin.h
-#   ./MainWindow.h
-#   ./PreferencesDialog.h
-#   ./proxy.h
-#   ./SeedView.h
-#   ./ColumnSelectorDialog.h
+  ./DownloadView.h
+  ./MainWindow.h
+  ./PreferencesDialog.h
+  ./proxy.h
+  ./SeedView.h
+  ./ColumnSelectorDialog.h
 )
 
 SET(SRC
 )
 
 SET(SRC
-#     ./DownloadView.cpp
-    ./main.cpp
-    ./models/QDeclarativeDownloadListModel.cpp
-#   ./MainWindow.cpp
-#   ./PreferencesDialog.cpp
-#   ./proxy.cpp
-#   ./SeedView.cpp
-#   ./ColumnSelectorDialog.cpp
+  ./DownloadView.cpp
+  ./main.cpp
+  ./MainWindow.cpp
+  ./PreferencesDialog.cpp
+  ./proxy.cpp
+  ./SeedView.cpp
+  ./ColumnSelectorDialog.cpp
 )
 
 )
 
-
-# Set the resource files to be used.
-# Add all .qrc files here, that are needed.
-SET(RCCS qml/qml.qrc)
-
-# generate rules for building source files from the resources
-QT4_ADD_RESOURCES(RCC_SRC ${RCCS})
-# generate rules for building source files that moc generates
-QT4_WRAP_CPP(QtApp_MOC_SRCS ${QtApp_MOCS})
-
 QT4_WRAP_CPP(SRC ${MOC_HEADERS})
 QT4_WRAP_CPP(SRC ${MOC_HEADERS})
-# Build the executable from these files:
-ADD_EXECUTABLE(qml-client ${SRC} ${MOC_HEADERS}  ${RCC_SRC})
-INSTALL(TARGETS qml-client DESTINATION bin)
+ADD_EXECUTABLE(qtrapids-gui ${SRC} ${MOC_HEADERS})
+INSTALL(TARGETS qtrapids-gui DESTINATION bin)
 
 ADD_DEFINITIONS(-DQT_SHARED)
 
 
 ADD_DEFINITIONS(-DQT_SHARED)
 
@@ -76,18 +54,17 @@ if(NOT QT_QTMAEMO5_LIBRARY)
 endif(NOT QT_QTMAEMO5_LIBRARY)
 
 
 endif(NOT QT_QTMAEMO5_LIBRARY)
 
 
-TARGET_LINK_LIBRARIES(qml-client
+TARGET_LINK_LIBRARIES(qtrapids-gui
   ${QT_QTGUI_LIBRARY} 
   ${QT_QTCORE_LIBRARY} 
   ${QT_QTDBUS_LIBRARY}
   ${QT_QTTEST_LIBRARY}
   ${QT_QTGUI_LIBRARY} 
   ${QT_QTCORE_LIBRARY} 
   ${QT_QTDBUS_LIBRARY}
   ${QT_QTTEST_LIBRARY}
-  ${QT_QTDECLARATIVE_LIBRARY}
   -lboost_system-mt
 )
 
 # Check if we are building under scratchbox and link with QtMaemo5 only in that case.
 # Thus, we maintain desktop build-ability also
   -lboost_system-mt
 )
 
 # Check if we are building under scratchbox and link with QtMaemo5 only in that case.
 # Thus, we maintain desktop build-ability also
-#set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
+set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
 
 if (SCRATCHBOX_UNAME)
        MESSAGE("Configuring for building under Scratchbox..")
 
 if (SCRATCHBOX_UNAME)
        MESSAGE("Configuring for building under Scratchbox..")
diff --git a/src/client/models/Plugin.cpp b/src/client/models/Plugin.cpp
deleted file mode 100644 (file)
index a6c6165..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <QObject>
-#include <QtDeclarative/qdeclarativeextensionplugin.h>
-#include <QtDeclarative/qdeclarative.h>
-
-// This class is needed to make DownloadListModel class available to QML:
-class QmlDownloadListModelPlugin : public QDeclarativeExtensionPlugin
-{
-    Q_OBJECT
-public:
-    virtual void registerTypes(const char *uri)
-    {
-        Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.downloadlistmodel"));
-        qmlRegisterType<qtrapids::QDeclarativeDownloadListModel>(uri, 1, 0, "DownloadListModel");
-    }
-};
-
-#include "moc_Plugin.cxx"
-
-Q_EXPORT_PLUGIN2(downloadlistmodelplugin, QT_PREPEND_NAMESPACE(QmlDownloadListModelPlugin));
\ No newline at end of file
diff --git a/src/client/models/Plugin.h b/src/client/models/Plugin.h
deleted file mode 100644 (file)
index 129970c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <QtDeclarative/qdeclarativeextensionplugin.h>
-#include <QtDeclarative/qdeclarative.h>
-
-#include "QDeclarativeDownloadListModel.h"
-
-// This class is needed to make DownloadListModel class available to QML:
-class QmlDownloadListModelPlugin : public QDeclarativeExtensionPlugin
-{
-    Q_OBJECT
-public:
-    virtual void registerTypes(const char *uri)
-    {
-        Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.downloadlistmodel"));
-        qmlRegisterType<qtrapids::QDeclarativeDownloadListModel>(uri, 1, 0, "DownloadListModel");
-    }
-};
-
-Q_EXPORT_PLUGIN2(downloadlistmodelplugin, QT_PREPEND_NAMESPACE(QmlDownloadListModelPlugin));
\ No newline at end of file
diff --git a/src/client/models/QDeclarativeDownloadListModel.cpp b/src/client/models/QDeclarativeDownloadListModel.cpp
deleted file mode 100644 (file)
index e990705..0000000
+++ /dev/null
@@ -1,304 +0,0 @@
-/***************************************************************************
- *   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; 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        *
- *   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 <QtCore/QVariant>
-#include <QtCore/QDebug>
-
-#include "QDeclarativeDownloadListModel.h"
-#include "QDeclarativeDownloadListModel_p.h"
-#include "qtrapids/format.hpp"
-
-namespace qtrapids
-{
-
-QDeclarativeDownloadListModel::QDeclarativeDownloadListModel(QObject *parent):
-        QAbstractListModel(parent)
-{
-    d = new QDeclarativeDownloadListModelPrivate;
-
-    // These roles are the names that we use to access the model data on QML
-    // in the string format. So, use the value on the right-hand side of assignment operator in QML.
-    // The role enum value is passed from QML side to the C++ model for fetching the data.
-    QHash<int, QByteArray> roles;
-    roles[DownloadRole] = "download";
-    roles[SeedRole] = "seed";
-    roles[HashRole] = "hash";
-    roles[NameRole] = "name";
-    roles[SizeRole] = "size";
-    roles[StatusRole] = "status";
-    roles[StateRole] = "state";
-    roles[ProgressRole] = "progress";
-    roles[DownRateRole] = "downRate";
-    roles[UpRateRole] = "upRate";
-    roles[SeedsRole] = "seeds";
-    roles[LeechesRole] = "leeches";
-    roles[RatioRole] = "ratio";
-    roles[TotaSizeRole] = "totalSize";
-    roles[TotalDoneRole] = "totalDone";
-    setRoleNames(roles);
-}
-
-QDeclarativeDownloadListModel::~QDeclarativeDownloadListModel()
-{
-}
-
-
-void
-QDeclarativeDownloadListModel::updateItem(TorrentState const& info,
-                                          ParamsMap_t other_info)
-{
-    qDebug() << Q_FUNC_INFO << " enter";
-
-    DownloadItems_t::iterator p = d->items_.find(info.hash);
-    switch (info.action) {
-        case TorrentState::action_add :
-            if (p == d->items_.end()) {
-                addItem_(info, other_info);
-            } else {
-                qWarning() << "item with similar info hash marked as added";
-                updateItem_(info, other_info);
-            }
-            break;
-        case TorrentState::action_update :
-            if (p != d->items_.end()) {
-                updateItem_(info, other_info);
-            } else {
-                qWarning() << "item does not exist in list but information update arrived";
-            }
-            break;
-        case TorrentState::action_remove :
-            if (p != d->items_.end()) {
-                removeItem_(info);
-            } else {
-                qWarning() << "item removal request arrived but there is no such item";
-            }
-            break;
-        default:
-            qWarning() << "unknown action requested: " << info.action;
-            break;
-    }
-}
-
-
-    // Returns the hash of the torrent be removed.
-QString QDeclarativeDownloadListModel::prepareRemoveSelected()
-{
-    return "DUMMY_HASH";
-}
-
-int QDeclarativeDownloadListModel::rowCount(const QModelIndex &parent) const
-{
-    return d->items_.count();
-}
-
-QVariant QDeclarativeDownloadListModel::data(const QModelIndex &index, int role) const
-{
-
-    qDebug() << Q_FUNC_INFO << " enter";
-    int rowIndex = index.row();
-    QString hash;
-    TorrentState item;
-
-    // Get the item hash corresponding to row number:
-    if (d->itemIndexes_.contains(rowIndex))
-        hash = d->itemIndexes_[rowIndex];
-    else
-        return QVariant();
-
-    // Get the torrent info for the hash:
-    if (d->items_.contains(hash))
-        item = d->items_[hash];
-    else 
-        return QVariant();
-
-    switch (role) {
-//         case DownloadRole:
-//             // TODO: What to do here??
-//             break;
-//         case SeedRole:
-//             // TODO: What to do here??
-//             break;
-        case HashRole:
-            return QVariant(item.hash);
-        case NameRole:
-            return QVariant(item.name);
-//         case SizeRole:
-//             return QVariant(item.total_size);
-        case StatusRole:
-            return QVariant();
-        case StateRole:
-            return QVariant(item.state);
-        case ProgressRole:
-            return QVariant(item.progress);
-        case DownRateRole:
-            return QVariant(item.down_rate);
-        case UpRateRole:
-            return QVariant(item.up_rate);
-        case SeedsRole:
-            return QVariant(item.seeds);
-        case LeechesRole:
-            return QVariant(item.leeches);
-        case RatioRole:
-            return QVariant(item.ratio);
-        case TotaSizeRole:
-            return QVariant(item.total_size);
-        case TotalDoneRole:
-            return QVariant(item.total_done);
-        default:
-            qWarning() << Q_FUNC_INFO << "Unknown role requested from model";
-            return QVariant();
-    }
-    return QVariant();
-}
-
-bool QDeclarativeDownloadListModel::insertRow(int row, const QModelIndex &parent)
-{
-    qDebug() << "QDeclarativeDownloadListModel::insertRow()";
-    return false;
-}
-
-bool QDeclarativeDownloadListModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
-    qDebug() << "QDeclarativeDownloadListModel::setData()";
-    return false;
-}
-
-
-void QDeclarativeDownloadListModel::classBegin()
-{
-    qDebug() << "QDeclarativeDownloadListModel::classBegin()";
-}
-
-void QDeclarativeDownloadListModel::componentComplete()
-{
-    qDebug() << "QDeclarativeDownloadListModel::componentComplete()";
-}
-
-
-void QDeclarativeDownloadListModel::removeItem_(TorrentState const& info)
-{
-    qDebug() << Q_FUNC_INFO << " enter";
-    QString hash = info.hash;
-
-    // TODO: Emit rows remove start
-    int removed = d->items_.remove(hash);
-    // TODO: Edit rows insert end
-    if (!removed)
-        qDebug() << "Inconsistent download view state on item removal";
-
-    /*
-    int index = indexOfTopLevelItem(item);
-    if (index >= 0) {
-            takeTopLevelItem(index);
-    }
-    */
-}
-
-void QDeclarativeDownloadListModel::addItem_(TorrentState const& info,
-                                             ParamsMap_t)
-{
-     qDebug() << Q_FUNC_INFO << " enter";
-/*
-    DownloadViewItem *item = new DownloadViewItem
-    ( info.hash,
-      QStringList()
-      << info.name
-      << formatSize(info.total_size)
-      << GetStatusString((TorrentStatus::Id)info.state)
-      << formatProgress(info.progress)
-      << formatSize(info.down_rate)
-      << formatSize(info.up_rate)
-      << QString::number(info.seeds) + "/" + QString::number(info.leeches)
-      << QString::number(info.ratio)
-      << "ETA" );
-
-    QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
-    item->setForeground(2, brushTmp);
-
-    addTopLevelItem(item);
-    */
-
-    int itemsCount = d->items_.count();
-    beginInsertRows(QModelIndex(), itemsCount, itemsCount+1);
-    d->items_[info.hash] = info;
-    d->itemIndexes_[itemsCount+1] = info.hash;
-    endInsertRows();
-}
-
-
-void QDeclarativeDownloadListModel::updateItem_(TorrentState const& info, ParamsMap_t)
-{
-     qDebug() << Q_FUNC_INFO << " enter";
-    /*
-    item->setData(2, Qt::DisplayRole,
-                  QVariant(GetStatusString((TorrentStatus::Id)info.state)));
-    item->setData(3, Qt::DisplayRole,
-                  QVariant(formatProgress(info.progress)));
-    item->setData(4, Qt::DisplayRole,
-                  QVariant(formatSize(info.down_rate)));
-    item->setData(5, Qt::DisplayRole,
-                  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");
-    }
-*/
-    // TODO: Update items data & Emit data changed.
-
-/*
-    // Set color for status text
-    QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
-    item->setForeground(2, brushTmp);
-    */
-}
-
-
-
-QString QDeclarativeDownloadListModel::GetStatusString(TorrentStatus::Id status)
-{
-    qDebug() << Q_FUNC_INFO << " enter";
-    switch (status) {
-        case TorrentStatus::QUEUED_FOR_CHECKING :
-            return tr("Queued");
-        case TorrentStatus::CHECKING_FILES :
-            return tr("Checking");
-        case TorrentStatus::DOWNLOADING_METADATA :
-            return tr("DL meta");
-        case TorrentStatus::DOWNLOADING :
-            return tr("Downloading");
-        case TorrentStatus::FINISHED :
-            return tr("Finished");
-        case TorrentStatus::SEEDING :
-            return tr("Seeding");
-        case TorrentStatus::ALLOCATING :
-            return tr("Allocating");
-        case TorrentStatus::CHECKING_RESUME_DATA :
-            return tr("Checking resume");
-        default:
-            return tr("N/A");
-    }
-}
-
-} // namespace qtrapids
diff --git a/src/client/models/QDeclarativeDownloadListModel.h b/src/client/models/QDeclarativeDownloadListModel.h
deleted file mode 100644 (file)
index ee9cadd..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/***************************************************************************
- *   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; 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        *
- *   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 QDECLARATIVEDOWNLOADLISTMODEL_H
-#define QDECLARATIVEDOWNLOADLISTMODEL_H
-
-
-#include <QDeclarativeParserStatus>
-#include <QAbstractListModel>
-#include <QtDeclarative>
-#include <QModelIndex>
-
-#include "qtrapids/dbus.hpp"
-#include "qtrapids/info.hpp"
-
-//#include "../DownloadView.h"
-
-QT_MODULE(Declarative);
-
-namespace qtrapids
-{
-
-typedef QHash<QString, TorrentState> DownloadItems_t;
-typedef QMap<int, QString> ItemIndex_t;
-
-class QDeclarativeContext;
-class QDeclarativeDownloadListModelPrivate;
-
-class QDeclarativeDownloadListModel :
-            public QAbstractListModel, public QDeclarativeParserStatus
-{
-    Q_OBJECT
-    Q_INTERFACES(QDeclarativeParserStatus);
-
-    /*
-    Q_PROPERTY(QString hash READ hash);
-    Q_PROPERTY(QString name READ name WRITE setName);
-    Q_PROPERTY(QString size READ size);
-    Q_PROPERTY(QString status READ status);
-    Q_PROPERTY(uint state READ state);
-    Q_PROPERTY(uint progress READ progress);
-    Q_PROPERTY(uint downRate READ downRate);
-    Q_PROPERTY(uint upRate READ upRate);
-    Q_PROPERTY(uint seeds READ seeds);
-    Q_PROPERTY(uint leeches READ leeches);
-    Q_PROPERTY(qulonglong ratio READ ratio);
-    Q_PROPERTY(qulonglong totaSize READ totalDone);
-    Q_PROPERTY(qulonglong totalDone READ totalDone);
-*/
-
-public:
-    QDeclarativeDownloadListModel(QObject *parent = 0);
-    virtual ~QDeclarativeDownloadListModel();
-
-    // TODO: Learn to use roles..
-    enum Roles {
-        DownloadRole = Qt::UserRole + 1, 
-        SeedRole,
-        HashRole,
-        NameRole,
-        SizeRole,
-        StatusRole,
-        StateRole,
-        ProgressRole,
-        DownRateRole,
-        UpRateRole,
-        SeedsRole,
-        LeechesRole,
-        RatioRole,
-        TotaSizeRole,
-        TotalDoneRole
-    };
-
-    // Updates the torrent status in the model.
-    void updateItem(TorrentState const& info, ParamsMap_t other_info);
-    // Returns the hash of the torrent be removed.
-    QString prepareRemoveSelected();
-
-    // -- QAbstractListModel
-    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
-    virtual QVariant data(const QModelIndex &index, int role) const;
-    virtual bool insertRow(int row, const QModelIndex &parent);
-    virtual bool setData (const QModelIndex & index, const QVariant &value, int role = Qt::EditRole);
-    // -- End QAbstractListModel
-
-    // -- Overrides from QDeclarativeParserStatus
-    virtual void classBegin();
-    virtual void componentComplete();
-    // -- End QDeclarativeParserStatus
-
-Q_SIGNALS:
-    void downloadItemChanged(QString hash);
-
-// Private functions.
-private:
-    Q_DISABLE_COPY(QDeclarativeDownloadListModel)
-    QDeclarativeDownloadListModelPrivate *d;
-
-    void addItem_(TorrentState const& info, ParamsMap_t other_info);
-    void updateItem_(TorrentState const& info, ParamsMap_t other_info);
-    void removeItem_(TorrentState const& info);
-    QString GetStatusString(TorrentStatus::Id status);
-private:
-
-};
-
-
-} // namespace qtrapids
-
-// We need to declare the type
-QML_DECLARE_TYPE(qtrapids::QDeclarativeDownloadListModel);
-
-
-
-#endif
diff --git a/src/client/models/QDeclarativeDownloadListModel_p.h b/src/client/models/QDeclarativeDownloadListModel_p.h
deleted file mode 100644 (file)
index 6c4b699..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef QDECLARATIVEDOWNLOADLISTMODELPRIVATE_H
-#define QDECLARATIVEDOWNLOADLISTMODELPRIVATE_H
-
-#include <QModelIndex>
-
-#include "QDeclarativeDownloadListModel.h" // TODO: For DownloadItems_t, move that to common place..
-
-namespace qtrapids
-{
-
-class QDeclarativeDownloadListModelPrivate : QObject
-{
-    Q_OBJECT
-public:
-    QDeclarativeDownloadListModelPrivate()
-    {
-    }
-
-    DownloadItems_t items_;
-    ItemIndex_t itemIndexes_;
-    //QModelIndex downloadIndex_;
-
-signals:
-    void itemAdded(QString hash);
-    void itemRemoved(QString hash);
-
-};
-} // namespace qtrapids
-
-#endif
diff --git a/src/client/models/qmldir b/src/client/models/qmldir
deleted file mode 100644 (file)
index 9e05264..0000000
+++ /dev/null
@@ -1 +0,0 @@
-plugin qmlfolderlistmodelplugin
\ No newline at end of file
diff --git a/src/client/qml/DownloadView.qml b/src/client/qml/DownloadView.qml
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/client/qml/MainPage.qml b/src/client/qml/MainPage.qml
deleted file mode 100644 (file)
index a189bab..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-import QtQuick 1.1
-import Qt.labs.components 1.0
-import com.nokia.meego 1.0
-import com.meego 1.0
-import com.nokia.extras 1.0
-
-import QtRapids 1.0
-
-Page {
-    id: tabbarPage
-
-    property bool busy: Boolean(tabGroup.currentTab.busy)
-    anchors.margins: rootWindow.pageMargin
-
-    tools: ToolBarLayout {
-        ToolIcon { iconId: "toolbar-back"; onClicked: pageStack.pop(); }
-        ButtonRow {
-            platformStyle: TabButtonStyle { }
-            TabButton {
-                text: "Downloads"
-                tab: downloads
-            }
-            TabButton {
-                text: "Seeds"
-                tab: seeds
-            }
-        }
-        ToolIcon { iconId: "toolbar-view-menu"; onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close() }
-    }
-//  Text {
-//      text: "Hello World!"
-//      font.family: "Helvetica"
-//      font.pointSize: 24
-//      color: "red"
-//     anchors.fill: parent
-//  }
-
-    ListView {
-        width: 200; height: 400
-/*
-        DownloadListModel {
-            id: downloadModel
-            // TODO: Does not work like this. Need properties to set from QML?
-            // Try setting test data from C++ side and view here..
-            /*
-            ListElement {
-                Hash: "QMLHASH1"
-                Size: "Size1"
-                Status: "DONE1"
-            }
-            ListElement {
-                Hash: "QMLHASH2"
-                Size: "Size2"
-                Status: "DONE2"
-            }
-            ListElement {
-                Hash: "QMLHASH3"
-                Size: "Size3"
-                Status: "DONE3"
-            }
-        }
-*/
-        Component {
-            id: downloadDelegate
-            Item {
-                height: 40
-                width: parent.width
-                Text {
-                    id: hashText
-                    text: hash
-                }
-                Text {
-                    id: nameText
-                    anchors.leftMargin: 10
-                    anchors.left: hashText.right
-                    text: name
-                }
-                Text {
-                    id: seedsText
-                    anchors.leftMargin: 10
-                    anchors.left: nameText.right
-                    text: seeds
-                }
-                Text {
-                    id: leechesText
-                    anchors.leftMargin: 10
-                    anchors.left: seedsText.right
-                    text: leeches
-                }
-            }
-        }
-
-        // downloadModel is from rootContext, set in main.cpp
-        model: downloadModel
-        delegate: downloadDelegate
-    }
-
-    /*
-    ListModel {
-        id: pagesModel
-        ListElement {
-            page: "CountBubble.qml"
-            title: "CountBubble"
-            subtitle: "Indicates current count"
-        }
-        ListElement {
-            page: "NetPromoterScore.qml"
-            title: "NetPromoterScore"
-            subtitle: "Shows net promotion query page"
-        }
-        ListElement {
-            page: "PageIndicator.qml"
-            title: "PageIndicator"
-            subtitle: "Indicates total & current pages"
-        }
-        ListElement {
-            page: "RatingIndicator.qml"
-            title: "RatingIndicator"
-            subtitle: "Indicates ratings"
-        }
-        ListElement {
-            page: "ListDelegates.qml"
-            title: "List Delegates"
-            subtitle: "Various List Delegates"
-        }
-        ListElement {
-            page: "MoreIndicator.qml"
-            title: "MoreIndicator"
-            subtitle: "Indicates that there are more contents"
-        }
-        ListElement {
-            page: "StyledButtons.qml"
-            title: "StyledButtons"
-            subtitle: "Buttons with different styles"
-        }
-    }
-    ListView {
-        id: listview
-        anchors.fill: parent
-        model: pagesModel
-
-        delegate: ListDelegate {
-            Image {
-                source: "image://theme/icon-m-common-drilldown-arrow" + (theme.inverted ? "-inverse" : "")
-                anchors.right: parent.right;
-                anchors.verticalCenter: parent.verticalCenter
-            }
-
-            subtitleColor: "#cc6633"
-            onClicked: { openFile(model.page); }
-        }
-    }
-*/
-    TabGroup {
-        id: tabGroup
-
-        currentTab: downloads
-
-        PageStack {
-            id: downloads
-        }
-        PageStack {
-            id: seeds
-        }
-        Page {
-            id: tab3
-            Column {
-                spacing: 10
-
-                Text {
-                    text: "This is a single page"
-                }
-            }
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/src/client/qml/SeedView.qml b/src/client/qml/SeedView.qml
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/client/qml/main.qml b/src/client/qml/main.qml
deleted file mode 100644 (file)
index 67383aa..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-import QtQuick 1.1
-import com.meego 1.0
-
-PageStackWindow {
-    id: rootWindow
-    property int pageMargin: 16
-
-    platformStyle: defaultStyle;
-
-    PageStackWindowStyle { id: defaultStyle }
-    PageStackWindowStyle { id: customStyle; background: "image://theme/meegotouch-wallpaper-portrait"}
-
-    // ListPage is what we see when the app starts, it links to the component specific pages
-    initialPage: MainPage { }
-
-    // These tools are shared by most sub-pages by assigning the id to a page's tools property
-    ToolBarLayout {
-        id: commonTools
-        visible: false
-        ToolIcon { iconId: "toolbar-back"; onClicked: { myMenu.close(); pageStack.pop(); } }
-        ToolIcon { iconId: "toolbar-view-menu"; onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close() }
-    }
-
-    Menu {
-        id: myMenu
-        visualParent: pageStack
-        MenuLayout {
-            MenuItem {id: b1; text: "Landscape"; onClicked: screen.allowedOrientations = Screen.Landscape}
-            MenuItem {id: b2; text: "Portrait"; onClicked: screen.allowedOrientations = Screen.Portrait}
-            MenuItem {id: b3; text: "Item 3"; onClicked: myMenu.accept()}
-            MenuItem {id: b4; text: "Item 4"; onClicked: myMenu.accept()}
-        }
-    }
-}
-
diff --git a/src/client/qml/qml.qrc b/src/client/qml/qml.qrc
deleted file mode 100644 (file)
index 955eecb..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
- <!DOCTYPE RCC>
- <RCC version="1.0">
-
- <qresource prefix="/">
-    <file>main.qml</file>
-    <file>MainPage.qml</file>
- </qresource>
-
- </RCC>
\ No newline at end of file
diff --git a/src/qml-client/CMakeLists.txt b/src/qml-client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..873b699
--- /dev/null
@@ -0,0 +1,102 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+set(QT_USE_QTDECLARATIVE 1)
+
+FIND_PACKAGE(Qt4 REQUIRED)
+
+INCLUDE(${QT_USE_FILE})
+
+INCLUDE_DIRECTORIES(${qtrapids_SOURCE_DIR}/src/include ${qtrapids_SOURCE_DIR}/src/plugins)
+
+FIND_LIBRARY(BOOST_SYSTEM boost_system-mt)
+IF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
+  MESSAGE(SEND_ERROR ${BOOST_SYSTEM})
+ENDIF(${BOOST_SYSTEM} STREQUAL BOOST_SYSTEM-NOTFOUND)
+
+INCLUDE_DIRECTORIES(
+   ${QT_INCLUDE_DIR}
+   ${QT_QTTEST_INCLUDE_DIR}
+   ${QT_QTDBUS}
+   ${QT_QTGUI}
+   ${QT_QTDECLARATIVE_INCLUDE_DIR}
+)
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/proxy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/proxy.h PROPERTIES GENERATED 1)
+
+SET(MOC_HEADERS
+    ./models/QDeclarativeDownloadListModel.h
+    ./models/QDeclarativeDownloadListModel_p.h
+#     ./DownloadView.h
+#     ./models/Plugin.h
+#   ./MainWindow.h
+#   ./PreferencesDialog.h
+#   ./proxy.h
+#   ./SeedView.h
+#   ./ColumnSelectorDialog.h
+)
+
+SET(SRC
+#     ./DownloadView.cpp
+    ./main.cpp
+    ./models/QDeclarativeDownloadListModel.cpp
+#   ./MainWindow.cpp
+#   ./PreferencesDialog.cpp
+#   ./proxy.cpp
+#   ./SeedView.cpp
+#   ./ColumnSelectorDialog.cpp
+)
+
+
+# Set the resource files to be used.
+# Add all .qrc files here, that are needed.
+SET(RCCS qml/qml.qrc)
+
+# generate rules for building source files from the resources
+QT4_ADD_RESOURCES(RCC_SRC ${RCCS})
+# generate rules for building source files that moc generates
+QT4_WRAP_CPP(QtApp_MOC_SRCS ${QtApp_MOCS})
+
+QT4_WRAP_CPP(SRC ${MOC_HEADERS})
+# Build the executable from these files:
+ADD_EXECUTABLE(qml-client ${SRC} ${MOC_HEADERS}  ${RCC_SRC})
+INSTALL(TARGETS qml-client DESTINATION bin)
+
+ADD_DEFINITIONS(-DQT_SHARED)
+
+set(QT_QTMAEMO5_LIBRARY -lQtMaemo5 -L${QT_LIBRARY_DIR})
+
+# QT_QTMAEMO5_* variables are not defined by CMake
+if(NOT QT_QTMAEMO5_INCLUDE_DIR)
+       FIND_PATH(QT_QTMAEMO5_INCLUDE_DIR QtMaemo5
+       PATHS ${QT_HEADERS_DIR}/QtMaemo5 NO_DEFAULT_PATH)
+endif(NOT QT_QTMAEMO5_INCLUDE_DIR)
+if(NOT QT_QTMAEMO5_LIBRARY)
+       FIND_LIBRARY(QT_QTMAEMO5_LIBRARY QtMaemo5
+       PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH)
+endif(NOT QT_QTMAEMO5_LIBRARY)
+
+
+TARGET_LINK_LIBRARIES(qml-client
+  ${QT_QTGUI_LIBRARY} 
+  ${QT_QTCORE_LIBRARY} 
+  ${QT_QTDBUS_LIBRARY}
+  ${QT_QTTEST_LIBRARY}
+  ${QT_QTDECLARATIVE_LIBRARY}
+  -lboost_system-mt
+)
+
+# Check if we are building under scratchbox and link with QtMaemo5 only in that case.
+# Thus, we maintain desktop build-ability also
+#set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
+
+if (SCRATCHBOX_UNAME)
+       MESSAGE("Configuring for building under Scratchbox..")
+       TARGET_LINK_LIBRARIES(qtrapids-gui  ${QT_QTMAEMO5_LIBRARY})
+endif (SCRATCHBOX_UNAME)
+
+#MESSAGE(${CMAKE_HOST_SYSTEM_PROCESSOR}) 
+#CHECK_LIBRARY_EXISTS(QT_QTMAEMO5_LIBRARY)
+
+
+
+ADD_DEPENDENCIES(qtrapids-gui dbusapi)
diff --git a/src/qml-client/ColumnSelectorDialog.cpp b/src/qml-client/ColumnSelectorDialog.cpp
new file mode 100644 (file)
index 0000000..4fe9c30
--- /dev/null
@@ -0,0 +1,130 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <QScrollArea>
+#include <QGroupBox>
+#include <QGridLayout>
+#include <QTreeWidgetItem>
+#include <QCheckBox>
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+
+#ifdef Q_WS_MAEMO_5
+       #include <QAbstractKineticScroller>
+#endif
+
+#include "ColumnSelectorDialog.h"
+
+
+ColumnSelectorDialog::ColumnSelectorDialog(QTreeWidget *treewidget, QWidget* parent, Qt::WindowFlags f) :
+       QDialog(parent, f), // Superclass construct
+       dialogButtons_(NULL),
+       grid_(NULL),
+       treeWidget_(treewidget),
+       scroller_(NULL),
+       checkBoxes_()
+{
+       QScrollArea *scrollArea = new QScrollArea(this);
+
+#ifdef Q_WS_MAEMO_5
+       /// @todo Kineticscrolling (property "FingerScrollable" does not work in Qt 4.6, only in 4.5)   
+       scroller_ = scrollArea->property("kineticScroller").value<QAbstractKineticScroller*>();
+
+       if (!scroller_)                                                               
+               qFatal("This example only works with QMaemo5Style as the default style for all QAbstractScrollAreas"); 
+#endif
+
+       scrollArea->setWidgetResizable(true);
+       //scrollArea->setProperty("FingerScrollable", false);
+       QBoxLayout *verticalBox = new QBoxLayout(QBoxLayout::TopToBottom);
+       grid_ = new QGridLayout;
+       QCheckBox *cbox = NULL;
+
+
+
+       // Create scrollable checkbox dialog to allow proper viewing on Maemo:
+       verticalBox->addWidget(scrollArea);
+       // A "temporary" widget for containing QScrollArea stuff
+       QWidget* scrollAreaWidgetContents = new QWidget(); 
+       scrollAreaWidgetContents->setLayout(grid_);
+       scrollArea->setWidget(scrollAreaWidgetContents);
+       setLayout(verticalBox);
+       
+       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;
+               }
+       }
+}
+
diff --git a/src/qml-client/ColumnSelectorDialog.h b/src/qml-client/ColumnSelectorDialog.h
new file mode 100644 (file)
index 0000000..5077aba
--- /dev/null
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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;
+class QAbstractKineticScroller;
+
+
+/**
+   @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_;
+               QAbstractKineticScroller *scroller_;
+               std::vector<QCheckBox*> checkBoxes_;
+
+       private:
+               void ApplySettings();
+       
+};
+
+#endif
diff --git a/src/qml-client/DownloadView.cpp b/src/qml-client/DownloadView.cpp
new file mode 100644 (file)
index 0000000..cf04e51
--- /dev/null
@@ -0,0 +1,244 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <qtrapids/format.hpp>
+
+#include "DownloadView.h"
+
+#include <QDebug>
+#include <QVariant>
+#include <QColor>
+
+namespace qtrapids
+{
+
+DownloadView::DownloadView(QWidget* parent) :
+               QTreeWidget(parent),
+               items_(),
+               settings_()
+{
+       setRootIsDecorated(false); // Hide branch lines, making one-level treeview (similar to list)
+       setHeaderItem(DownloadViewItem::getHeaderItem());
+
+       connect(this, SIGNAL(itemPressed(QTreeWidgetItem*, int)),
+               this, SLOT(on_itemClicked(QTreeWidgetItem*, int)));
+
+}
+
+
+DownloadView::~DownloadView()
+{
+}
+
+void DownloadView::updateItem(TorrentState const& info, ParamsMap_t other_info)
+{
+       DownloadItems_t::iterator p = items_.find(info.hash);
+       switch (info.action) {
+       case TorrentState::action_add :
+               if (p == items_.end()) {
+                       addItem_(info, other_info);
+               } else {
+                       qWarning() << "item with similar info hash marked as added";
+                       updateItem_(p.value(), info, other_info);
+               }
+               break;
+       case TorrentState::action_update :
+               if (p != items_.end()) {
+                       updateItem_(p.value(), info, other_info);
+               } else {
+                       qWarning() << "item does not exist in list but information update arrived";
+               }
+               break;
+       case TorrentState::action_remove :
+               if (p != items_.end()) {
+                       removeItem_(p.value(), info);
+               } else {
+                       qWarning() << "item removal request arrived but there is no such item";
+               }
+               break;
+       default:
+               qWarning() << "unknown action requested: " << info.action;
+               break;
+       }
+}
+
+void DownloadView::removeItem_(DownloadViewItem *item, TorrentState const& info)
+{
+       QString hash = item->getHash();
+
+       int removed = items_.remove(hash);
+       if (!removed)
+               qDebug() << "Inconsistent download view state on item removal";
+
+       int index = indexOfTopLevelItem(item);
+       if (index >= 0) {
+               takeTopLevelItem(index);
+       }
+}
+
+void DownloadView::addItem_(TorrentState const& info, ParamsMap_t)
+{
+       DownloadViewItem *item = new DownloadViewItem
+       ( info.hash,
+         QStringList()
+         << info.name
+         << formatSize(info.total_size)
+         << GetStatusString((TorrentStatus::Id)info.state)
+         << formatProgress(info.progress)
+         << formatSize(info.down_rate)
+         << formatSize(info.up_rate)
+         << QString::number(info.seeds) + "/" + QString::number(info.leeches)
+         << QString::number(info.ratio)
+         << "ETA" );
+
+       QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
+       item->setForeground(2, brushTmp);
+
+       addTopLevelItem(item);
+       items_[info.hash] = item;
+}
+
+
+void DownloadView::updateItem_(DownloadViewItem *item
+                               , TorrentState const& info, ParamsMap_t)
+{
+       item->setData(2, Qt::DisplayRole,
+                     QVariant(GetStatusString((TorrentStatus::Id)info.state)));
+       item->setData(3, Qt::DisplayRole,
+                     QVariant(formatProgress(info.progress)));
+       item->setData(4, Qt::DisplayRole,
+                     QVariant(formatSize(info.down_rate)));
+       item->setData(5, Qt::DisplayRole,
+                     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);
+}
+
+
+QString DownloadView::prepareRemoveSelected()
+{
+       qDebug() << "DownloadView::removeSelected() " <<  topLevelItemCount() ;
+
+       DownloadViewItem *item = dynamic_cast<DownloadViewItem*> (currentItem());
+       QString hash = item->getHash();
+
+       item->setDisabled(true);
+
+       qDebug() << "DownloadView::removeSelected() " <<  topLevelItemCount() ;
+
+       return hash;
+}
+
+
+void DownloadView::on_itemClicked(QTreeWidgetItem * , int)
+{
+       /*
+         qDebug() << "DownloadView::on_itemClicked(()" << item << "," << column;
+         qDebug() << "current item" << currentItem();
+
+         if (item == currentItem() && item->isSelected()) {
+         item->setSelected(false);
+         }
+       */
+}
+
+
+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) {
+               case TorrentStatus::QUEUED_FOR_CHECKING :
+                       return tr("Queued");
+               case TorrentStatus::CHECKING_FILES :
+                       return tr("Checking");
+               case TorrentStatus::DOWNLOADING_METADATA :
+                       return tr("DL meta");
+               case TorrentStatus::DOWNLOADING :
+                       return tr("Downloading");
+               case TorrentStatus::FINISHED :
+                       return tr("Finished");
+               case TorrentStatus::SEEDING :
+                       return tr("Seeding");
+               case TorrentStatus::ALLOCATING :
+                       return tr("Allocating");
+               case TorrentStatus::CHECKING_RESUME_DATA :
+                       return tr("Checking resume");
+               default:
+                       return tr("N/A");
+       }
+}
+
+
+QColor DownloadView::GetStatusColor(TorrentStatus::Id status)
+{
+       QColor green(40,205,40);
+       QColor yellow(255,174,0);
+
+       switch (status) {
+               case TorrentStatus::QUEUED_FOR_CHECKING :
+               case TorrentStatus::CHECKING_FILES :
+               case TorrentStatus::DOWNLOADING_METADATA :
+               case TorrentStatus::ALLOCATING :
+               case TorrentStatus::CHECKING_RESUME_DATA:
+                       return yellow;
+               case TorrentStatus::DOWNLOADING :
+               case TorrentStatus::FINISHED :
+               case TorrentStatus::SEEDING :
+                       return green;
+               default:
+                       return QColor();
+       }
+}
+
+} // namespace qtrapids
diff --git a/src/qml-client/DownloadView.h b/src/qml-client/DownloadView.h
new file mode 100644 (file)
index 0000000..4bac449
--- /dev/null
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 DOWNLOADVIEW_H
+#define DOWNLOADVIEW_H
+
+#include <map>
+#include <qtrapids/info.hpp>
+#include <qtrapids/dbus.hpp>
+
+#include <QTreeWidget>
+
+
+namespace qtrapids
+{
+
+class DownloadViewItem;
+
+typedef QHash<QString, DownloadViewItem*> DownloadItems_t;
+
+/**
+   @class DownloadView
+   @brief A view showing all downloaded torrents
+   @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+*/
+class DownloadView : public QTreeWidget
+{
+       Q_OBJECT
+
+public:
+       DownloadView(QWidget* parent);
+
+       ~DownloadView();
+
+       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);
+
+
+       static QString GetStatusString(TorrentStatus::Id status);
+       static QColor GetStatusColor(TorrentStatus::Id status);
+       
+};
+
+
+/**
+   @class DownloadViewItem
+   @brief Represents one item row of DownloadView
+*/
+class DownloadViewItem : public QTreeWidgetItem
+{
+
+public:
+       DownloadViewItem(QTreeWidget* parent, int type) :
+                       QTreeWidgetItem(parent, type = QTreeWidgetItem::UserType) {};
+
+       DownloadViewItem(QString hash, const QStringList& strings,
+                        int type = QTreeWidgetItem::UserType) :
+                       QTreeWidgetItem (strings, type = Type),
+                       hash_(hash) {}
+
+
+       /// @return An item comprising of string list, suitable for QTableView
+       /// header.
+       static DownloadViewItem *getHeaderItem() {
+               DownloadViewItem *item
+               = new DownloadViewItem("", QStringList()
+                                      << "Name"
+                                      << "Size" << "Status"
+                                      << "Progress" << "DL speed"
+                                      << "UL speed" << "Seeds/Leechers"
+                                      << "Ratio" << "ETA");
+
+               return item;
+       }
+
+       /// @todo QTorrentHandle as one hidden column
+
+       QString getHash() const {
+               return hash_;
+       }
+
+private:
+       QString hash_;
+};
+
+} // namespace qtrapids
+
+#endif // DOWNLOADVIEW_H
+
diff --git a/src/qml-client/MainWindow.cpp b/src/qml-client/MainWindow.cpp
new file mode 100644 (file)
index 0000000..551197a
--- /dev/null
@@ -0,0 +1,503 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <qtrapids/dbus.hpp>
+
+#include <QDebug>
+#include <QtGui/QMenuBar>
+#include <QtGui/QToolBar>
+#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"
+
+namespace qtrapids
+{
+
+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@gmail.com"
+                          "\n\nIxonos Plc, Finland\n"));
+
+const QString PLUGINS_DIR = "plugins";
+
+// Consturctor
+MainWindow::MainWindow() :
+               QMainWindow(), // Superclass
+               tabWidget_(NULL),
+               dlView_(NULL),
+               seedView_(NULL),
+               searchWidget_(NULL),
+               startDaemonAction_(NULL),
+               stopDaemonAction_(NULL),
+               preferencesDialog_(NULL),
+               settings_(QCoreApplication::organizationName()
+                         , QCoreApplication::applicationName()),
+               pluginDirs_(),
+               server_(QtRapidsServer::staticInterfaceName()
+                       , "/qtrapids", QDBusConnection::sessionBus())
+               //      torrentHandles_(),
+{
+       
+       setWindowTitle("QtRapids");
+       
+       // 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);
+       
+       startDaemonAction_ = tempMenu->addAction(tr("S&tart daemon"));
+       stopDaemonAction_ = tempMenu->addAction(tr("Sto&p daemon"));
+       startDaemonAction_->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"));
+
+       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()));
+       connect(this, SIGNAL(itemSelected(bool)), removeAction, SLOT(setEnabled(bool)));
+       connect(quitAction, SIGNAL(triggered()), this, SLOT(on_quitAction_clicked()));
+       connect(startDaemonAction_, SIGNAL(triggered()), this, SLOT(on_startDaemonAction_clicked()));
+       connect(stopDaemonAction_, SIGNAL(triggered()), this, SLOT(on_stopDaemonAction_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()));
+
+       // 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()));
+
+       //connect(seedView_, SIGNAL(itemSelectionChanged()), this,
+       //        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::BottomToolBarArea, toolBar);
+
+       connect(this, SIGNAL(itemSelected(bool)), removeAction,
+               SLOT(setEnabled(bool)));
+       connect(toolBar, SIGNAL(actionTriggered(QAction*)), this,
+               SLOT(handleToolBarAction(QAction*)));
+       connect (tabWidget_, SIGNAL(tabCloseRequested(int)), this, SLOT(on_tabWidget_tabCloseRequested(int)));
+
+       connect(&server_, SIGNAL(alert(qtrapids::TorrentState, qtrapids::ParamsMap_t)), 
+                                       this, SLOT(on_alert(qtrapids::TorrentState, qtrapids::ParamsMap_t)));
+       
+       connect(&server_, SIGNAL(sessionTerminated()), this, SLOT(on_serverTerminated()));
+       
+//     connect(&btSession_, SIGNAL(alert(std::auto_ptr<Alert>)),
+//             this, SLOT(on_alert(std::auto_ptr<Alert>)));
+
+
+       LoadPlugins();
+
+}
+
+
+MainWindow::~MainWindow()
+{
+       settings_.setValue("geometry", saveGeometry());
+}
+
+// ===================== 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<qtrapids::PluginInterface*>(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()
+{
+       
+       // Restore previous main window geometry:
+       QVariant geometry(settings_.value("geometry"));
+       if (!geometry.isNull()) {
+               qDebug() << "restoring geometry";
+               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();
+       options["net/uploadRate"] = settings_.value("net/uploadRate").toString();
+       server_.setOptions(options);
+}
+
+
+// Opens torrent information from buffer data and adds torrent to session 
+void MainWindow::StartTorrentFromBufferData(char const* data, int size)
+{
+
+}
+
+// =========================== PRIVATE SLOTS =================================
+void MainWindow::on_openAction_clicked()
+{
+       QString filename = QFileDialog::getOpenFileName( this, tr("Open torrent file"), QString(), tr("Torrent files (*.torrent)") );
+       on_torrentFileSelected(filename);
+       /*
+       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()
+{
+       QString hash = dlView_->prepareRemoveSelected();
+       try {
+               server_.removeTorrent(hash);
+       } catch (...) {
+               qDebug() << "Exception while removing torrent";
+       }
+}
+
+
+void MainWindow::on_quitAction_clicked()
+{
+       close();
+}
+
+
+void MainWindow::on_startDaemonAction_clicked()
+{
+       server_.getState();
+       /// @todo create signal that signals server startup and 
+       /// enable controls in the handler slot
+       stopDaemonAction_->setEnabled(true);
+       startDaemonAction_->setEnabled(false);
+}
+
+
+void MainWindow::on_stopDaemonAction_clicked()
+{
+       server_.terminateSession();
+}
+
+
+void MainWindow::on_serverTerminated()
+{
+       stopDaemonAction_->setEnabled(false);
+       startDaemonAction_->setEnabled(true);
+}
+
+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_) {
+               preferencesDialog_ = new PreferencesDialog(this, 0, &server_);
+       }
+
+       preferencesDialog_->show();
+       preferencesDialog_->raise();
+       preferencesDialog_->activateWindow();
+}
+
+
+void MainWindow::on_aboutAction_clicked()
+{
+       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
+       qDebug() << "MainWindow::on_seedItemSelectionChanged():" << dlView_->currentItem();
+#endif
+       if (dlView_->currentItem() != NULL) {
+               emit(itemSelected(true));
+       } else {
+               emit(itemSelected(false));
+       }
+}
+
+
+void MainWindow::on_seedItemSelectionChanged()
+{
+#ifdef QTRAPIDS_DEBUG
+       qDebug() << "MainWindow::on_seedItemSelectionChanged():" << seedView_->currentItem();
+#endif
+       if (seedView_->currentItem() != NULL) {
+               emit(itemSelected(true));
+       } else {
+               emit(itemSelected(false));
+       }
+}
+
+
+void MainWindow::handleToolBarAction(QAction* action)
+{
+       if (action->text() == "Open") {
+               on_openAction_clicked();
+       } else if (action->text() == "Remove") {
+               on_removeAction_clicked();
+       }
+}
+
+
+void MainWindow::on_torrentFileSelected(QString file)
+{
+#ifdef QTRAPIDS_DEBUG
+       qDebug() << " MainWindow::on_torrentFileSelected(): " << file;
+#endif
+       // Torrent filename empty, do nothing.
+       if (file == "") {
+               return;
+       }
+
+       // Otherwise add torrent
+       // For params, see: http://www.rasterbar.com/products/libtorrent/manual.html#add-torrent
+       // save_path is the only mandatory parameter, rest are optional.
+       //addParams.storage_mode = libtorrent::storage_mode_allocate;
+       try {
+               server_.addTorrent(file, settings_.value("download/directory").toString()
+                                  , ParamsMap_t());
+       } catch (...) {
+               qDebug() << "Exception adding torrent";
+       }
+}
+
+
+void MainWindow::on_alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info)
+{
+#ifdef QTRAPIDS_DEBUG
+       qDebug() << "got alert";
+#endif
+       dlView_->updateItem(info, other_info);
+}
+
+} // namespace qtrapids
diff --git a/src/qml-client/MainWindow.h b/src/qml-client/MainWindow.h
new file mode 100644 (file)
index 0000000..2b017b8
--- /dev/null
@@ -0,0 +1,125 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QSettings>
+
+#include "PluginInterface.h"
+#include "proxy.h"
+
+class QTabWidget;
+class DownloadView;
+class PreferencesDialog;
+
+namespace qtrapids
+{
+
+class SeedView;
+
+/**
+   @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+*/
+class MainWindow : public QMainWindow, public PluginHostInterface 
+{
+
+       Q_OBJECT;
+
+public:
+
+       MainWindow();
+       virtual ~MainWindow();
+
+       // Implemented from PluginHostInterface
+       virtual bool setGui(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE, qtrapids::PluginInterface* plugin = NULL);
+       virtual void addPluginWidget(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE);
+       virtual void addToolbar(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE);
+       virtual void addToolItem(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE);
+       virtual void addMenu(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE);
+       virtual void addMenuItem(QWidget* widget, PluginWidgetType type = UNKNOWN_TYPE);
+       virtual bool eventRequest(QVariant param, PluginRequest req = UNKNOWN_REQUEST);
+       
+       void RestoreSettings();
+
+       void connectToServer() {
+               qDBusRegisterMetaType<qtrapids::TorrentState>();
+               qDBusRegisterMetaType<qtrapids::ParamsMap_t>();
+
+               connect(&server_
+                       , SIGNAL(alert(qtrapids::TorrentState
+                                      , qtrapids::ParamsMap_t))
+                       , this
+                       , SLOT(on_alert(qtrapids::TorrentState
+                                    , qtrapids::ParamsMap_t)));
+               // Request server state. 
+               // NOTE: This call starts qtrapids-server automatically with the GUI, 
+               // if the .service file is in /usr/share/dbus-1/services/
+               server_.getState();
+       }
+
+signals:
+       void itemSelected(bool enabled);
+
+public slots:
+private slots:
+       void on_openAction_clicked();
+       void on_removeAction_clicked();
+       void on_quitAction_clicked();
+       void on_startDaemonAction_clicked();
+       void on_stopDaemonAction_clicked();
+       void on_serverTerminated();
+       void on_columnsAction_clicked();
+       void on_preferencesAction_clicked();
+       void on_aboutAction_clicked();
+       void on_aboutQtAction_clicked();
+       void on_tabWidget_tabCloseRequested(int index);
+       void on_downloadItemSelectionChanged();
+       void on_seedItemSelectionChanged();
+       void handleToolBarAction(QAction* action);
+       void on_torrentFileSelected(QString file);
+       void on_alert(qtrapids::TorrentState, qtrapids::ParamsMap_t);
+
+       
+private:
+       void LoadPlugins();
+       void StartTorrentFromBufferData(char const* data, int size);
+               
+private:
+       QTabWidget *tabWidget_;
+       DownloadView *dlView_;
+       SeedView *seedView_;
+       QWidget *searchWidget_;
+       QAction *startDaemonAction_, *stopDaemonAction_;
+       PreferencesDialog *preferencesDialog_;
+       QSettings settings_;
+       QList<QDir> pluginDirs_;
+       QStringList pluginFileNames_;
+
+
+       //std::vector< std::auto_ptr<QTorrentHandle> const > torrentHandles_;
+
+       QtRapidsServer server_;
+
+
+       //bool IsNewTorrent(std::auto_ptr<QTorrentHandle> handlePtr);
+};
+
+} // namespace qtrapids
+
+#endif
diff --git a/src/qml-client/PreferencesDialog.cpp b/src/qml-client/PreferencesDialog.cpp
new file mode 100644 (file)
index 0000000..4f6bbf1
--- /dev/null
@@ -0,0 +1,195 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <QDebug>
+#include <QBoxLayout>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QDialogButtonBox>
+#include <QAbstractButton>
+#include <QFileDialog>
+
+#include "qtrapids/dbus.hpp"
+#include "proxy.h"
+#include "PreferencesDialog.h"
+
+
+
+PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags f, QtRapidsServer *server) :
+               QDialog(parent, f), // Superclass
+               dirLineEdit_(NULL),
+               dialogButtons_(NULL),
+               uploadRateSpinBox_(NULL),
+               downloadRateSpinBox_(NULL),
+               server_(server),
+               settings_()
+{
+       setWindowTitle("Preferences");
+
+       QBoxLayout *verticalBox = new QBoxLayout(QBoxLayout::TopToBottom);
+       //QBoxLayout *horizontalBox1 = new QBoxLayout(QBoxLayout::LeftToRight);
+       QGridLayout *grid = new QGridLayout;
+       setLayout(verticalBox);
+       verticalBox->addLayout(grid);
+
+       QLabel *dirLabel = new QLabel(tr("Download directory: "));
+       dirLineEdit_ = new QLineEdit(this);
+       QPushButton *browseDirButton = new QPushButton(tr("Browse.."));
+       
+       QLabel *uploadLabel = new QLabel(tr("Max. upload rate: "));
+       QLabel *downloadLabel = new QLabel(tr("Max. download rate: "));
+       uploadRateSpinBox_ = new QSpinBox(this);
+       downloadRateSpinBox_ = new QSpinBox(this);
+       
+       grid->addWidget(dirLabel, 0, 0);
+       grid->addWidget(dirLineEdit_, 0, 1);
+       grid->addWidget(browseDirButton, 0, 2);
+       
+       grid->addWidget(uploadLabel, 1, 0);
+       grid->addWidget(uploadRateSpinBox_, 1, 1);
+       grid->addWidget(downloadLabel, 2, 0);
+       grid->addWidget(downloadRateSpinBox_, 2, 1);
+       
+       uploadRateSpinBox_->setRange(0, 1000);
+       uploadRateSpinBox_->setSuffix(" kB/s");
+       downloadRateSpinBox_->setRange(0, 1000);
+       downloadRateSpinBox_->setSuffix(" kB/s");
+       
+//     horizontalBox1->addWidget(dirLabel);
+//     horizontalBox1->addWidget(dirLineEdit_);
+//     horizontalBox1->addWidget(browseDirButton);
+
+       connect(browseDirButton, SIGNAL(clicked()),
+               this, SLOT(on_browseDirButtonClicked()));
+
+
+       dialogButtons_ = new QDialogButtonBox(this);
+       dialogButtons_->setStandardButtons(QDialogButtonBox::Ok
+                                          | QDialogButtonBox::Apply
+                                          | QDialogButtonBox::Cancel);
+
+       verticalBox->addWidget(dialogButtons_);
+
+       connect(dialogButtons_, SIGNAL(clicked(QAbstractButton*)),
+               this, SLOT(on_buttonClicked(QAbstractButton*)));
+
+       // Set saved preference values to fields.
+       ReadSettings();
+
+}
+
+
+PreferencesDialog::~PreferencesDialog()
+{
+}
+
+// ======================== SLOTS ========================
+void PreferencesDialog::on_browseDirButtonClicked()
+{
+       QString dir = QFileDialog::getExistingDirectory(this, tr("Download directory"), QString(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+       on_downloadDirectorySelected(dir);
+       
+       /*
+       QFileDialog *dialog
+       = new QFileDialog(this, "Download directory",
+                         QString(), tr("Torrent files (*.torrent)"));
+
+       dialog->setFileMode(QFileDialog::Directory);
+       dialog->setOption(QFileDialog::ShowDirsOnly, true);
+
+       connect(dialog, SIGNAL(fileSelected(const QString&)),
+               this, SLOT(on_downloadDirectorySelected(const QString&)));
+
+       dialog->show();
+       */
+}
+
+void PreferencesDialog::on_buttonClicked(QAbstractButton* button)
+{
+       switch (dialogButtons_->buttonRole ( button ) ) {
+       case QDialogButtonBox::AcceptRole :
+               qDebug() << "PreferencesDialog: OK";
+               WriteSettings();
+               done(QDialog::Accepted);
+               break;
+       case QDialogButtonBox::ApplyRole :
+               qDebug() << "PreferencesDialog: APPLY";
+               WriteSettings();
+               break;
+       case QDialogButtonBox::RejectRole :
+               qDebug() << "PreferencesDialog: CANCEL";
+               done(QDialog::Rejected);
+               break;
+       default:
+               return;
+       }
+}
+
+void PreferencesDialog::on_downloadDirectorySelected(QString directory)
+{
+       qDebug() << "PreferencesDialog::on_downloadDirectorySelected(): " << directory;
+       // Torrent filename empty, do nothing.
+       if (directory == "")
+               return;
+
+       dirLineEdit_->clear();
+       dirLineEdit_->insert(directory);
+
+       /// @todo check that user has privileges to write to this directory.
+}
+
+
+// ========================= Private functions ==========================
+void PreferencesDialog::WriteSettings()
+{
+       int ulRate = 1000*uploadRateSpinBox_->value();
+       int dlRate = 1000*downloadRateSpinBox_->value();
+       
+       settings_.setValue("download/directory", dirLineEdit_->text());
+       //settings_.setValue("net/uploadRate", ulRate);
+       //settings_.setValue("net/downloadRate", dlRate);
+       
+       // NOTE: We might need to call QSettigns::sync() here to instantly write settings.
+       // settings are written also by QSettings() destructor and by event loop at regular interval.
+       
+       // If server pointer was given, apply settings immediately.
+       if (server_) {
+               /// @todo Use DBus interface
+               /// @todo Set parameters for server
+               /// @todo Add speedlimit functionality to Server.
+               qtrapids::ParamsMap_t options;
+               options["net/downloadRate"] = QString::number(dlRate);
+               options["net/uploadRate"] = QString::number(ulRate);
+               server_->setOptions(options);
+//             btSession_->setUploadRateLimit(ulRate);
+//             btSession_->setDownloadRateLimit(dlRate);
+       }
+       
+}
+
+void PreferencesDialog::ReadSettings()
+{
+       dirLineEdit_->insert(settings_.value("download/directory").toString());
+       uploadRateSpinBox_->setValue(settings_.value("net/uploadRate").toInt()/1000);
+       downloadRateSpinBox_->setValue(settings_.value("net/downloadRate").toInt()/1000);
+       
+       // NOTE: We might need to call QSettigns::sync() here to instantly write settings.
+       // settings are written also by QSettings() destructor and by event loop at regular interval.
+}
+
diff --git a/src/qml-client/PreferencesDialog.h b/src/qml-client/PreferencesDialog.h
new file mode 100644 (file)
index 0000000..c667034
--- /dev/null
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QDialog>
+#include <QSettings>
+
+
+class QAbstractButton;
+class QLineEdit;
+class QSpinBox;
+class QDialogButtonBox;
+
+class QtRapidsServer;
+
+
+/**
+       @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+*/
+class PreferencesDialog : public QDialog
+{
+
+       Q_OBJECT
+
+public:
+       PreferencesDialog(QWidget* parent = 0, Qt::WindowFlags f = 0, QtRapidsServer *server = 0);
+
+       ~PreferencesDialog();
+
+private slots:
+       void on_browseDirButtonClicked();
+       void on_buttonClicked(QAbstractButton* button);
+       void on_downloadDirectorySelected(QString directory);
+
+private:
+       QLineEdit *dirLineEdit_;
+       QDialogButtonBox *dialogButtons_;
+       QSpinBox *uploadRateSpinBox_, *downloadRateSpinBox_;
+       
+       QtRapidsServer *server_;
+
+       QSettings settings_;
+
+private:
+       // Private functions:
+       void WriteSettings();
+       void ReadSettings();
+};
+
+#endif
diff --git a/src/qml-client/SeedView.cpp b/src/qml-client/SeedView.cpp
new file mode 100644 (file)
index 0000000..2fd3a65
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 "SeedView.h"
+
+#include <QDebug>
+
+namespace qtrapids
+{
+
+SeedView::SeedView(QWidget* parent):
+               QTreeWidget(parent)
+{
+       setRootIsDecorated(false); // Hide branch lines, making one-level treeview (similar to list)
+       setHeaderItem(SeedViewItem::getHeaderItem());
+
+       connect(this, SIGNAL(itemPressed(QTreeWidgetItem*, int)),
+               this, SLOT(on_itemPressed(QTreeWidgetItem*, int)));
+}
+
+
+SeedView::~SeedView()
+{
+}
+
+void SeedView::on_itemPressed(QTreeWidgetItem * item, int column)
+{
+       qDebug() << "SeedView::on_itemPressed() " << item << "," << column;
+}
+
+} // namespace qtrapids
diff --git a/src/qml-client/SeedView.h b/src/qml-client/SeedView.h
new file mode 100644 (file)
index 0000000..bc6988a
--- /dev/null
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 SEEDVIEW_H
+#define SEEDVIEW_H
+
+#include <QTreeWidget>
+
+namespace qtrapids
+{
+
+class TorrentHandle;
+class SeedViewItem;
+
+/**
+   @author Lassi Väätämöinen <lassi.vaatamoinen@ixonos.com>
+*/
+class SeedView : public QTreeWidget
+{
+       Q_OBJECT
+public:
+       SeedView(QWidget* parent);
+
+       ~SeedView();
+
+private slots:
+       void on_itemPressed(QTreeWidgetItem *item, int column);
+
+private:
+
+       // Name
+       // Size
+       // Status
+       // UP speed
+       // Seeds/Leechers
+       // Connected peers
+       // total uploaded
+       // ratio
+};
+
+/**
+   @class DownloadViewItem
+   @brief Represents one item row of DownloadView
+*/
+class SeedViewItem : public QTreeWidgetItem
+{
+
+public:
+
+       SeedViewItem(QTreeWidget* parent, int type) :
+                       QTreeWidgetItem(parent, type = QTreeWidgetItem::UserType) {};
+
+       SeedViewItem(const QStringList& strings, int type = QTreeWidgetItem::UserType ) :
+                       QTreeWidgetItem (strings, type = Type) {};
+
+
+       /// @return An item comprising of string list, suitable for QTableView
+       /// header.
+       static SeedViewItem *getHeaderItem() {
+               SeedViewItem *item
+               = new SeedViewItem(QStringList()
+                                  << "Name"
+                                  << "Size" << "Status"
+                                  << "Progress" << "UL speed" << "Seeds/Leechers"
+                                  << "Conn. peers"
+                                  << "Ratio");
+
+               return item;
+       }
+
+       /// @todo TorrentHandle as one hidden column
+};
+
+} // namespace qtrapids
+
+#endif
diff --git a/src/qml-client/main.cpp b/src/qml-client/main.cpp
new file mode 100644 (file)
index 0000000..9d992b8
--- /dev/null
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <QApplication>
+#include <QtDeclarative>
+#include <QDeclarativeContext>
+#include <QTest>
+#include <QDebug>
+//#include <QDesktopWidget>
+//#include "DownloadView.h"
+#include <QtDeclarative/qdeclarative.h>
+#include "models/QDeclarativeDownloadListModel.h"
+
+#include "MainWindow.h"
+#include "../include/qtrapids/dbus.hpp"
+
+using qtrapids::MainWindow;
+
+int main(int argc, char *argv[])
+{
+
+
+
+    QCoreApplication::setOrganizationName("Ixonos");
+    QCoreApplication::setOrganizationDomain("ixonos.com");
+    QCoreApplication::setApplicationName("QtRapids");
+
+    // Q_INIT_RESOURCE(application);
+    QApplication app(argc, argv);
+    //MainWindow mainWindow;
+    app.setProperty("NoMStyle", true);
+    
+    // Register our types:
+    qmlRegisterType<qtrapids::QDeclarativeDownloadListModel>("QtRapids", 1, 0, "DownloadListModel");
+
+    QDir::setCurrent(app.applicationDirPath());
+
+    QDeclarativeView window;
+    //QDeclarativeEngine engine;
+    qtrapids::QDeclarativeDownloadListModel downloadModel;
+    QDeclarativeContext *context = window.rootContext();
+    context->setContextProperty("downloadModel", &downloadModel);
+    window.setSource(QUrl("qrc:/main.qml"));
+
+    window.showFullScreen();
+//    window.show();
+
+
+    /* TODO: Enable this once we have the views up & running
+    QDBusConnection dbus = QDBusConnection::sessionBus();
+    dbus.registerObject("/qtrapids_gui", &mainWindow);
+    dbus.registerService("com.ixonos.qtrapids_gui");
+
+    mainWindow.connectToServer();
+    mainWindow.RestoreSettings();
+
+    // mainWindow->setGeometry(QApplication::desktop()->screenGeometry());
+
+    mainWindow.show();
+    */
+    /*
+    DownloadView* dlw = new DownloadView(NULL);
+      //qtrapids * mw = new qtrapids();
+    dlw->show();
+    DownloadViewItem* dlwItem = new DownloadViewItem(QStringList() << "Name"
+                << "Size" << "Status"
+                << "Progress" << "DL speed"
+                << "UL speed" << "Seeds/Leechers"
+                << "ratio");
+    DownloadViewItem* dlwItem2 = new DownloadViewItem(QStringList() << "Name"
+                << "1000" << "Downloading"
+                << "23%" << "11"
+                << "0.1" << "0/2"
+                << "1.10");
+    //dlwItem->insertChild(0, new DownloadViewItem(QStringList() << "Name"));
+    dlw->insertTopLevelItem(0,dlwItem);
+    dlw->insertTopLevelItem(1,dlwItem2);
+
+    for (unsigned i = 0; i < 10; ++i)
+    {
+        DownloadViewItem *editItem = dynamic_cast<DownloadViewItem*>
+                        (dlw->itemAt(QPoint(0,0)));
+        editItem->setData ( 8, Qt::DisplayRole, QVariant("EDITED" + QString::number(i, 'g', 2)));
+        QTest::qSleep(2000);
+    }
+    */
+
+    qtrapids::TorrentState editItem;
+    for (unsigned i = 0; i < 10; ++i)
+    {
+        editItem.hash = QString("asdfasdfasdfasdfasfsd-") + QString::number(i);
+        editItem.name = QString("Lassi-") + QString::number(i);
+        editItem.action = qtrapids::TorrentState::action_add;
+        editItem.state = 0;
+        editItem.progress = 10+i;
+        editItem.down_rate = 10+i;
+        editItem.up_rate = 10+i;
+        editItem.seeds = 10+i;
+        editItem.leeches = 10+i;
+        editItem.ratio = 10+i;
+        editItem.total_size = 100000+i;
+        editItem.total_done = 10000+i;
+        downloadModel.updateItem(editItem, qtrapids::ParamsMap_t());
+    }
+
+    return app.exec();
+}
diff --git a/src/qml-client/models/Plugin.cpp b/src/qml-client/models/Plugin.cpp
new file mode 100644 (file)
index 0000000..a6c6165
--- /dev/null
@@ -0,0 +1,19 @@
+#include <QObject>
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+
+// This class is needed to make DownloadListModel class available to QML:
+class QmlDownloadListModelPlugin : public QDeclarativeExtensionPlugin
+{
+    Q_OBJECT
+public:
+    virtual void registerTypes(const char *uri)
+    {
+        Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.downloadlistmodel"));
+        qmlRegisterType<qtrapids::QDeclarativeDownloadListModel>(uri, 1, 0, "DownloadListModel");
+    }
+};
+
+#include "moc_Plugin.cxx"
+
+Q_EXPORT_PLUGIN2(downloadlistmodelplugin, QT_PREPEND_NAMESPACE(QmlDownloadListModelPlugin));
\ No newline at end of file
diff --git a/src/qml-client/models/Plugin.h b/src/qml-client/models/Plugin.h
new file mode 100644 (file)
index 0000000..129970c
--- /dev/null
@@ -0,0 +1,18 @@
+#include <QtDeclarative/qdeclarativeextensionplugin.h>
+#include <QtDeclarative/qdeclarative.h>
+
+#include "QDeclarativeDownloadListModel.h"
+
+// This class is needed to make DownloadListModel class available to QML:
+class QmlDownloadListModelPlugin : public QDeclarativeExtensionPlugin
+{
+    Q_OBJECT
+public:
+    virtual void registerTypes(const char *uri)
+    {
+        Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.downloadlistmodel"));
+        qmlRegisterType<qtrapids::QDeclarativeDownloadListModel>(uri, 1, 0, "DownloadListModel");
+    }
+};
+
+Q_EXPORT_PLUGIN2(downloadlistmodelplugin, QT_PREPEND_NAMESPACE(QmlDownloadListModelPlugin));
\ No newline at end of file
diff --git a/src/qml-client/models/QDeclarativeDownloadListModel.cpp b/src/qml-client/models/QDeclarativeDownloadListModel.cpp
new file mode 100644 (file)
index 0000000..e990705
--- /dev/null
@@ -0,0 +1,304 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 <QtCore/QVariant>
+#include <QtCore/QDebug>
+
+#include "QDeclarativeDownloadListModel.h"
+#include "QDeclarativeDownloadListModel_p.h"
+#include "qtrapids/format.hpp"
+
+namespace qtrapids
+{
+
+QDeclarativeDownloadListModel::QDeclarativeDownloadListModel(QObject *parent):
+        QAbstractListModel(parent)
+{
+    d = new QDeclarativeDownloadListModelPrivate;
+
+    // These roles are the names that we use to access the model data on QML
+    // in the string format. So, use the value on the right-hand side of assignment operator in QML.
+    // The role enum value is passed from QML side to the C++ model for fetching the data.
+    QHash<int, QByteArray> roles;
+    roles[DownloadRole] = "download";
+    roles[SeedRole] = "seed";
+    roles[HashRole] = "hash";
+    roles[NameRole] = "name";
+    roles[SizeRole] = "size";
+    roles[StatusRole] = "status";
+    roles[StateRole] = "state";
+    roles[ProgressRole] = "progress";
+    roles[DownRateRole] = "downRate";
+    roles[UpRateRole] = "upRate";
+    roles[SeedsRole] = "seeds";
+    roles[LeechesRole] = "leeches";
+    roles[RatioRole] = "ratio";
+    roles[TotaSizeRole] = "totalSize";
+    roles[TotalDoneRole] = "totalDone";
+    setRoleNames(roles);
+}
+
+QDeclarativeDownloadListModel::~QDeclarativeDownloadListModel()
+{
+}
+
+
+void
+QDeclarativeDownloadListModel::updateItem(TorrentState const& info,
+                                          ParamsMap_t other_info)
+{
+    qDebug() << Q_FUNC_INFO << " enter";
+
+    DownloadItems_t::iterator p = d->items_.find(info.hash);
+    switch (info.action) {
+        case TorrentState::action_add :
+            if (p == d->items_.end()) {
+                addItem_(info, other_info);
+            } else {
+                qWarning() << "item with similar info hash marked as added";
+                updateItem_(info, other_info);
+            }
+            break;
+        case TorrentState::action_update :
+            if (p != d->items_.end()) {
+                updateItem_(info, other_info);
+            } else {
+                qWarning() << "item does not exist in list but information update arrived";
+            }
+            break;
+        case TorrentState::action_remove :
+            if (p != d->items_.end()) {
+                removeItem_(info);
+            } else {
+                qWarning() << "item removal request arrived but there is no such item";
+            }
+            break;
+        default:
+            qWarning() << "unknown action requested: " << info.action;
+            break;
+    }
+}
+
+
+    // Returns the hash of the torrent be removed.
+QString QDeclarativeDownloadListModel::prepareRemoveSelected()
+{
+    return "DUMMY_HASH";
+}
+
+int QDeclarativeDownloadListModel::rowCount(const QModelIndex &parent) const
+{
+    return d->items_.count();
+}
+
+QVariant QDeclarativeDownloadListModel::data(const QModelIndex &index, int role) const
+{
+
+    qDebug() << Q_FUNC_INFO << " enter";
+    int rowIndex = index.row();
+    QString hash;
+    TorrentState item;
+
+    // Get the item hash corresponding to row number:
+    if (d->itemIndexes_.contains(rowIndex))
+        hash = d->itemIndexes_[rowIndex];
+    else
+        return QVariant();
+
+    // Get the torrent info for the hash:
+    if (d->items_.contains(hash))
+        item = d->items_[hash];
+    else 
+        return QVariant();
+
+    switch (role) {
+//         case DownloadRole:
+//             // TODO: What to do here??
+//             break;
+//         case SeedRole:
+//             // TODO: What to do here??
+//             break;
+        case HashRole:
+            return QVariant(item.hash);
+        case NameRole:
+            return QVariant(item.name);
+//         case SizeRole:
+//             return QVariant(item.total_size);
+        case StatusRole:
+            return QVariant();
+        case StateRole:
+            return QVariant(item.state);
+        case ProgressRole:
+            return QVariant(item.progress);
+        case DownRateRole:
+            return QVariant(item.down_rate);
+        case UpRateRole:
+            return QVariant(item.up_rate);
+        case SeedsRole:
+            return QVariant(item.seeds);
+        case LeechesRole:
+            return QVariant(item.leeches);
+        case RatioRole:
+            return QVariant(item.ratio);
+        case TotaSizeRole:
+            return QVariant(item.total_size);
+        case TotalDoneRole:
+            return QVariant(item.total_done);
+        default:
+            qWarning() << Q_FUNC_INFO << "Unknown role requested from model";
+            return QVariant();
+    }
+    return QVariant();
+}
+
+bool QDeclarativeDownloadListModel::insertRow(int row, const QModelIndex &parent)
+{
+    qDebug() << "QDeclarativeDownloadListModel::insertRow()";
+    return false;
+}
+
+bool QDeclarativeDownloadListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    qDebug() << "QDeclarativeDownloadListModel::setData()";
+    return false;
+}
+
+
+void QDeclarativeDownloadListModel::classBegin()
+{
+    qDebug() << "QDeclarativeDownloadListModel::classBegin()";
+}
+
+void QDeclarativeDownloadListModel::componentComplete()
+{
+    qDebug() << "QDeclarativeDownloadListModel::componentComplete()";
+}
+
+
+void QDeclarativeDownloadListModel::removeItem_(TorrentState const& info)
+{
+    qDebug() << Q_FUNC_INFO << " enter";
+    QString hash = info.hash;
+
+    // TODO: Emit rows remove start
+    int removed = d->items_.remove(hash);
+    // TODO: Edit rows insert end
+    if (!removed)
+        qDebug() << "Inconsistent download view state on item removal";
+
+    /*
+    int index = indexOfTopLevelItem(item);
+    if (index >= 0) {
+            takeTopLevelItem(index);
+    }
+    */
+}
+
+void QDeclarativeDownloadListModel::addItem_(TorrentState const& info,
+                                             ParamsMap_t)
+{
+     qDebug() << Q_FUNC_INFO << " enter";
+/*
+    DownloadViewItem *item = new DownloadViewItem
+    ( info.hash,
+      QStringList()
+      << info.name
+      << formatSize(info.total_size)
+      << GetStatusString((TorrentStatus::Id)info.state)
+      << formatProgress(info.progress)
+      << formatSize(info.down_rate)
+      << formatSize(info.up_rate)
+      << QString::number(info.seeds) + "/" + QString::number(info.leeches)
+      << QString::number(info.ratio)
+      << "ETA" );
+
+    QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
+    item->setForeground(2, brushTmp);
+
+    addTopLevelItem(item);
+    */
+
+    int itemsCount = d->items_.count();
+    beginInsertRows(QModelIndex(), itemsCount, itemsCount+1);
+    d->items_[info.hash] = info;
+    d->itemIndexes_[itemsCount+1] = info.hash;
+    endInsertRows();
+}
+
+
+void QDeclarativeDownloadListModel::updateItem_(TorrentState const& info, ParamsMap_t)
+{
+     qDebug() << Q_FUNC_INFO << " enter";
+    /*
+    item->setData(2, Qt::DisplayRole,
+                  QVariant(GetStatusString((TorrentStatus::Id)info.state)));
+    item->setData(3, Qt::DisplayRole,
+                  QVariant(formatProgress(info.progress)));
+    item->setData(4, Qt::DisplayRole,
+                  QVariant(formatSize(info.down_rate)));
+    item->setData(5, Qt::DisplayRole,
+                  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");
+    }
+*/
+    // TODO: Update items data & Emit data changed.
+
+/*
+    // Set color for status text
+    QBrush brushTmp(GetStatusColor((TorrentStatus::Id)info.state));
+    item->setForeground(2, brushTmp);
+    */
+}
+
+
+
+QString QDeclarativeDownloadListModel::GetStatusString(TorrentStatus::Id status)
+{
+    qDebug() << Q_FUNC_INFO << " enter";
+    switch (status) {
+        case TorrentStatus::QUEUED_FOR_CHECKING :
+            return tr("Queued");
+        case TorrentStatus::CHECKING_FILES :
+            return tr("Checking");
+        case TorrentStatus::DOWNLOADING_METADATA :
+            return tr("DL meta");
+        case TorrentStatus::DOWNLOADING :
+            return tr("Downloading");
+        case TorrentStatus::FINISHED :
+            return tr("Finished");
+        case TorrentStatus::SEEDING :
+            return tr("Seeding");
+        case TorrentStatus::ALLOCATING :
+            return tr("Allocating");
+        case TorrentStatus::CHECKING_RESUME_DATA :
+            return tr("Checking resume");
+        default:
+            return tr("N/A");
+    }
+}
+
+} // namespace qtrapids
diff --git a/src/qml-client/models/QDeclarativeDownloadListModel.h b/src/qml-client/models/QDeclarativeDownloadListModel.h
new file mode 100644 (file)
index 0000000..ee9cadd
--- /dev/null
@@ -0,0 +1,129 @@
+/***************************************************************************
+ *   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; 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        *
+ *   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 QDECLARATIVEDOWNLOADLISTMODEL_H
+#define QDECLARATIVEDOWNLOADLISTMODEL_H
+
+
+#include <QDeclarativeParserStatus>
+#include <QAbstractListModel>
+#include <QtDeclarative>
+#include <QModelIndex>
+
+#include "qtrapids/dbus.hpp"
+#include "qtrapids/info.hpp"
+
+//#include "../DownloadView.h"
+
+QT_MODULE(Declarative);
+
+namespace qtrapids
+{
+
+typedef QHash<QString, TorrentState> DownloadItems_t;
+typedef QMap<int, QString> ItemIndex_t;
+
+class QDeclarativeContext;
+class QDeclarativeDownloadListModelPrivate;
+
+class QDeclarativeDownloadListModel :
+            public QAbstractListModel, public QDeclarativeParserStatus
+{
+    Q_OBJECT
+    Q_INTERFACES(QDeclarativeParserStatus);
+
+    /*
+    Q_PROPERTY(QString hash READ hash);
+    Q_PROPERTY(QString name READ name WRITE setName);
+    Q_PROPERTY(QString size READ size);
+    Q_PROPERTY(QString status READ status);
+    Q_PROPERTY(uint state READ state);
+    Q_PROPERTY(uint progress READ progress);
+    Q_PROPERTY(uint downRate READ downRate);
+    Q_PROPERTY(uint upRate READ upRate);
+    Q_PROPERTY(uint seeds READ seeds);
+    Q_PROPERTY(uint leeches READ leeches);
+    Q_PROPERTY(qulonglong ratio READ ratio);
+    Q_PROPERTY(qulonglong totaSize READ totalDone);
+    Q_PROPERTY(qulonglong totalDone READ totalDone);
+*/
+
+public:
+    QDeclarativeDownloadListModel(QObject *parent = 0);
+    virtual ~QDeclarativeDownloadListModel();
+
+    // TODO: Learn to use roles..
+    enum Roles {
+        DownloadRole = Qt::UserRole + 1, 
+        SeedRole,
+        HashRole,
+        NameRole,
+        SizeRole,
+        StatusRole,
+        StateRole,
+        ProgressRole,
+        DownRateRole,
+        UpRateRole,
+        SeedsRole,
+        LeechesRole,
+        RatioRole,
+        TotaSizeRole,
+        TotalDoneRole
+    };
+
+    // Updates the torrent status in the model.
+    void updateItem(TorrentState const& info, ParamsMap_t other_info);
+    // Returns the hash of the torrent be removed.
+    QString prepareRemoveSelected();
+
+    // -- QAbstractListModel
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QVariant data(const QModelIndex &index, int role) const;
+    virtual bool insertRow(int row, const QModelIndex &parent);
+    virtual bool setData (const QModelIndex & index, const QVariant &value, int role = Qt::EditRole);
+    // -- End QAbstractListModel
+
+    // -- Overrides from QDeclarativeParserStatus
+    virtual void classBegin();
+    virtual void componentComplete();
+    // -- End QDeclarativeParserStatus
+
+Q_SIGNALS:
+    void downloadItemChanged(QString hash);
+
+// Private functions.
+private:
+    Q_DISABLE_COPY(QDeclarativeDownloadListModel)
+    QDeclarativeDownloadListModelPrivate *d;
+
+    void addItem_(TorrentState const& info, ParamsMap_t other_info);
+    void updateItem_(TorrentState const& info, ParamsMap_t other_info);
+    void removeItem_(TorrentState const& info);
+    QString GetStatusString(TorrentStatus::Id status);
+private:
+
+};
+
+
+} // namespace qtrapids
+
+// We need to declare the type
+QML_DECLARE_TYPE(qtrapids::QDeclarativeDownloadListModel);
+
+
+
+#endif
diff --git a/src/qml-client/models/QDeclarativeDownloadListModel_p.h b/src/qml-client/models/QDeclarativeDownloadListModel_p.h
new file mode 100644 (file)
index 0000000..6c4b699
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef QDECLARATIVEDOWNLOADLISTMODELPRIVATE_H
+#define QDECLARATIVEDOWNLOADLISTMODELPRIVATE_H
+
+#include <QModelIndex>
+
+#include "QDeclarativeDownloadListModel.h" // TODO: For DownloadItems_t, move that to common place..
+
+namespace qtrapids
+{
+
+class QDeclarativeDownloadListModelPrivate : QObject
+{
+    Q_OBJECT
+public:
+    QDeclarativeDownloadListModelPrivate()
+    {
+    }
+
+    DownloadItems_t items_;
+    ItemIndex_t itemIndexes_;
+    //QModelIndex downloadIndex_;
+
+signals:
+    void itemAdded(QString hash);
+    void itemRemoved(QString hash);
+
+};
+} // namespace qtrapids
+
+#endif
diff --git a/src/qml-client/models/qmldir b/src/qml-client/models/qmldir
new file mode 100644 (file)
index 0000000..9e05264
--- /dev/null
@@ -0,0 +1 @@
+plugin qmlfolderlistmodelplugin
\ No newline at end of file
diff --git a/src/qml-client/proxy.cpp b/src/qml-client/proxy.cpp
new file mode 100644 (file)
index 0000000..2c0c20c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -a server -c QtRapidsServer -i qtrapids/dbus.hpp -p proxy /home/lassi/Projects/qtrapids/trunk/dbus/com.ixonos.qtrapids.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * This file may have been hand-edited. Look for HAND-EDIT comments
+ * before re-generating it.
+ */
+
+#include "proxy.h"
+
+/*
+ * Implementation of interface class QtRapidsServer
+ */
+
+QtRapidsServer::QtRapidsServer(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+    : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QtRapidsServer::~QtRapidsServer()
+{
+}
+
diff --git a/src/qml-client/proxy.h b/src/qml-client/proxy.h
new file mode 100644 (file)
index 0000000..6690149
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * This file was generated by qdbusxml2cpp version 0.7
+ * Command line was: qdbusxml2cpp -a server -c QtRapidsServer -i qtrapids/dbus.hpp -p proxy /home/lassi/Projects/qtrapids/trunk/dbus/com.ixonos.qtrapids.xml
+ *
+ * qdbusxml2cpp is Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This is an auto-generated file.
+ * Do not edit! All changes made to it will be lost.
+ */
+
+#ifndef PROXY_H_1327258740
+#define PROXY_H_1327258740
+
+#include <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtDBus/QtDBus>
+#include "qtrapids/dbus.hpp"
+
+/*
+ * Proxy class for interface com.ixonos.qtrapids
+ */
+class QtRapidsServer: public QDBusAbstractInterface
+{
+    Q_OBJECT
+public:
+    static inline const char *staticInterfaceName()
+    { return "com.ixonos.qtrapids"; }
+
+public:
+    QtRapidsServer(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
+
+    ~QtRapidsServer();
+
+public Q_SLOTS: // METHODS
+    inline QDBusPendingReply<> addTorrent(const QString &path, const QString &save_path, qtrapids::ParamsMap_t other_params)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(path) << qVariantFromValue(save_path) << qVariantFromValue(other_params);
+        return asyncCallWithArgumentList(QLatin1String("addTorrent"), argumentList);
+    }
+
+    inline QDBusPendingReply<qtrapids::ParamsMap_t> getOptions()
+    {
+        QList<QVariant> argumentList;
+        return asyncCallWithArgumentList(QLatin1String("getOptions"), argumentList);
+    }
+
+    inline QDBusPendingReply<> getState()
+    {
+        QList<QVariant> argumentList;
+        return asyncCallWithArgumentList(QLatin1String("getState"), argumentList);
+    }
+
+    inline QDBusPendingReply<> removeTorrent(const QString &hash)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(hash);
+        return asyncCallWithArgumentList(QLatin1String("removeTorrent"), argumentList);
+    }
+
+    inline QDBusPendingReply<> setOptions(qtrapids::ParamsMap_t options)
+    {
+        QList<QVariant> argumentList;
+        argumentList << qVariantFromValue(options);
+        return asyncCallWithArgumentList(QLatin1String("setOptions"), argumentList);
+    }
+
+    inline QDBusPendingReply<> terminateSession()
+    {
+        QList<QVariant> argumentList;
+        return asyncCallWithArgumentList(QLatin1String("terminateSession"), argumentList);
+    }
+
+Q_SIGNALS: // SIGNALS
+    void alert(qtrapids::TorrentState info, qtrapids::ParamsMap_t other_info);
+    void sessionTerminated();
+    void terminate();
+};
+
+namespace com {
+  namespace ixonos {
+    typedef ::QtRapidsServer qtrapids;
+  }
+}
+#endif
diff --git a/src/qml-client/qml/DownloadView.qml b/src/qml-client/qml/DownloadView.qml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/qml-client/qml/MainPage.qml b/src/qml-client/qml/MainPage.qml
new file mode 100644 (file)
index 0000000..a189bab
--- /dev/null
@@ -0,0 +1,177 @@
+import QtQuick 1.1
+import Qt.labs.components 1.0
+import com.nokia.meego 1.0
+import com.meego 1.0
+import com.nokia.extras 1.0
+
+import QtRapids 1.0
+
+Page {
+    id: tabbarPage
+
+    property bool busy: Boolean(tabGroup.currentTab.busy)
+    anchors.margins: rootWindow.pageMargin
+
+    tools: ToolBarLayout {
+        ToolIcon { iconId: "toolbar-back"; onClicked: pageStack.pop(); }
+        ButtonRow {
+            platformStyle: TabButtonStyle { }
+            TabButton {
+                text: "Downloads"
+                tab: downloads
+            }
+            TabButton {
+                text: "Seeds"
+                tab: seeds
+            }
+        }
+        ToolIcon { iconId: "toolbar-view-menu"; onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close() }
+    }
+//  Text {
+//      text: "Hello World!"
+//      font.family: "Helvetica"
+//      font.pointSize: 24
+//      color: "red"
+//     anchors.fill: parent
+//  }
+
+    ListView {
+        width: 200; height: 400
+/*
+        DownloadListModel {
+            id: downloadModel
+            // TODO: Does not work like this. Need properties to set from QML?
+            // Try setting test data from C++ side and view here..
+            /*
+            ListElement {
+                Hash: "QMLHASH1"
+                Size: "Size1"
+                Status: "DONE1"
+            }
+            ListElement {
+                Hash: "QMLHASH2"
+                Size: "Size2"
+                Status: "DONE2"
+            }
+            ListElement {
+                Hash: "QMLHASH3"
+                Size: "Size3"
+                Status: "DONE3"
+            }
+        }
+*/
+        Component {
+            id: downloadDelegate
+            Item {
+                height: 40
+                width: parent.width
+                Text {
+                    id: hashText
+                    text: hash
+                }
+                Text {
+                    id: nameText
+                    anchors.leftMargin: 10
+                    anchors.left: hashText.right
+                    text: name
+                }
+                Text {
+                    id: seedsText
+                    anchors.leftMargin: 10
+                    anchors.left: nameText.right
+                    text: seeds
+                }
+                Text {
+                    id: leechesText
+                    anchors.leftMargin: 10
+                    anchors.left: seedsText.right
+                    text: leeches
+                }
+            }
+        }
+
+        // downloadModel is from rootContext, set in main.cpp
+        model: downloadModel
+        delegate: downloadDelegate
+    }
+
+    /*
+    ListModel {
+        id: pagesModel
+        ListElement {
+            page: "CountBubble.qml"
+            title: "CountBubble"
+            subtitle: "Indicates current count"
+        }
+        ListElement {
+            page: "NetPromoterScore.qml"
+            title: "NetPromoterScore"
+            subtitle: "Shows net promotion query page"
+        }
+        ListElement {
+            page: "PageIndicator.qml"
+            title: "PageIndicator"
+            subtitle: "Indicates total & current pages"
+        }
+        ListElement {
+            page: "RatingIndicator.qml"
+            title: "RatingIndicator"
+            subtitle: "Indicates ratings"
+        }
+        ListElement {
+            page: "ListDelegates.qml"
+            title: "List Delegates"
+            subtitle: "Various List Delegates"
+        }
+        ListElement {
+            page: "MoreIndicator.qml"
+            title: "MoreIndicator"
+            subtitle: "Indicates that there are more contents"
+        }
+        ListElement {
+            page: "StyledButtons.qml"
+            title: "StyledButtons"
+            subtitle: "Buttons with different styles"
+        }
+    }
+    ListView {
+        id: listview
+        anchors.fill: parent
+        model: pagesModel
+
+        delegate: ListDelegate {
+            Image {
+                source: "image://theme/icon-m-common-drilldown-arrow" + (theme.inverted ? "-inverse" : "")
+                anchors.right: parent.right;
+                anchors.verticalCenter: parent.verticalCenter
+            }
+
+            subtitleColor: "#cc6633"
+            onClicked: { openFile(model.page); }
+        }
+    }
+*/
+    TabGroup {
+        id: tabGroup
+
+        currentTab: downloads
+
+        PageStack {
+            id: downloads
+        }
+        PageStack {
+            id: seeds
+        }
+        Page {
+            id: tab3
+            Column {
+                spacing: 10
+
+                Text {
+                    text: "This is a single page"
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/qml-client/qml/SeedView.qml b/src/qml-client/qml/SeedView.qml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/qml-client/qml/main.qml b/src/qml-client/qml/main.qml
new file mode 100644 (file)
index 0000000..67383aa
--- /dev/null
@@ -0,0 +1,36 @@
+
+import QtQuick 1.1
+import com.meego 1.0
+
+PageStackWindow {
+    id: rootWindow
+    property int pageMargin: 16
+
+    platformStyle: defaultStyle;
+
+    PageStackWindowStyle { id: defaultStyle }
+    PageStackWindowStyle { id: customStyle; background: "image://theme/meegotouch-wallpaper-portrait"}
+
+    // ListPage is what we see when the app starts, it links to the component specific pages
+    initialPage: MainPage { }
+
+    // These tools are shared by most sub-pages by assigning the id to a page's tools property
+    ToolBarLayout {
+        id: commonTools
+        visible: false
+        ToolIcon { iconId: "toolbar-back"; onClicked: { myMenu.close(); pageStack.pop(); } }
+        ToolIcon { iconId: "toolbar-view-menu"; onClicked: (myMenu.status == DialogStatus.Closed) ? myMenu.open() : myMenu.close() }
+    }
+
+    Menu {
+        id: myMenu
+        visualParent: pageStack
+        MenuLayout {
+            MenuItem {id: b1; text: "Landscape"; onClicked: screen.allowedOrientations = Screen.Landscape}
+            MenuItem {id: b2; text: "Portrait"; onClicked: screen.allowedOrientations = Screen.Portrait}
+            MenuItem {id: b3; text: "Item 3"; onClicked: myMenu.accept()}
+            MenuItem {id: b4; text: "Item 4"; onClicked: myMenu.accept()}
+        }
+    }
+}
+
diff --git a/src/qml-client/qml/qml.qrc b/src/qml-client/qml/qml.qrc
new file mode 100644 (file)
index 0000000..955eecb
--- /dev/null
@@ -0,0 +1,9 @@
+ <!DOCTYPE RCC>
+ <RCC version="1.0">
+
+ <qresource prefix="/">
+    <file>main.qml</file>
+    <file>MainPage.qml</file>
+ </qresource>
+
+ </RCC>
\ No newline at end of file