Creating EventModel class
authorkomarma <komarma@localhost>
Sat, 2 Jan 2010 21:14:10 +0000 (21:14 +0000)
committerkomarma <komarma@localhost>
Sat, 2 Jan 2010 21:14:10 +0000 (21:14 +0000)
src/app/app.pro
src/gui/gui.pro
src/gui/mainwindow.cpp
src/model/event.cpp
src/model/event.h
src/model/eventmodel.cpp [new file with mode: 0644]
src/model/eventmodel.h [new file with mode: 0644]
src/model/model.pro
src/orm/ormrecord.h
src/test/model/eventtest.cpp
src/test/model/eventtest.h

index 258c0a6..48d12f6 100644 (file)
@@ -1,6 +1,7 @@
 TEMPLATE = app
 TARGET = fosdem
 DESTDIR = ../bin
+QT += sql
 
 # module dependencies
 LIBS += -L$$DESTDIR -lgui -lmodel
index 0ee1884..f8f6988 100644 (file)
@@ -2,12 +2,13 @@ TEMPLATE = lib
 TARGET = gui
 DESTDIR = ../bin
 CONFIG += static
+QT += sql
 
 # module dependencies
-LIBS += -L$$DESTDIR -lmodel
-INCLUDEPATH += ../model
-DEPENDPATH += . ../model
-TARGETDEPS += $$DESTDIR/libmodel.a
+LIBS += -L$$DESTDIR -lmodel -orm
+INCLUDEPATH += ../orm ../model
+DEPENDPATH += . ../orm ../model
+TARGETDEPS += $$DESTDIR/liborm.a $$DESTDIR/libmodel.a
 
 
 # A shamelessly long list of sources, headers and forms.
index d1e4fe6..e0f20d4 100644 (file)
@@ -1,6 +1,19 @@
 #include "mainwindow.h"
 
+#include <QTreeView>
+
+#include <eventmodel.h>
+
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
 {
+    // open database connection
+    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName("fosdem-test.sqlite");
+    db.open();
+
+    QTreeView * view = new QTreeView(parent);
+    this->setCentralWidget(view);
+
+    view->setModel(new EventModel());
 }
index ff7f1d2..ffc805a 100644 (file)
@@ -13,11 +13,20 @@ QString const Event::sTableName = QString("event");
 
 Event Event::getById(int id, int conferenceId)
 {
-    QString query = selectQuery() + "WHERE id = :id AND xid_conference = :conf";
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE id = :id AND xid_conference = :conf");
+    query.bindValue(":id", id);
+    query.bindValue(":conf", conferenceId);
+    return loadOne(query);
+}
+
+QList<Event> Event::getByDate(const QDate& date, int conferenceId)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE xid_conference = :conf AND start >= :start AND start < :end ORDER BY start");
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
+    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
 
-    QSqlQuery q;
-    q.prepare(query);
-    q.bindValue(":id", id);
-    q.bindValue(":conf", conferenceId);
-    return loadOne(q);
+    return load(query);
 }
index b3efb48..05c74a8 100644 (file)
@@ -23,6 +23,7 @@ public:
 
 public:
     static Event getById(int id, int conferenceId);
+    static QList<Event> getByDate(const QDate& date, int conferenceId);
 
 public:
     int id() const { return value("id").toInt(); }
diff --git a/src/model/eventmodel.cpp b/src/model/eventmodel.cpp
new file mode 100644 (file)
index 0000000..768791b
--- /dev/null
@@ -0,0 +1,118 @@
+#include "eventmodel.h"
+
+EventModel::EventModel() :
+        mEvents(Event::getByDate(QDate(2009, 2, 7), 1))
+{
+    createTimeGroups();
+}
+
+void EventModel::createTimeGroups()
+{
+    mGroups.clear();
+    mParents.clear();
+
+    if (mEvents.empty())
+    {
+        return;
+    }
+
+    const int timeSpan = 5400;
+
+    QTime startTime = mEvents.first().start().time();
+    mGroups << EventModel::Group(QString("%1 - %2").arg(startTime.toString("HH:mm"),
+        startTime.addSecs(timeSpan).toString("HH:mm")), 0);
+    QTime nextGroupTime = mEvents.first().start().time().addSecs(timeSpan);
+
+    for (int i=0; i<mEvents.count(); i++)
+    {
+        QTime eventTime = mEvents.at(i).start().time();
+
+        if (nextGroupTime < eventTime)
+        {
+            mGroups.last().mChildCount = i - mGroups.last().mFirstEventIndex;
+            mGroups << EventModel::Group(QString("%1 - %2").arg(nextGroupTime.toString("HH:mm"),
+                nextGroupTime.addSecs(timeSpan).toString("HH:mm")), i);
+            nextGroupTime = nextGroupTime.addSecs(timeSpan);
+        }
+
+        // add parent-child relation
+        mParents[mEvents.at(i).id()] = mGroups.count() - 1;
+    }
+
+    mGroups.last().mChildCount = mEvents.count() - mGroups.last().mFirstEventIndex;
+}
+
+QVariant EventModel::data(const QModelIndex& index, int role) const
+{
+    if (index.isValid() && role == Qt::DisplayRole)
+    {
+        if (index.internalId() == 0)
+        {
+            return mGroups.at(index.row()).mTitle;
+        }
+        else
+        {
+            return static_cast<Event*>(index.internalPointer())->id();
+        }
+    }
+
+    return QVariant();
+}
+
+QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) const
+{
+    // TODO: add checks for out of range rows
+
+    if (!parent.isValid())
+    {
+        return createIndex(row, column, 0);
+    }
+    else if (parent.internalId() == 0)
+    {
+        const Group& group = mGroups.at(parent.row());
+        Event* event = const_cast<Event*>(&mEvents.at(row + group.mFirstEventIndex));
+        return createIndex(row, column, reinterpret_cast<void*>(event));
+    }
+    else
+    {
+        return QModelIndex();
+    }
+}
+
+QModelIndex EventModel::parent(const QModelIndex & index) const
+{
+    if (index.isValid())
+    {
+        if (index.internalId() == 0)
+        {
+            return QModelIndex();
+        }
+
+        Event * event = static_cast<Event*>(index.internalPointer());
+
+        return createIndex(mParents[event->id()], 0, 0);
+    }
+
+    return QModelIndex();
+}
+
+int EventModel::columnCount(const QModelIndex & parent) const
+{
+    Q_UNUSED(parent);
+    return 1;
+}
+
+int EventModel::rowCount (const QModelIndex & parent) const
+{
+    if (!parent.isValid())
+    {
+        return mGroups.count();
+    }
+
+    if (parent.internalId() == 0)
+    {
+        return mGroups.at(parent.row()).mChildCount;
+    }
+
+    return 0;
+}
diff --git a/src/model/eventmodel.h b/src/model/eventmodel.h
new file mode 100644 (file)
index 0000000..9c06db2
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef EVENTMODEL_H
+#define EVENTMODEL_H
+
+#include <QAbstractItemModel>
+
+#include "event.h"
+
+class EventModel : public QAbstractItemModel
+{
+public:
+    EventModel();
+    QVariant data(const QModelIndex& index, int role) const;
+    QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+    QModelIndex parent ( const QModelIndex & index ) const;
+    int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
+    int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
+
+private:
+    struct Group
+    {
+        Group(const QString & title,
+              int firstEventIndex) :
+
+            mTitle(title),
+            mFirstEventIndex(firstEventIndex),
+            mChildCount(0)
+        {}
+
+        QString mTitle;
+        int mFirstEventIndex;
+        int mChildCount;
+    };
+
+private:
+    void createTimeGroups();
+
+private:
+    QList<Event> mEvents;
+    QList<Group> mGroups;
+    QHash<int, int> mParents;
+};
+
+#endif // EVENTMODEL_H
index 726488f..c8e0b62 100644 (file)
@@ -10,6 +10,10 @@ INCLUDEPATH += ../orm
 DEPENDPATH += . ../orm
 TARGETDEPS += $$DESTDIR/liborm.a
 
-HEADERS += event.h
-SOURCES += event.cpp
+HEADERS += \
+    event.h \
+    eventmodel.h
+SOURCES += \
+    event.cpp \
+    eventmodel.cpp
 
index a939248..5502b79 100644 (file)
@@ -162,7 +162,7 @@ QVariant OrmRecord<T>::convertToC(QVariant value, QVariant::Type colType)
 template <typename T>
 QVariant OrmRecord<T>::convertToDb(QVariant value, QVariant::Type colType)
 {
-    if (colType == QVariant::DateTime && value.type() == QVariant::DateTime)
+    if (colType == QVariant::DateTime && value.canConvert<QDateTime>())
     {
         return value.toDateTime().toTime_t();
     }
index 515ab42..232421a 100644 (file)
@@ -28,6 +28,12 @@ void EventTest::getById()
     QCOMPARE(event.language(), QString("English"));
 }
 
+void EventTest::getByDate()
+{
+    QCOMPARE(Event::getByDate(QDate(2009, 2, 7), 1).count(), 127);
+    QCOMPARE(Event::getByDate(QDate(2009, 2, 8), 1).count(), 154);
+}
+
 void EventTest::storingValues()
 {
     Event event;
index 9a734a8..920191e 100644 (file)
@@ -11,6 +11,7 @@ private slots:
     void initTestCase();
 
     void getById();
+    void getByDate();
     void storingValues();
     void hydrate();
     void columnsForSelect();