TEMPLATE = app
TARGET = fosdem
DESTDIR = ../bin
+QT += sql
# module dependencies
LIBS += -L$$DESTDIR -lgui -lmodel
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.
#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());
}
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);
}
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(); }
--- /dev/null
+#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;
+}
--- /dev/null
+#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
DEPENDPATH += . ../orm
TARGETDEPS += $$DESTDIR/liborm.a
-HEADERS += event.h
-SOURCES += event.cpp
+HEADERS += \
+ event.h \
+ eventmodel.h
+SOURCES += \
+ event.cpp \
+ eventmodel.cpp
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();
}
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;
void initTestCase();
void getById();
+ void getByDate();
void storingValues();
void hydrate();
void columnsForSelect();