Initial commit for the QML client:
authorlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Sun, 29 Jan 2012 14:00:40 +0000 (14:00 +0000)
committerlvaatamoinen <lassi.vaatamoinen@ixonos.com>
Sun, 29 Jan 2012 14:00:40 +0000 (14:00 +0000)
Adding data to model works, currently testdata used.
TODO: Make torrent adding work, use real data.
TODO: Add real functionality: status update, torrent removal.

git-svn-id: file:///svnroot/qtrapids/trunk@82 42ac0dd5-4c8c-4c71-bb3e-ecdfe252ffda

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

index da3d8b5..873b699 100644 (file)
@@ -1,6 +1,12 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+set(QT_USE_QTDECLARATIVE 1)
+
+FIND_PACKAGE(Qt4 REQUIRED)
+
 INCLUDE(${QT_USE_FILE})
 
-INCLUDE_DIRECTORIES(../include ../plugins)
+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)
@@ -12,32 +18,48 @@ INCLUDE_DIRECTORIES(
    ${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
-  ./DownloadView.h
-  ./MainWindow.h
-  ./PreferencesDialog.h
-  ./proxy.h
-  ./SeedView.h
-  ./ColumnSelectorDialog.h
+    ./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
-  ./MainWindow.cpp
-  ./PreferencesDialog.cpp
-  ./proxy.cpp
-  ./SeedView.cpp
-  ./ColumnSelectorDialog.cpp
+#     ./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})
-ADD_EXECUTABLE(qtrapids-gui ${SRC} ${MOC_HEADERS})
-INSTALL(TARGETS qtrapids-gui DESTINATION bin)
+# 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)
 
@@ -54,17 +76,18 @@ if(NOT QT_QTMAEMO5_LIBRARY)
 endif(NOT QT_QTMAEMO5_LIBRARY)
 
 
-TARGET_LINK_LIBRARIES(qtrapids-gui
+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})
+#set (SCRATCHBOX_UNAME $ENV{SBOX_UNAME_MACHINE})
 
 if (SCRATCHBOX_UNAME)
        MESSAGE("Configuring for building under Scratchbox..")
index 524da17..9d992b8 100644 (file)
  *   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;
 
@@ -30,51 +34,88 @@ 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;
-       
-       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);
-       }
-       */
-
-       return app.exec();
+
+    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/client/models/Plugin.cpp b/src/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/client/models/Plugin.h b/src/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/client/models/QDeclarativeDownloadListModel.cpp b/src/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/client/models/QDeclarativeDownloadListModel.h b/src/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/client/models/QDeclarativeDownloadListModel_p.h b/src/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/client/models/qmldir b/src/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/client/proxy.cpp b/src/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/client/proxy.h b/src/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/client/qml/DownloadView.qml b/src/client/qml/DownloadView.qml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/client/qml/MainPage.qml b/src/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/client/qml/SeedView.qml b/src/client/qml/SeedView.qml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/client/qml/main.qml b/src/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/client/qml/qml.qrc b/src/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