just some directory renaming
authorpavelpa <pavelpa@localhost>
Thu, 14 Jan 2010 07:43:12 +0000 (07:43 +0000)
committerpavelpa <pavelpa@localhost>
Thu, 14 Jan 2010 07:43:12 +0000 (07:43 +0000)
 - renamed 'model' to 'mvc' (Model-View-Controller), since it contains also 'delegate' and 'view'

33 files changed:
src/app/app.pro
src/fosdem.pro
src/gui/daynavigatorwidget.cpp
src/gui/gui.pro
src/gui/mainwindow.ui
src/model/conference.cpp [deleted file]
src/model/conference.h [deleted file]
src/model/delegate.cpp [deleted file]
src/model/delegate.h [deleted file]
src/model/event.cpp [deleted file]
src/model/event.h [deleted file]
src/model/eventmodel.cpp [deleted file]
src/model/eventmodel.h [deleted file]
src/model/model.pro [deleted file]
src/model/treeview.cpp [deleted file]
src/model/treeview.h [deleted file]
src/mvc/conference.cpp [new file with mode: 0644]
src/mvc/conference.h [new file with mode: 0644]
src/mvc/delegate.cpp [new file with mode: 0644]
src/mvc/delegate.h [new file with mode: 0644]
src/mvc/event.cpp [new file with mode: 0644]
src/mvc/event.h [new file with mode: 0644]
src/mvc/eventmodel.cpp [new file with mode: 0644]
src/mvc/eventmodel.h [new file with mode: 0644]
src/mvc/mvc.pro [new file with mode: 0644]
src/mvc/treeview.cpp [new file with mode: 0644]
src/mvc/treeview.h [new file with mode: 0644]
src/test/main.cpp
src/test/model/eventtest.cpp [deleted file]
src/test/model/eventtest.h [deleted file]
src/test/mvc/eventtest.cpp [new file with mode: 0644]
src/test/mvc/eventtest.h [new file with mode: 0644]
src/test/test.pro

index a48b1f24629bd055172bc15525519039117865cb..5567579222ec71e66d8055349d6def58c0f49f0d 100644 (file)
@@ -4,10 +4,10 @@ DESTDIR = ../bin
 QT += sql xml
 
 # module dependencies
-LIBS += -L$$DESTDIR -lgui -lmodel -lsql
+LIBS += -L$$DESTDIR -lgui -lmvc -lsql
 INCLUDEPATH += ../gui
 DEPENDPATH += . ../gui
-TARGETDEPS += $$DESTDIR/libmodel.a $$DESTDIR/libgui.a $$DESTDIR/libsql.a
+TARGETDEPS += $$DESTDIR/libmvc.a $$DESTDIR/libgui.a $$DESTDIR/libsql.a
 
 SOURCES += main.cpp
 
index ded833f17079dc643953f64fd74db9c9b0c9e0fb..69179f80e892be85b0ce78dad413fb38c991f50f 100644 (file)
@@ -1,4 +1,4 @@
 TEMPLATE = subdirs
-SUBDIRS  = orm model sql gui app test
+SUBDIRS  = orm mvc sql gui app test
 CONFIG += ordered
 
index 4f4ce54c2e2220cf4884719dcf7c3fefedbd2323..20b277893dc0fac6e3c3d0353413a57765eeb896 100644 (file)
@@ -15,7 +15,7 @@ DayNavigatorWidget::DayNavigatorWidget(QWidget *aParent)
 
 void DayNavigatorWidget::setDates(const QDate &aStartDate, const QDate &aEndDate)
 {
-    Q_ASSERT(aStartDate>=aEndDate);
+    Q_ASSERT(aStartDate<=aEndDate);
 
     //qDebug() << "DayNavigatorWidget::setDates(): " << aStartDate << ", " << aEndDate;
     mStartDate = aStartDate;
index 9849e2747d67da46220768d693bb0702fb1ea2e8..0abcbbdb1c66ce9daafcc8c024d9f6b622a0e385 100644 (file)
@@ -5,10 +5,10 @@ CONFIG += static
 QT += sql xml
 
 # module dependencies
-LIBS += -L$$DESTDIR -lmodel -lorm -lsql
-INCLUDEPATH += ../orm ../model ../sql
-DEPENDPATH += . ../orm ../model ../sql
-TARGETDEPS += $$DESTDIR/liborm.a $$DESTDIR/libmodel.a $$DESTDIR/libsql.a
+LIBS += -L$$DESTDIR -lmvc -lorm -lsql
+INCLUDEPATH += ../orm ../mvc ../sql
+DEPENDPATH += . ../orm ../mvc ../sql
+TARGETDEPS += $$DESTDIR/liborm.a $$DESTDIR/libmvc.a $$DESTDIR/libsql.a
 
 
 # A shamelessly long list of sources, headers and forms.
index 72ccbfd17e5e1ba09a5fd3f43c1e63c06c2125c4..548054be55e1c60653162da3c1c76aeb408db00d 100644 (file)
@@ -19,9 +19,9 @@
       <property name="currentIndex" >
        <number>0</number>
       </property>
-      <widget class="QWidget" name="tab" >
+      <widget class="QWidget" name="dayViewTab" >
        <attribute name="title" >
-        <string>Tab 1</string>
+        <string>Day View</string>
        </attribute>
        <layout class="QGridLayout" name="gridLayout_2" >
         <item row="0" column="0" >
@@ -43,9 +43,9 @@
         </item>
        </layout>
       </widget>
-      <widget class="QWidget" name="tab_2" >
+      <widget class="QWidget" name="favouritiesTab" >
        <attribute name="title" >
-        <string>Tab 2</string>
+        <string>Favourities</string>
        </attribute>
       </widget>
      </widget>
   </action>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>TreeView</class>
-   <extends>QTreeView</extends>
-   <header>../model/treeview.h</header>
-  </customwidget>
   <customwidget>
    <class>DayNavigatorWidget</class>
    <extends>QWidget</extends>
    <header>daynavigatorwidget.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>TreeView</class>
+   <extends>QTreeView</extends>
+   <header>../mvc/treeview.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/src/model/conference.cpp b/src/model/conference.cpp
deleted file mode 100644 (file)
index c2d7d90..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "conference.h"
-
-QSqlRecord const Conference::sColumns = Conference::toRecord(QList<QSqlField>()
-    << QSqlField("id", QVariant::Int)
-    << QSqlField("title", QVariant::String)
-    << QSqlField("subtitle", QVariant::String)
-    << QSqlField("venue", QVariant::String)
-    << QSqlField("city", QVariant::String)
-    << QSqlField("start", QVariant::DateTime)
-    << QSqlField("end", QVariant::DateTime)
-    << QSqlField("days", QVariant::Int)
-    << QSqlField("day_change", QVariant::Int)
-    << QSqlField("timeslot_duration", QVariant::Int));
-
-QString const Conference::sTableName = QString("conference");
-
-Conference Conference::getById(int id)
-{
-    QSqlQuery query;
-    query.prepare(selectQuery() + "WHERE id = :id");
-    query.bindValue(":id", id);
-    return loadOne(query);
-}
-
-QList<Conference> Conference::getAll()
-{
-    QSqlQuery query;
-    query.prepare(selectQuery());
-    return load(query);
-}
-
diff --git a/src/model/conference.h b/src/model/conference.h
deleted file mode 100644 (file)
index c6c8e01..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef CONFERENCE_H
-#define CONFERENCE_H
-
-#include <QDateTime>
-#include <QVector>
-#include <QStringList>
-
-#include <ormrecord.h>
-
-class Conference : public OrmRecord<Conference>
-{
-public:
-    static QSqlRecord const sColumns;
-    static QString const sTableName;
-
-public:
-    static Conference getById(int id);
-    static QList<Conference> getAll();
-
-public:
-    int id() const { return value("id").toInt(); }
-    QString title() const { return value("title").toString(); }
-    QString subtitle() const { return value("subtitle").toString(); }
-    QString venue() const { return value("venue").toString(); }
-    QString city() const { return value("city").toString(); }
-    QDate start() const { return value("start").toDate(); }
-    QDate end() const { return value("end").toDate(); }
-    int days() const { return value("days").toInt(); }
-    int dayChange() const { return value("day_change").toInt(); } // in seconds from 00:00
-    int timeslotDuration() const { return value("timeslot_duration").toInt(); } // in seconds
-
-    void setId(int id) { setValue("id", id); }
-    void setTitle(const QString& title) { setValue("title", title); }
-    void setSubtitle(const QString& subtitle) { setValue("subtitle", subtitle); }
-    void setVenue(const QString& venue) { setValue("venue", venue); }
-    void setCity(const QString& city) { setValue("city", city); }
-    //void setStart(const QDate& start) { setValue("start", QDateTime(start)); }
-    void setStart(const QDate& start) { setValue("start", start); }
-    //void setEnd(const QDate& end) { setValue("end", QDateTime(end)); }
-    void setEnd(const QDate& end) { setValue("end", end); }
-    void setDays(int days) { setValue("days", days); }
-    void setDayChange(int dayChange) { setValue("day_change", dayChange); }
-    void setTimeslotDuration(int timeslotDuration) { setValue("timeslot_duration", timeslotDuration); }
-};
-
-#endif /* CONFERENCE_H */
-
diff --git a/src/model/delegate.cpp b/src/model/delegate.cpp
deleted file mode 100644 (file)
index 95ab7b1..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-#include "delegate.h"
-#include "eventmodel.h"
-
-#include <QDebug>
-#include <QPainter>
-
-const int RADIUS = 10;
-const int SPACER = RADIUS;
-
-Delegate::Delegate(QTreeView *aParent)
-    : QItemDelegate(aParent)
-    , mViewPtr(aParent)
-{
-    mControls.clear();
-    defineControls();
-}
-
-Delegate::~Delegate()
-{
-    QListIterator<ControlId> i(mControls.keys());
-    while (i.hasNext())
-    {
-        delete mControls[i.next()]->image();
-    }
-}
-
-void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
-    if(!mViewPtr)
-        return;
-
-    painter->save();
-
-    QColor bkgrColor = Qt::cyan;
-    QPen borderPen(bkgrColor.darker());
-    if(hasParent(index))
-    {
-        if(isLast(index))
-        {
-            QLinearGradient lastGradient(option.rect.topLeft(), option.rect.bottomLeft());
-            lastGradient.setColorAt(0.0, Qt::white);
-            lastGradient.setColorAt(0.5, bkgrColor);
-            lastGradient.setColorAt(1.0, Qt::white);
-
-            QPainterPath endPath;
-            endPath.moveTo(option.rect.topLeft());
-            endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
-            endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
-            endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
-            endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
-            endPath.lineTo(option.rect.topRight());
-
-            //painter->setBrush( bkgrColor );
-            painter->setBrush(lastGradient);
-            painter->setPen(borderPen);
-            painter->drawPath(endPath);
-
-            painter->setFont(option.font);
-        }
-        else // middle elements
-        {
-
-            QLinearGradient middleGradient(option.rect.topLeft(), option.rect.bottomLeft());
-            middleGradient.setColorAt(0.0, Qt::white);
-            middleGradient.setColorAt(0.25, bkgrColor);
-            middleGradient.setColorAt(0.5, Qt::white);
-            middleGradient.setColorAt(0.75, bkgrColor);
-            middleGradient.setColorAt(1.0, Qt::white);
-
-            //painter->setBrush( bkgrColor );
-            painter->setBrush(middleGradient);
-            painter->setPen(Qt::NoPen);
-            painter->drawRect(option.rect);
-
-            painter->setPen(borderPen);
-            // vertical lines
-            painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
-            painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
-            // horizontal lines
-            painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
-
-            painter->setFont(option.font);
-        }
-
-        // draw Controls
-        painter->drawImage(mControls[FavouriteControl]->drawPoint(option.rect),*mControls[FavouriteControl]->image());
-        painter->drawImage(mControls[AlarmControl]->drawPoint(option.rect),*mControls[AlarmControl]->image());
-    }
-    else // doesn't have parent - time-groups' elements (top items)
-    {
-        QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
-        //titleGradient.setColorAt(0.0, Qt::white);
-        titleGradient.setColorAt(0.0, bkgrColor);
-        titleGradient.setColorAt(0.5, Qt::white);
-        titleGradient.setColorAt(1.0, bkgrColor);
-
-        QPainterPath titlePath;
-        if(isExpanded(index))
-        {
-            titlePath.moveTo(option.rect.bottomLeft());
-            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
-            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
-            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
-            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
-            titlePath.lineTo(option.rect.bottomRight());
-            titlePath.closeSubpath();
-        }
-        else
-        {
-            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
-            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
-            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
-            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
-            titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
-            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
-            titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
-            titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
-            titlePath.closeSubpath();
-        }
-
-        painter->setBrush(titleGradient);
-        painter->setPen(borderPen);
-        painter->drawPath(titlePath);
-
-        QFont font = option.font;
-        font.setBold(true);
-        painter->setFont(font);
-    }
-
-    //// HIGHLIGHTING SELECTED ITEM
-    //if (option.state & QStyle::State_Selected)
-        //painter->fillRect(option.rect, option.palette.highlight());
-
-    // draw title
-    QPointF titlePointF(option.rect.x(),option.rect.y()+option.rect.height()-10);
-    QString text = qVariantValue<QString>(index.data());
-    painter->drawText(titlePointF,text);
-
-    painter->restore();
-}
-
-QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
-    Q_UNUSED(option)
-
-    if (index.internalId() == 0) // time group
-    {
-        return QSize(30,30);
-    }
-    else // event
-    {
-        return QSize(100,100);
-    }
-}
-
-bool Delegate::hasParent( const QModelIndex &index ) const
-{
-    if( index.parent().isValid() )
-        return true;
-    else
-        return false;
-}
-  
-bool Delegate::isLast( const QModelIndex &index ) const
-{
-    if(!hasParent(index))
-        return false; // what should be returned here?
-
-    if(index.row() >= (index.model()->rowCount(index.parent())-1))
-        return true;
-    else
-        return false;
-}
-
-bool Delegate::isExpanded( const QModelIndex &index ) const
-{
-    if( !mViewPtr )
-        return false;
-    else
-        return mViewPtr->isExpanded( index );
-}
-
-Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
-{
-    if(!hasParent(aIndex)) // time-group item (root item)
-        return ControlNone;
-
-    QListIterator<ControlId> i(mControls.keys());
-    while (i.hasNext())
-    {
-        ControlId id = i.next();
-        if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
-            return id;
-    }
-
-    return ControlNone;
-}
-
-void Delegate::defineControls()
-{
-    Control *control;
-    // FAVOURITE ICON
-    control = new Control(FavouriteControl,QString(":icons/favourite-on.png"));
-    control->setDrawPoint(QPoint(-control->image()->width()-SPACER,SPACER));
-    mControls.insert(FavouriteControl,control);
-
-    // ALARM ICON
-    control = new Control(AlarmControl,QString(":icons/alarm-on.png"));
-    control->setDrawPoint(QPoint(-mControls[FavouriteControl]->image()->width()-control->image()->width()-2*SPACER,SPACER));
-    mControls.insert(AlarmControl,control);
-}
-
-bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
-{
-    if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
-        return true;
-
-    return false;
-}
-
diff --git a/src/model/delegate.h b/src/model/delegate.h
deleted file mode 100644 (file)
index 657994d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef DELEGATE_H
-#define DELEGATE_H
-
-#include <QItemDelegate>
-#include <QTreeView>
-#include <QPointer>
-
-class Delegate : public QItemDelegate
-{
-    Q_OBJECT
-
-    public:
-
-        enum ControlId
-        {
-            ControlNone = 0,
-            FavouriteControl,
-            AlarmControl
-        };
-
-        class Control
-        {
-            public:
-                Control(ControlId aControlId, const QString &aImageName)
-                    : mId(aControlId)
-                    , mImage(new QImage(aImageName))
-                    , mDrawPoint(QPoint(0,0))
-                { }
-                inline QImage *image() const { return mImage; }
-                inline void setDrawPoint(const QPoint &aPoint) { mDrawPoint = aPoint; }
-                inline QPoint drawPoint(const QRect &aRect) const // for painter to draw Control
-                {
-                    return QPoint(aRect.x()+aRect.width(),aRect.y()) + mDrawPoint;
-                }
-                inline QRect drawRect(const QRect &aRect) const // helper for determining if Control was clicked
-                {
-                    return QRect(drawPoint(aRect), drawPoint(aRect)+QPoint(mImage->size().width(),mImage->size().height()));
-                }
-            private:
-                ControlId mId;
-                QImage *mImage;
-                QPoint mDrawPoint; // relative 'start-drawing' position (may hold negative values)
-        };
-
-        Delegate(QTreeView *aParent); // the delegate 'owner' has to be specified in the constructor - it's used to obtain visualRect of selected item/index
-        ~Delegate();
-
-        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
-        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
-        //
-        Delegate::ControlId whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const;
-        bool isPointFromRect(const QPoint &aPoint, const QRect &aRect) const;
-
-    private:
-        bool hasParent( const QModelIndex &index ) const;
-        bool isLast( const QModelIndex &index ) const;
-        bool isExpanded( const QModelIndex &index ) const;
-        void defineControls();
-
-    private:
-        QPointer<QTreeView> mViewPtr;
-        QMap<ControlId,Control*> mControls;
-};
-
-#endif /* DELEGATE_H */
-
diff --git a/src/model/event.cpp b/src/model/event.cpp
deleted file mode 100644 (file)
index ffc805a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "event.h"
-
-QSqlRecord const Event::sColumns = Event::toRecord(QList<QSqlField>()
-    << QSqlField("id", QVariant::Int)
-    << QSqlField("xid_conference", QVariant::Int)
-    << QSqlField("start", QVariant::DateTime)
-    << QSqlField("duration", QVariant::Int)
-    << QSqlField("xid_activity", QVariant::Int)
-    << QSqlField("type", QVariant::String)
-    << QSqlField("language", QVariant::String));
-
-QString const Event::sTableName = QString("event");
-
-Event Event::getById(int id, int conferenceId)
-{
-    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));
-
-    return load(query);
-}
diff --git a/src/model/event.h b/src/model/event.h
deleted file mode 100644 (file)
index 05c74a8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef EVENT_H
-#define EVENT_H
-
-#include <QDateTime>
-#include <QVector>
-#include <QStringList>
-
-#include <ormrecord.h>
-
-
-/**
-  NoSuchEventException is thrown when required event does not exist.
-*/
-class NoSuchEventException
-{
-};
-
-class Event : public OrmRecord<Event>
-{
-public:
-    static QSqlRecord const sColumns;
-    static QString const sTableName;
-
-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(); }
-    int conferenceId() const { return value("xid_conference").toInt(); }
-    QDateTime start() const { return value("start").toDateTime(); }
-    int duration() const { return value("duration").toInt(); }
-    int activityId() const { return value("xid_activity").toInt(); }
-    QString type() const { return value("type").toString(); }
-    QString language() const { return value("language").toString(); }
-
-    void setId(int id) { setValue("id", id); }
-    void setConferenceId(int conferenceId) { setValue("xid_conference", conferenceId); }
-    void setStart(const QDateTime& start) { setValue("start", start); }
-    void setDuration(int duration) { setValue("duration", duration); }
-    void setActivityId(int activityId) { setValue("xid_activity", activityId); }
-    void setType(const QString& type) { setValue("type", type); }
-    void setLanguage(const QString& language) { setValue("language", language); }
-
-friend class EventTest;
-};
-
-
-
-#endif // EVENT_H
diff --git a/src/model/eventmodel.cpp b/src/model/eventmodel.cpp
deleted file mode 100644 (file)
index 6d88977..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-#include "eventmodel.h"
-#include <conference.h>
-
-EventModel::EventModel()
-{
-    mEvents.clear();
-}
-
-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;
-}
-
-void EventModel::loadEvents(const QDate &aDate, int aConferenceId)
-{
-    mEvents.clear();
-
-    // check for existence of the conference in the DB
-    if(Conference::getAll().count())
-    {
-        qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
-        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
-    }
-    createTimeGroups();
-}
-
diff --git a/src/model/eventmodel.h b/src/model/eventmodel.h
deleted file mode 100644 (file)
index b22e3e5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#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;
-    void loadEvents(const QDate &aDate, int aConferenceId); // loads Events from the DB
-
-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
-
diff --git a/src/model/model.pro b/src/model/model.pro
deleted file mode 100644 (file)
index 87ce365..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-TEMPLATE = lib
-TARGET = model
-DESTDIR = ../bin
-CONFIG += static
-QT += sql
-
-# module dependencies
-LIBS += -L$$DESTDIR -lorm
-INCLUDEPATH += ../orm
-DEPENDPATH += . ../orm
-TARGETDEPS += $$DESTDIR/liborm.a
-
-HEADERS += \
-    event.h \
-    conference.h \
-    delegate.h \
-    eventmodel.h \
-    treeview.h
-SOURCES += \
-    event.cpp \
-    conference.cpp \
-    delegate.cpp \
-    eventmodel.cpp \
-    treeview.cpp
-
diff --git a/src/model/treeview.cpp b/src/model/treeview.cpp
deleted file mode 100644 (file)
index 80fbd28..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <QMouseEvent>
-
-#include "treeview.h"
-#include "delegate.h"
-
-#include <QDebug>
-
-TreeView::TreeView(QWidget *aParent)
-    : QTreeView(aParent)
-{
-}
-
-void TreeView::mouseReleaseEvent(QMouseEvent *aEvent)
-{
-    QModelIndex index = currentIndex();
-    QPoint point = aEvent->pos();
-
-    testForControlClicked(index,point);
-
-    // pass the event to the Base class, so item clicks/events are handled correctly
-    QTreeView::mouseReleaseEvent(aEvent);
-}
-
-void TreeView::testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) 
-{
-    if(!aIndex.isValid())
-        return;
-
-    QRect rect = visualRect(aIndex); // visual QRect of selected/clicked item in the list
-    Delegate *delegate = static_cast<Delegate*>(itemDelegate(aIndex));
-    switch(delegate->whichControlClicked(aIndex,aPoint))
-    {
-        case Delegate::FavouriteControl:
-            {
-                // handle Favourite Control clicked
-                qDebug() << "FAVOURITE CLICKED: " << qVariantValue<QString>(aIndex.data());
-            }
-            break;
-        case Delegate::AlarmControl:
-            {
-                // handle Alarm Control clicked
-                qDebug() << "ALARM CLICKED: " << qVariantValue<QString>(aIndex.data());
-            }
-            break;
-        case Delegate::ControlNone:
-        default:
-            {
-                // item was clicked, but not a control
-            }
-    };
-}
-
diff --git a/src/model/treeview.h b/src/model/treeview.h
deleted file mode 100644 (file)
index 2a81907..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef TREEVIEW_H
-#define TREEVIEW_H
-
-#include <QTreeView>
-
-class TreeView : public QTreeView
-{
-public:
-    TreeView(QWidget *aParent = NULL);
-    ~TreeView() {}
-private:
-    void mouseReleaseEvent(QMouseEvent *aEvent);
-    void testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint);
-};
-
-#endif /* TREEVIEW_H */
-
diff --git a/src/mvc/conference.cpp b/src/mvc/conference.cpp
new file mode 100644 (file)
index 0000000..c2d7d90
--- /dev/null
@@ -0,0 +1,31 @@
+#include "conference.h"
+
+QSqlRecord const Conference::sColumns = Conference::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField("title", QVariant::String)
+    << QSqlField("subtitle", QVariant::String)
+    << QSqlField("venue", QVariant::String)
+    << QSqlField("city", QVariant::String)
+    << QSqlField("start", QVariant::DateTime)
+    << QSqlField("end", QVariant::DateTime)
+    << QSqlField("days", QVariant::Int)
+    << QSqlField("day_change", QVariant::Int)
+    << QSqlField("timeslot_duration", QVariant::Int));
+
+QString const Conference::sTableName = QString("conference");
+
+Conference Conference::getById(int id)
+{
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE id = :id");
+    query.bindValue(":id", id);
+    return loadOne(query);
+}
+
+QList<Conference> Conference::getAll()
+{
+    QSqlQuery query;
+    query.prepare(selectQuery());
+    return load(query);
+}
+
diff --git a/src/mvc/conference.h b/src/mvc/conference.h
new file mode 100644 (file)
index 0000000..c6c8e01
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef CONFERENCE_H
+#define CONFERENCE_H
+
+#include <QDateTime>
+#include <QVector>
+#include <QStringList>
+
+#include <ormrecord.h>
+
+class Conference : public OrmRecord<Conference>
+{
+public:
+    static QSqlRecord const sColumns;
+    static QString const sTableName;
+
+public:
+    static Conference getById(int id);
+    static QList<Conference> getAll();
+
+public:
+    int id() const { return value("id").toInt(); }
+    QString title() const { return value("title").toString(); }
+    QString subtitle() const { return value("subtitle").toString(); }
+    QString venue() const { return value("venue").toString(); }
+    QString city() const { return value("city").toString(); }
+    QDate start() const { return value("start").toDate(); }
+    QDate end() const { return value("end").toDate(); }
+    int days() const { return value("days").toInt(); }
+    int dayChange() const { return value("day_change").toInt(); } // in seconds from 00:00
+    int timeslotDuration() const { return value("timeslot_duration").toInt(); } // in seconds
+
+    void setId(int id) { setValue("id", id); }
+    void setTitle(const QString& title) { setValue("title", title); }
+    void setSubtitle(const QString& subtitle) { setValue("subtitle", subtitle); }
+    void setVenue(const QString& venue) { setValue("venue", venue); }
+    void setCity(const QString& city) { setValue("city", city); }
+    //void setStart(const QDate& start) { setValue("start", QDateTime(start)); }
+    void setStart(const QDate& start) { setValue("start", start); }
+    //void setEnd(const QDate& end) { setValue("end", QDateTime(end)); }
+    void setEnd(const QDate& end) { setValue("end", end); }
+    void setDays(int days) { setValue("days", days); }
+    void setDayChange(int dayChange) { setValue("day_change", dayChange); }
+    void setTimeslotDuration(int timeslotDuration) { setValue("timeslot_duration", timeslotDuration); }
+};
+
+#endif /* CONFERENCE_H */
+
diff --git a/src/mvc/delegate.cpp b/src/mvc/delegate.cpp
new file mode 100644 (file)
index 0000000..95ab7b1
--- /dev/null
@@ -0,0 +1,220 @@
+#include "delegate.h"
+#include "eventmodel.h"
+
+#include <QDebug>
+#include <QPainter>
+
+const int RADIUS = 10;
+const int SPACER = RADIUS;
+
+Delegate::Delegate(QTreeView *aParent)
+    : QItemDelegate(aParent)
+    , mViewPtr(aParent)
+{
+    mControls.clear();
+    defineControls();
+}
+
+Delegate::~Delegate()
+{
+    QListIterator<ControlId> i(mControls.keys());
+    while (i.hasNext())
+    {
+        delete mControls[i.next()]->image();
+    }
+}
+
+void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    if(!mViewPtr)
+        return;
+
+    painter->save();
+
+    QColor bkgrColor = Qt::cyan;
+    QPen borderPen(bkgrColor.darker());
+    if(hasParent(index))
+    {
+        if(isLast(index))
+        {
+            QLinearGradient lastGradient(option.rect.topLeft(), option.rect.bottomLeft());
+            lastGradient.setColorAt(0.0, Qt::white);
+            lastGradient.setColorAt(0.5, bkgrColor);
+            lastGradient.setColorAt(1.0, Qt::white);
+
+            QPainterPath endPath;
+            endPath.moveTo(option.rect.topLeft());
+            endPath.lineTo(option.rect.bottomLeft()-QPoint(0, RADIUS));
+            endPath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 180, 90);
+            endPath.lineTo(option.rect.bottomRight()-QPoint(RADIUS, 0));
+            endPath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, 90);
+            endPath.lineTo(option.rect.topRight());
+
+            //painter->setBrush( bkgrColor );
+            painter->setBrush(lastGradient);
+            painter->setPen(borderPen);
+            painter->drawPath(endPath);
+
+            painter->setFont(option.font);
+        }
+        else // middle elements
+        {
+
+            QLinearGradient middleGradient(option.rect.topLeft(), option.rect.bottomLeft());
+            middleGradient.setColorAt(0.0, Qt::white);
+            middleGradient.setColorAt(0.25, bkgrColor);
+            middleGradient.setColorAt(0.5, Qt::white);
+            middleGradient.setColorAt(0.75, bkgrColor);
+            middleGradient.setColorAt(1.0, Qt::white);
+
+            //painter->setBrush( bkgrColor );
+            painter->setBrush(middleGradient);
+            painter->setPen(Qt::NoPen);
+            painter->drawRect(option.rect);
+
+            painter->setPen(borderPen);
+            // vertical lines
+            painter->drawLine(option.rect.topLeft(), option.rect.bottomLeft());
+            painter->drawLine(option.rect.topRight(), option.rect.bottomRight());
+            // horizontal lines
+            painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
+
+            painter->setFont(option.font);
+        }
+
+        // draw Controls
+        painter->drawImage(mControls[FavouriteControl]->drawPoint(option.rect),*mControls[FavouriteControl]->image());
+        painter->drawImage(mControls[AlarmControl]->drawPoint(option.rect),*mControls[AlarmControl]->image());
+    }
+    else // doesn't have parent - time-groups' elements (top items)
+    {
+        QLinearGradient titleGradient(option.rect.topLeft(), option.rect.topRight());
+        //titleGradient.setColorAt(0.0, Qt::white);
+        titleGradient.setColorAt(0.0, bkgrColor);
+        titleGradient.setColorAt(0.5, Qt::white);
+        titleGradient.setColorAt(1.0, bkgrColor);
+
+        QPainterPath titlePath;
+        if(isExpanded(index))
+        {
+            titlePath.moveTo(option.rect.bottomLeft());
+            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
+            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
+            titlePath.lineTo(option.rect.bottomRight());
+            titlePath.closeSubpath();
+        }
+        else
+        {
+            titlePath.lineTo(option.rect.topLeft()+QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.left(), option.rect.top(), 2*RADIUS, 2*RADIUS, 180, -90);
+            titlePath.lineTo(option.rect.topRight()-QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.top(), 2*RADIUS, 2*RADIUS, 90, -90);
+            titlePath.lineTo(option.rect.bottomRight()-QPoint(0, RADIUS));
+            titlePath.arcTo(option.rect.right()-2*RADIUS, option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 0, -90);
+            titlePath.lineTo(option.rect.bottomLeft()+QPoint(RADIUS, 0));
+            titlePath.arcTo(option.rect.left(), option.rect.bottom()-2*RADIUS, 2*RADIUS, 2*RADIUS, 270, -90);      
+            titlePath.closeSubpath();
+        }
+
+        painter->setBrush(titleGradient);
+        painter->setPen(borderPen);
+        painter->drawPath(titlePath);
+
+        QFont font = option.font;
+        font.setBold(true);
+        painter->setFont(font);
+    }
+
+    //// HIGHLIGHTING SELECTED ITEM
+    //if (option.state & QStyle::State_Selected)
+        //painter->fillRect(option.rect, option.palette.highlight());
+
+    // draw title
+    QPointF titlePointF(option.rect.x(),option.rect.y()+option.rect.height()-10);
+    QString text = qVariantValue<QString>(index.data());
+    painter->drawText(titlePointF,text);
+
+    painter->restore();
+}
+
+QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    Q_UNUSED(option)
+
+    if (index.internalId() == 0) // time group
+    {
+        return QSize(30,30);
+    }
+    else // event
+    {
+        return QSize(100,100);
+    }
+}
+
+bool Delegate::hasParent( const QModelIndex &index ) const
+{
+    if( index.parent().isValid() )
+        return true;
+    else
+        return false;
+}
+  
+bool Delegate::isLast( const QModelIndex &index ) const
+{
+    if(!hasParent(index))
+        return false; // what should be returned here?
+
+    if(index.row() >= (index.model()->rowCount(index.parent())-1))
+        return true;
+    else
+        return false;
+}
+
+bool Delegate::isExpanded( const QModelIndex &index ) const
+{
+    if( !mViewPtr )
+        return false;
+    else
+        return mViewPtr->isExpanded( index );
+}
+
+Delegate::ControlId Delegate::whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const
+{
+    if(!hasParent(aIndex)) // time-group item (root item)
+        return ControlNone;
+
+    QListIterator<ControlId> i(mControls.keys());
+    while (i.hasNext())
+    {
+        ControlId id = i.next();
+        if(mControls[id]->drawRect(static_cast<QTreeView*>(parent())->visualRect(aIndex)).contains(aPoint))
+            return id;
+    }
+
+    return ControlNone;
+}
+
+void Delegate::defineControls()
+{
+    Control *control;
+    // FAVOURITE ICON
+    control = new Control(FavouriteControl,QString(":icons/favourite-on.png"));
+    control->setDrawPoint(QPoint(-control->image()->width()-SPACER,SPACER));
+    mControls.insert(FavouriteControl,control);
+
+    // ALARM ICON
+    control = new Control(AlarmControl,QString(":icons/alarm-on.png"));
+    control->setDrawPoint(QPoint(-mControls[FavouriteControl]->image()->width()-control->image()->width()-2*SPACER,SPACER));
+    mControls.insert(AlarmControl,control);
+}
+
+bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
+{
+    if( (aPoint.x()>=aRect.left() && aPoint.x()<=aRect.right()) && (aPoint.y()>=aRect.top() && aPoint.y()<=aRect.bottom()) )
+        return true;
+
+    return false;
+}
+
diff --git a/src/mvc/delegate.h b/src/mvc/delegate.h
new file mode 100644 (file)
index 0000000..657994d
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef DELEGATE_H
+#define DELEGATE_H
+
+#include <QItemDelegate>
+#include <QTreeView>
+#include <QPointer>
+
+class Delegate : public QItemDelegate
+{
+    Q_OBJECT
+
+    public:
+
+        enum ControlId
+        {
+            ControlNone = 0,
+            FavouriteControl,
+            AlarmControl
+        };
+
+        class Control
+        {
+            public:
+                Control(ControlId aControlId, const QString &aImageName)
+                    : mId(aControlId)
+                    , mImage(new QImage(aImageName))
+                    , mDrawPoint(QPoint(0,0))
+                { }
+                inline QImage *image() const { return mImage; }
+                inline void setDrawPoint(const QPoint &aPoint) { mDrawPoint = aPoint; }
+                inline QPoint drawPoint(const QRect &aRect) const // for painter to draw Control
+                {
+                    return QPoint(aRect.x()+aRect.width(),aRect.y()) + mDrawPoint;
+                }
+                inline QRect drawRect(const QRect &aRect) const // helper for determining if Control was clicked
+                {
+                    return QRect(drawPoint(aRect), drawPoint(aRect)+QPoint(mImage->size().width(),mImage->size().height()));
+                }
+            private:
+                ControlId mId;
+                QImage *mImage;
+                QPoint mDrawPoint; // relative 'start-drawing' position (may hold negative values)
+        };
+
+        Delegate(QTreeView *aParent); // the delegate 'owner' has to be specified in the constructor - it's used to obtain visualRect of selected item/index
+        ~Delegate();
+
+        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+        //
+        Delegate::ControlId whichControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) const;
+        bool isPointFromRect(const QPoint &aPoint, const QRect &aRect) const;
+
+    private:
+        bool hasParent( const QModelIndex &index ) const;
+        bool isLast( const QModelIndex &index ) const;
+        bool isExpanded( const QModelIndex &index ) const;
+        void defineControls();
+
+    private:
+        QPointer<QTreeView> mViewPtr;
+        QMap<ControlId,Control*> mControls;
+};
+
+#endif /* DELEGATE_H */
+
diff --git a/src/mvc/event.cpp b/src/mvc/event.cpp
new file mode 100644 (file)
index 0000000..ffc805a
--- /dev/null
@@ -0,0 +1,32 @@
+#include "event.h"
+
+QSqlRecord const Event::sColumns = Event::toRecord(QList<QSqlField>()
+    << QSqlField("id", QVariant::Int)
+    << QSqlField("xid_conference", QVariant::Int)
+    << QSqlField("start", QVariant::DateTime)
+    << QSqlField("duration", QVariant::Int)
+    << QSqlField("xid_activity", QVariant::Int)
+    << QSqlField("type", QVariant::String)
+    << QSqlField("language", QVariant::String));
+
+QString const Event::sTableName = QString("event");
+
+Event Event::getById(int id, int conferenceId)
+{
+    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));
+
+    return load(query);
+}
diff --git a/src/mvc/event.h b/src/mvc/event.h
new file mode 100644 (file)
index 0000000..05c74a8
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <QDateTime>
+#include <QVector>
+#include <QStringList>
+
+#include <ormrecord.h>
+
+
+/**
+  NoSuchEventException is thrown when required event does not exist.
+*/
+class NoSuchEventException
+{
+};
+
+class Event : public OrmRecord<Event>
+{
+public:
+    static QSqlRecord const sColumns;
+    static QString const sTableName;
+
+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(); }
+    int conferenceId() const { return value("xid_conference").toInt(); }
+    QDateTime start() const { return value("start").toDateTime(); }
+    int duration() const { return value("duration").toInt(); }
+    int activityId() const { return value("xid_activity").toInt(); }
+    QString type() const { return value("type").toString(); }
+    QString language() const { return value("language").toString(); }
+
+    void setId(int id) { setValue("id", id); }
+    void setConferenceId(int conferenceId) { setValue("xid_conference", conferenceId); }
+    void setStart(const QDateTime& start) { setValue("start", start); }
+    void setDuration(int duration) { setValue("duration", duration); }
+    void setActivityId(int activityId) { setValue("xid_activity", activityId); }
+    void setType(const QString& type) { setValue("type", type); }
+    void setLanguage(const QString& language) { setValue("language", language); }
+
+friend class EventTest;
+};
+
+
+
+#endif // EVENT_H
diff --git a/src/mvc/eventmodel.cpp b/src/mvc/eventmodel.cpp
new file mode 100644 (file)
index 0000000..6d88977
--- /dev/null
@@ -0,0 +1,132 @@
+#include "eventmodel.h"
+#include <conference.h>
+
+EventModel::EventModel()
+{
+    mEvents.clear();
+}
+
+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;
+}
+
+void EventModel::loadEvents(const QDate &aDate, int aConferenceId)
+{
+    mEvents.clear();
+
+    // check for existence of the conference in the DB
+    if(Conference::getAll().count())
+    {
+        qDebug() << "Loading Conference Data: [" << Conference::getById(aConferenceId).title() << "] " << aDate;
+        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
+    }
+    createTimeGroups();
+}
+
diff --git a/src/mvc/eventmodel.h b/src/mvc/eventmodel.h
new file mode 100644 (file)
index 0000000..b22e3e5
--- /dev/null
@@ -0,0 +1,45 @@
+#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;
+    void loadEvents(const QDate &aDate, int aConferenceId); // loads Events from the DB
+
+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
+
diff --git a/src/mvc/mvc.pro b/src/mvc/mvc.pro
new file mode 100644 (file)
index 0000000..7ab7bb9
--- /dev/null
@@ -0,0 +1,25 @@
+TEMPLATE = lib
+TARGET = mvc
+DESTDIR = ../bin
+CONFIG += static
+QT += sql
+
+# module dependencies
+LIBS += -L$$DESTDIR -lorm
+INCLUDEPATH += ../orm
+DEPENDPATH += . ../orm
+TARGETDEPS += $$DESTDIR/liborm.a
+
+HEADERS += \
+    event.h \
+    conference.h \
+    delegate.h \
+    eventmodel.h \
+    treeview.h
+SOURCES += \
+    event.cpp \
+    conference.cpp \
+    delegate.cpp \
+    eventmodel.cpp \
+    treeview.cpp
+
diff --git a/src/mvc/treeview.cpp b/src/mvc/treeview.cpp
new file mode 100644 (file)
index 0000000..80fbd28
--- /dev/null
@@ -0,0 +1,52 @@
+#include <QMouseEvent>
+
+#include "treeview.h"
+#include "delegate.h"
+
+#include <QDebug>
+
+TreeView::TreeView(QWidget *aParent)
+    : QTreeView(aParent)
+{
+}
+
+void TreeView::mouseReleaseEvent(QMouseEvent *aEvent)
+{
+    QModelIndex index = currentIndex();
+    QPoint point = aEvent->pos();
+
+    testForControlClicked(index,point);
+
+    // pass the event to the Base class, so item clicks/events are handled correctly
+    QTreeView::mouseReleaseEvent(aEvent);
+}
+
+void TreeView::testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint) 
+{
+    if(!aIndex.isValid())
+        return;
+
+    QRect rect = visualRect(aIndex); // visual QRect of selected/clicked item in the list
+    Delegate *delegate = static_cast<Delegate*>(itemDelegate(aIndex));
+    switch(delegate->whichControlClicked(aIndex,aPoint))
+    {
+        case Delegate::FavouriteControl:
+            {
+                // handle Favourite Control clicked
+                qDebug() << "FAVOURITE CLICKED: " << qVariantValue<QString>(aIndex.data());
+            }
+            break;
+        case Delegate::AlarmControl:
+            {
+                // handle Alarm Control clicked
+                qDebug() << "ALARM CLICKED: " << qVariantValue<QString>(aIndex.data());
+            }
+            break;
+        case Delegate::ControlNone:
+        default:
+            {
+                // item was clicked, but not a control
+            }
+    };
+}
+
diff --git a/src/mvc/treeview.h b/src/mvc/treeview.h
new file mode 100644 (file)
index 0000000..2a81907
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef TREEVIEW_H
+#define TREEVIEW_H
+
+#include <QTreeView>
+
+class TreeView : public QTreeView
+{
+public:
+    TreeView(QWidget *aParent = NULL);
+    ~TreeView() {}
+private:
+    void mouseReleaseEvent(QMouseEvent *aEvent);
+    void testForControlClicked(const QModelIndex &aIndex, const QPoint &aPoint);
+};
+
+#endif /* TREEVIEW_H */
+
index 2cda83592f02c63d00044e3661cd34c62bcacd4c..2b2227193433c9b9b073e3994e5198bcf4d98f3a 100644 (file)
@@ -1,6 +1,6 @@
 #include <QtTest>
 
-#include "model/eventtest.h"
+#include "mvc/eventtest.h"
 
 int main(int argc, char *argv[])
 {
diff --git a/src/test/model/eventtest.cpp b/src/test/model/eventtest.cpp
deleted file mode 100644 (file)
index 232421a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "eventtest.h"
-
-#include <QtTest>
-#include <QSqlDatabase>
-
-#include <QDebug>
-
-#include <event.h>
-
-void EventTest::initTestCase()
-{
-    // Connect to the test database. Ask Mr. Pavelka to generate one for you :)
-    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
-    db.setDatabaseName("fosdem-test.sqlite");
-    QVERIFY(db.open());
-}
-
-void EventTest::getById()
-{
-    Event event = Event::getById(500, 1);
-
-    QCOMPARE(event.id(), 500);
-    QCOMPARE(event.start(), QDateTime(QDate(2009, 2, 7), QTime(11, 30, 0), Qt::UTC));
-    QCOMPARE(event.activityId(), 123);
-
-    // !!! TODO: typeId and languageId
-    QCOMPARE(event.type(), QString("Podium"));
-    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;
-
-    event.setId(10);
-    event.setConferenceId(20);
-    event.setStart(QDateTime::fromString("Sat Feb 7 11:30:00 2009"));
-    event.setDuration(30);
-    event.setActivityId(40);
-    event.setType(QString("type"));
-    event.setLanguage(QString("language"));
-
-    QCOMPARE(event.id(), 10);
-    QCOMPARE(event.conferenceId(), 20);
-    QCOMPARE(event.start(), QDateTime::fromString("Sat Feb 7 11:30:00 2009"));
-    QCOMPARE(event.duration(), 30);
-    QCOMPARE(event.activityId(), 40);
-    QCOMPARE(event.type(), QString("type"));
-    QCOMPARE(event.language(), QString("language"));
-}
-
-void EventTest::hydrate()
-{
-    QSqlRecord record;
-    record.append(QSqlField("duration", QVariant::Int));
-    record.append(QSqlField("id", QVariant::Int));
-    record.setValue(0, 10);
-    record.setValue(1, 20);
-
-    Event event = Event::hydrate(record);
-    QCOMPARE(event.id(), 20);
-    QCOMPARE(event.duration(), 10);
-}
-
-void EventTest::columnsForSelect()
-{
-    QCOMPARE(Event::columnsForSelect(), QString("id,xid_conference,start,duration,xid_activity,type,language"));
-    QCOMPARE(Event::columnsForSelect("t0"),
-             QString("t0.id,t0.xid_conference,t0.start,t0.duration,t0.xid_activity,t0.type,t0.language"));
-}
-
-void EventTest::selectQuery()
-{
-    QCOMPARE(Event::selectQuery(), QString("SELECT id,xid_conference,start,duration,xid_activity,type,language FROM event "));
-}
diff --git a/src/test/model/eventtest.h b/src/test/model/eventtest.h
deleted file mode 100644 (file)
index 920191e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef EVENTTEST_H
-#define EVENTTEST_H
-
-#include <QObject>
-
-class EventTest : public QObject
-{
-    Q_OBJECT
-
-private slots:
-    void initTestCase();
-
-    void getById();
-    void getByDate();
-    void storingValues();
-    void hydrate();
-    void columnsForSelect();
-    void selectQuery();
-};
-
-
-#endif // EVENTTEST_H
-
diff --git a/src/test/mvc/eventtest.cpp b/src/test/mvc/eventtest.cpp
new file mode 100644 (file)
index 0000000..232421a
--- /dev/null
@@ -0,0 +1,81 @@
+#include "eventtest.h"
+
+#include <QtTest>
+#include <QSqlDatabase>
+
+#include <QDebug>
+
+#include <event.h>
+
+void EventTest::initTestCase()
+{
+    // Connect to the test database. Ask Mr. Pavelka to generate one for you :)
+    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName("fosdem-test.sqlite");
+    QVERIFY(db.open());
+}
+
+void EventTest::getById()
+{
+    Event event = Event::getById(500, 1);
+
+    QCOMPARE(event.id(), 500);
+    QCOMPARE(event.start(), QDateTime(QDate(2009, 2, 7), QTime(11, 30, 0), Qt::UTC));
+    QCOMPARE(event.activityId(), 123);
+
+    // !!! TODO: typeId and languageId
+    QCOMPARE(event.type(), QString("Podium"));
+    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;
+
+    event.setId(10);
+    event.setConferenceId(20);
+    event.setStart(QDateTime::fromString("Sat Feb 7 11:30:00 2009"));
+    event.setDuration(30);
+    event.setActivityId(40);
+    event.setType(QString("type"));
+    event.setLanguage(QString("language"));
+
+    QCOMPARE(event.id(), 10);
+    QCOMPARE(event.conferenceId(), 20);
+    QCOMPARE(event.start(), QDateTime::fromString("Sat Feb 7 11:30:00 2009"));
+    QCOMPARE(event.duration(), 30);
+    QCOMPARE(event.activityId(), 40);
+    QCOMPARE(event.type(), QString("type"));
+    QCOMPARE(event.language(), QString("language"));
+}
+
+void EventTest::hydrate()
+{
+    QSqlRecord record;
+    record.append(QSqlField("duration", QVariant::Int));
+    record.append(QSqlField("id", QVariant::Int));
+    record.setValue(0, 10);
+    record.setValue(1, 20);
+
+    Event event = Event::hydrate(record);
+    QCOMPARE(event.id(), 20);
+    QCOMPARE(event.duration(), 10);
+}
+
+void EventTest::columnsForSelect()
+{
+    QCOMPARE(Event::columnsForSelect(), QString("id,xid_conference,start,duration,xid_activity,type,language"));
+    QCOMPARE(Event::columnsForSelect("t0"),
+             QString("t0.id,t0.xid_conference,t0.start,t0.duration,t0.xid_activity,t0.type,t0.language"));
+}
+
+void EventTest::selectQuery()
+{
+    QCOMPARE(Event::selectQuery(), QString("SELECT id,xid_conference,start,duration,xid_activity,type,language FROM event "));
+}
diff --git a/src/test/mvc/eventtest.h b/src/test/mvc/eventtest.h
new file mode 100644 (file)
index 0000000..920191e
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef EVENTTEST_H
+#define EVENTTEST_H
+
+#include <QObject>
+
+class EventTest : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void initTestCase();
+
+    void getById();
+    void getByDate();
+    void storingValues();
+    void hydrate();
+    void columnsForSelect();
+    void selectQuery();
+};
+
+
+#endif // EVENTTEST_H
+
index 47ab4b4e6c10ef857dc1b44fd024fa008647c915..df5a9341e578b9ac84e5bffb03198c01cf603935 100644 (file)
@@ -5,14 +5,14 @@ CONFIG += qtestlib console
 QT += sql
 
 # module dependencies
-LIBS += -L$$DESTDIR -lgui -lmodel
-INCLUDEPATH += ../gui ../model ../orm
-DEPENDPATH += . ../gui ../model ../orm
-TARGETDEPS += $$DESTDIR/libmodel.a $$DESTDIR/libgui.a $$DESTDIR/liborm.a
+LIBS += -L$$DESTDIR -lgui -lmvc
+INCLUDEPATH += ../gui ../mvc ../orm
+DEPENDPATH += . ../gui ../mvc ../orm
+TARGETDEPS += $$DESTDIR/libmvc.a $$DESTDIR/libgui.a $$DESTDIR/liborm.a
 
 SOURCES += main.cpp \
-    model/EventTest.cpp
+    mvc/EventTest.cpp
 
 HEADERS += \
-    model/EventTest.h
+    mvc/EventTest.h