Branch 'dev/invitations' - 4 commits - calendarsupport/utils.cpp calendarsupport/utils.h calendarviews/agenda calendarviews/CMakeLists.txt incidenceeditor-ng/CMakeLists.txt incidenceeditor-ng/editoritemmanager.cpp incidenceeditor-ng/freebusyitemmodel.cpp incidenceeditor-ng/incidencedialog.cpp incidenceeditor-ng/incidenceresource.cpp incidenceeditor-ng/incidenceresource.h incidenceeditor-ng/resourcemanagement.cpp incidenceeditor-ng/resourcemanagement.h

Sandro Knauß knauss at kolabsys.com
Mon Sep 15 23:01:58 CEST 2014


 calendarsupport/utils.cpp                 |   45 ++++
 calendarsupport/utils.h                   |   30 +++
 calendarviews/CMakeLists.txt              |    1 
 calendarviews/agenda/agenda.cpp           |  124 ++++++-------
 calendarviews/agenda/agenda.h             |   31 +--
 calendarviews/agenda/agendaitem.cpp       |  103 ++++-------
 calendarviews/agenda/agendaitem.h         |   13 -
 calendarviews/agenda/agendaview.cpp       |  245 ++++++++++++++++----------
 calendarviews/agenda/agendaview.h         |   14 +
 calendarviews/agenda/viewcalendar.cpp     |  169 ++++++++++++++++++
 calendarviews/agenda/viewcalendar.h       |  103 +++++++++++
 incidenceeditor-ng/CMakeLists.txt         |    4 
 incidenceeditor-ng/editoritemmanager.cpp  |    3 
 incidenceeditor-ng/freebusyitemmodel.cpp  |    3 
 incidenceeditor-ng/incidencedialog.cpp    |    2 
 incidenceeditor-ng/incidenceresource.cpp  |   20 +-
 incidenceeditor-ng/incidenceresource.h    |    7 
 incidenceeditor-ng/resourcemanagement.cpp |  275 ++++++++++++++++--------------
 incidenceeditor-ng/resourcemanagement.h   |   21 ++
 19 files changed, 840 insertions(+), 373 deletions(-)

New commits:
commit 694eeaa5b37f501e04303b1e7638c206dd3ac547
Author: Sandro Knauß <knauss at kolabsys.com>
Date:   Mon Sep 15 23:00:18 2014 +0200

    Show agendaview for ifb in resourcemanagement
    
    Kolab: 3583

diff --git a/incidenceeditor-ng/CMakeLists.txt b/incidenceeditor-ng/CMakeLists.txt
index fcfa555..eb53e5b 100644
--- a/incidenceeditor-ng/CMakeLists.txt
+++ b/incidenceeditor-ng/CMakeLists.txt
@@ -7,6 +7,7 @@ include_directories(
   ${CMAKE_CURRENT_BINARY_DIR}
   ${CMAKE_SOURCE_DIR}/calendarsupport
   ${CMAKE_BINARY_DIR}/calendarsupport
+  ${CMAKE_SOURCE_DIR}/calendarviews
   ${CMAKE_SOURCE_DIR}/libkdepim
   ${CMAKE_BINARY_DIR}/incidenceeditor-ng
   ${Boost_INCLUDE_DIR}
@@ -114,6 +115,7 @@ target_link_libraries(incidenceeditorsng
   kdepim
   kdepimdbusinterfaces # For UriHandler
   calendarsupport      # For KCalPrefs
+  eventviews
   kdgantt2             # For FreeBusy Editor
 )
 
@@ -156,6 +158,7 @@ install(TARGETS incidenceeditorsng ${INSTALL_TARGETS_DEFAULT_ARGS})
     kdepim               # For KPIM::K{Date|Time}Edit
     calendarsupport      # For KCalPrefs
     kdepimdbusinterfaces # For UriHandler
+    eventviews
     kdgantt2
     ${KDEPIMLIBS_KCALUTILS_LIBS}
     ${KDEPIMLIBS_KCALCORE_LIBS}
@@ -186,6 +189,7 @@ target_link_libraries(kincidenceeditor
   ${KDEPIMLIBS_KCALUTILS_LIBS}
   incidenceeditorsng
   calendarsupport
+  eventviews
   kdepimdbusinterfaces
 )
 
diff --git a/incidenceeditor-ng/freebusyitemmodel.cpp b/incidenceeditor-ng/freebusyitemmodel.cpp
index 8b66af5..62141f9 100644
--- a/incidenceeditor-ng/freebusyitemmodel.cpp
+++ b/incidenceeditor-ng/freebusyitemmodel.cpp
@@ -289,10 +289,11 @@ void FreeBusyItemModel::setFreeBusyPeriods( const QModelIndex &parent,
 
 void FreeBusyItemModel::clear()
 {
+  beginResetModel();
   mFreeBusyItems.clear();
   delete mRootData;
   mRootData = new ItemPrivateData( 0 );
-  reset();
+  endResetModel();
 }
 
 void IncidenceEditorNG::FreeBusyItemModel::removeRow( int row )
diff --git a/incidenceeditor-ng/incidencedialog.cpp b/incidenceeditor-ng/incidencedialog.cpp
index dc82880..440fb54 100644
--- a/incidenceeditor-ng/incidencedialog.cpp
+++ b/incidenceeditor-ng/incidencedialog.cpp
@@ -173,7 +173,7 @@ IncidenceDialogPrivate::IncidenceDialogPrivate( Akonadi::IncidenceChanger *chang
   mIeAttendee->setParent(qq);
   mEditor->combine( mIeAttendee );
 
-  mIeResource = new IncidenceResource( mIeAttendee, mUi );
+  mIeResource = new IncidenceResource( mIeAttendee, mIeDateTime, mUi );
   mEditor->combine( mIeResource );
 
   q->connect( mEditor, SIGNAL(showMessage(QString,KMessageWidget::MessageType)),
diff --git a/incidenceeditor-ng/incidenceresource.cpp b/incidenceeditor-ng/incidenceresource.cpp
index bf50b78..87eb89b 100644
--- a/incidenceeditor-ng/incidenceresource.cpp
+++ b/incidenceeditor-ng/incidenceresource.cpp
@@ -21,6 +21,7 @@
 #include "resourcemanagement.h"
 #include "resourcemodel.h"
 #include "attendeecomboboxdelegate.h"
+#include "incidencedatetime.h"
 
 #ifdef KDEPIM_MOBILE_UI
 #include "ui_dialogmoremobile.h"
@@ -57,19 +58,26 @@ public:
 };
 
 #ifdef KDEPIM_MOBILE_UI
-IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrTodoMore *ui)
+IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, IncidenceDateTime *dateTime, Ui::EventOrTodoMore *ui)
 #else
-IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrTodoDesktop *ui)
+IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, IncidenceDateTime *dateTime, Ui::EventOrTodoDesktop *ui)
 #endif
     : IncidenceEditor(0)
     , mUi(ui)
     , dataModel(ieAttendee->dataModel())
+    , mDateTime(dateTime)
     , resourceDialog(new ResourceManagement())
 {
     setObjectName("IncidenceResource");
     connect(resourceDialog, SIGNAL(okClicked()),
             SLOT(dialogOkPressed()));
 
+    connect( mDateTime, SIGNAL(startDateChanged(QDate)),
+             SLOT(slotDateChanged()) );
+    connect( mDateTime, SIGNAL(endDateChanged(QDate)),
+             SLOT(slotDateChanged()) );
+
+
 #ifndef KDEPIM_MOBILE_UI
     QStringList attrs;
     attrs << QLatin1String("cn") <<  QLatin1String("mail");
@@ -114,9 +122,15 @@ IncidenceResource::IncidenceResource(IncidenceAttendee* ieAttendee, Ui::EventOrT
 
 void IncidenceResource::load(const KCalCore::Incidence::Ptr &incidence)
 {
-  //all logic inside IncidenceAtendee (using same model)
+    slotDateChanged();
 }
 
+void IncidenceResource::slotDateChanged()
+{
+    resourceDialog->slotDateChanged(mDateTime->startDate(), mDateTime->endDate());
+}
+
+
 void IncidenceResource::save(const KCalCore::Incidence::Ptr &incidence)
 {
   //all logic inside IncidenceAtendee (using same model)
diff --git a/incidenceeditor-ng/incidenceresource.h b/incidenceeditor-ng/incidenceresource.h
index 9d9dd43..67c7208 100644
--- a/incidenceeditor-ng/incidenceresource.h
+++ b/incidenceeditor-ng/incidenceresource.h
@@ -42,9 +42,9 @@ class INCIDENCEEDITORS_NG_EXPORT IncidenceResource : public IncidenceEditor
     Q_OBJECT
 public:
 #ifdef KDEPIM_MOBILE_UI
-    explicit IncidenceResource(IncidenceAttendee* mIeAttendee, Ui::EventOrTodoMore *ui);
+    explicit IncidenceResource(IncidenceAttendee* mIeAttendee, IncidenceDateTime *dateTime, Ui::EventOrTodoMore *ui);
 #else
-    explicit IncidenceResource(IncidenceAttendee* mIeAttendee,  Ui::EventOrTodoDesktop *ui);
+    explicit IncidenceResource(IncidenceAttendee* mIeAttendee, IncidenceDateTime *dateTime, Ui::EventOrTodoDesktop *ui);
 #endif
 
     void load(const KCalCore::Incidence::Ptr &incidence);
@@ -66,6 +66,8 @@ private slots:
     void layoutChanged();
     void updateCount();
 
+    void slotDateChanged();
+
     void dialogOkPressed();
 private:
 #ifdef KDEPIM_MOBILE_UI
@@ -79,6 +81,7 @@ private:
 
     /** used dataModel to rely on*/
     AttendeeTableModel *dataModel;
+    IncidenceDateTime *mDateTime;
 
     ResourceManagement* resourceDialog;
 };
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index 582f89d..b69d2bb 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -29,6 +29,12 @@
 
 #include "freebusyganttproxymodel.h"
 
+#include <calendarviews/agenda/agendaview.h>
+#include <calendarviews/agenda/viewcalendar.h>
+
+#include <KCalCore/Event>
+#include <KCalCore/MemoryCalendar>
+
 #include <kdgantt2/kdganttgraphicsview.h>
 #include <kdgantt2/kdganttview.h>
 #include <kdgantt2/kdganttdatetimegrid.h>
@@ -43,116 +49,69 @@
 #include <QSplitter>
 #include <QStringList>
 #include <QLabel>
-
+#include <QColor>
 
 #include <KDebug>
-
+#include <KSystemTimeZones>
 
 using namespace IncidenceEditorNG;
 
-class RowController : public KDGantt::AbstractRowController
-{
-  private:
-    static const int ROW_HEIGHT ;
-    QPointer<QAbstractItemModel> m_model;
-
-  public:
-    RowController()
-    {
-      mRowHeight = 20;
-    }
-
-    void setModel( QAbstractItemModel *model )
-    {
-      m_model = model;
-    }
-
-    /*reimp*/
-    int headerHeight() const
-    {
-      return mRowHeight + 10;
-    }
-
-    /*reimp*/
-    bool isRowVisible( const QModelIndex & ) const
-    {
-      return true;
-    }
-
-    /*reimp*/
-    bool isRowExpanded( const QModelIndex & ) const
-    {
-      return false;
-    }
-
-    /*reimp*/
-    KDGantt::Span rowGeometry( const QModelIndex &idx ) const
-    {
-      return KDGantt::Span( idx.row() * mRowHeight, mRowHeight );
-    }
+enum FbStatus {
+    Unkown,
+    Free,
+    Busy,
+    Tentative
+};
 
-    /*reimp*/
-    int maximumItemHeight() const
+class FreebusyViewCalendar : public EventViews::ViewCalendar
+{
+public:
+    virtual ~FreebusyViewCalendar() {};
+    virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const
     {
-      return mRowHeight*6/8;
+        return incidence->uid().startsWith("fb-");
     }
 
-    /*reimp*/
-    int totalHeight() const
+    virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const
     {
-      return m_model->rowCount() * mRowHeight;
+        Q_UNUSED(incidence);
+        return QLatin1String("Freebusy");
     }
 
-    /*reimp*/
-    QModelIndex indexAt( int height ) const
+    virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const
     {
-      return m_model->index( height / mRowHeight, 0 );
-    }
+        bool ok = false;
+        int status = incidence->customProperty("FREEBUSY", "STATUS").toInt(&ok);
 
-    /*reimp*/
-    QModelIndex indexBelow( const QModelIndex &idx ) const
-    {
-      if ( !idx.isValid() ) {
-        return QModelIndex();
-      }
-      return idx.model()->index( idx.row() + 1, idx.column(), idx.parent() );
-    }
+        if (!ok) {
+            return QColor("#555");
+        }
 
-    /*reimp*/
-    QModelIndex indexAbove( const QModelIndex &idx ) const
-    {
-      if ( !idx.isValid() ) {
-        return QModelIndex();
-      }
-      return idx.model()->index( idx.row() - 1, idx.column(), idx.parent() );
+        switch (status) {
+        case Busy:
+            return QColor("#f00");
+        case Tentative:
+            return QColor("#f70");
+        case Free:
+            return QColor("#0f0");
+        default:
+            return QColor("#555");
+        }
     }
 
-    void setRowHeight( int height )
+    virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const
     {
-      mRowHeight = height;
+        return QString();
     }
 
-  private:
-    int mRowHeight;
-
-};
-
-class GanttHeaderView : public QHeaderView
-{
-public:
-    explicit GanttHeaderView( QWidget *parent = 0 ) : QHeaderView( Qt::Horizontal, parent )
+    virtual KCalCore::Calendar::Ptr getCalendar() const
     {
+        return mCalendar;
     }
 
-    QSize sizeHint() const
-    {
-        QSize s = QHeaderView::sizeHint();
-        s.rheight() *= 2;
-        return s;
-    }
+    KCalCore::Calendar::Ptr mCalendar;
 };
 
-
 ResourceManagement::ResourceManagement()
 {
     setButtonText(KDialog::Ok, i18nc("@action:button add resource to attendeelist", "Book resource"));
@@ -164,36 +123,26 @@ ResourceManagement::ResourceManagement()
     setMainWidget( w );
 
     QVariantList list;
-    mModel = new FreeBusyItemModel;
-#ifndef KDEPIM_MOBILE_UI
-
-    KDGantt::GraphicsView *mGanttGraphicsView = new KDGantt::GraphicsView( this );
-    mGanttGraphicsView->setObjectName( "mGanttGraphicsView" );
-    mGanttGraphicsView->setToolTip(
-        i18nc( "@info:tooltip",
-            "Shows the Free/Busy status of a resource.") );
-    mGanttGraphicsView->setWhatsThis(
-        i18nc( "@info:whatsthis",
-            "Shows the Free/Busy status of a resource.") );
-    FreeBusyGanttProxyModel *model = new FreeBusyGanttProxyModel( this );
-    model->setSourceModel( mModel );
-
-    RowController *mRowController = new RowController;
-    mRowController->setRowHeight( fontMetrics().height()*4 );   //TODO: detect
-
-    mRowController->setModel( model );
-    mGanttGraphicsView->setRowController( mRowController );
-
-    KDGantt::DateTimeGrid *mGanttGrid = new KDGantt::DateTimeGrid;
-    mGanttGrid->setScale( KDGantt::DateTimeGrid::ScaleDay );
-    mGanttGrid->setDayWidth( 300 );
-    mGanttGrid->setRowSeparators( true );
-    mGanttGraphicsView->setGrid( mGanttGrid );
-    mGanttGraphicsView->setModel( model );
-    mGanttGraphicsView->viewport()->setFixedWidth( 300 * 30 );
-
-    mUi->resourceCalender->addWidget( mGanttGraphicsView );
-#endif
+    mModel = new FreeBusyItemModel(this);
+
+    connect(mModel, SIGNAL(layoutChanged()), SLOT(slotFbModelLayoutChanged()));
+    connect(mModel, SIGNAL(modelReset()), SLOT(slotFbModelLayoutChanged()));
+    connect(mModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+                    SLOT(slotFbModelRowsRemoved(QModelIndex,int,int)));
+    connect(mModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                    SLOT(slotFbModelRowsAdded(QModelIndex,int,int)));
+    connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                    SLOT(slotFbModelRowsChanged(QModelIndex,QModelIndex)));
+
+    mAgendaView = new EventViews::AgendaView(QDate(), QDate(), false,  false);
+
+    KCalCore::Calendar::Ptr cal = KCalCore::Calendar::Ptr(new KCalCore::MemoryCalendar(KSystemTimeZones::local()));
+    FreebusyViewCalendar *fbCalendar = new FreebusyViewCalendar();
+    fbCalendar->mCalendar = cal;
+    mFbCalendar = EventViews::ViewCalendar::Ptr(fbCalendar);
+    mAgendaView->addCalendar(mFbCalendar);
+
+    mUi->resourceCalender->addWidget( mAgendaView );
 
     QStringList attrs;
     attrs << QLatin1String("cn") << QLatin1String("mail")
@@ -202,7 +151,7 @@ ResourceManagement::ResourceManagement()
     ResourceModel *resourcemodel = new ResourceModel(attrs);
     mUi->treeResults->setModel(resourcemodel);
 
-    // This doesn't work till now :( -> that's why i use the clieck signal
+    // This doesn't work till now :( -> that's why i use the click signal
     mUi->treeResults->setSelectionMode(QAbstractItemView::SingleSelection);
     selectionModel = mUi->treeResults->selectionModel();
 
@@ -212,19 +161,20 @@ ResourceManagement::ResourceManagement()
     connect(mUi->treeResults, SIGNAL(clicked(const QModelIndex &)),
             SLOT(slotShowDetails(const QModelIndex &)));
 
-    Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
-    connect( m, SIGNAL(freeBusyRetrieved(KCalCore::FreeBusy::Ptr,QString)),
-        SLOT(slotInsertFreeBusy(KCalCore::FreeBusy::Ptr,QString)) );
-
     connect(resourcemodel,SIGNAL(layoutChanged()),SLOT(slotLayoutChanged()));
 }
 
+ResourceManagement::~ResourceManagement()
+{
+    delete mModel;
+}
+
+
 ResourceItem::Ptr ResourceManagement::selectedItem() const
 {
     return mSelectedItem;
 }
 
-
 void ResourceManagement::slotStartSearch(const QString &text)
 {
     ((ResourceModel*)mUi->treeResults->model())->startSearch(text);
@@ -237,7 +187,6 @@ void ResourceManagement::slotShowDetails(const QModelIndex & current)
     showDetails(item->ldapObject(), item->ldapClient());
 }
 
-
 void ResourceManagement::showDetails(const KLDAP::LdapObject &obj, const KLDAP::LdapClient &client)
 {
     // Clean up formDetails
@@ -294,6 +243,8 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj, const KLDAP::
     FreeBusyItem::Ptr freebusy( new FreeBusyItem( attendee, this ));
     mModel->clear();
     mModel->addItem(freebusy);
+
+
 }
 
 void ResourceManagement::slotLayoutChanged()
@@ -342,10 +293,88 @@ void ResourceManagement::slotOwnerSearchFinished()
               }
           } else {
               mUi->formOwner->addRow(translateLDAPAttributeForDisplay(key), new QLabel(list.join("\n")));
-            }
+          }
       }
 
 }
 
+void ResourceManagement::slotDateChanged(QDate start, QDate end)
+{
+    int days = start.daysTo(end);
+    if (days < 7) {
+        end = start.addDays(7);
+    }
+    mAgendaView->showDates(start, end);
+}
+
+void ResourceManagement::slotFbModelLayoutChanged()
+{
+    if (mFbEvent.count() > 0) {
+        mFbCalendar->getCalendar()->deleteAllEvents();
+        mFbEvent.clear();
+        for (int i = mModel->rowCount()-1; i>=0; i--) {
+            QModelIndex parent = mModel->index(i, 0);
+            slotFbModelRowsAdded(parent, 0, mModel->rowCount(parent)-1);
+        }
+    }
+}
+
+void ResourceManagement::slotFbModelRowsAdded(const QModelIndex &parent, int first, int last)
+{
+    if (!parent.isValid()) {
+        return;
+    }
+    for(int i=first; i<=last; i++) {
+        QModelIndex index = mModel->index(i, 0, parent);
+
+        const KCalCore::FreeBusyPeriod &period = mModel->data(index, FreeBusyItemModel::FreeBusyPeriodRole).value<KCalCore::FreeBusyPeriod>();
+        const KCalCore::Attendee::Ptr &attendee = mModel->data(parent, FreeBusyItemModel::AttendeeRole).value<KCalCore::Attendee::Ptr>();
+        const KCalCore::FreeBusy::Ptr &fb = mModel->data(parent, FreeBusyItemModel::FreeBusyRole).value<KCalCore::FreeBusy::Ptr>();
+
+        KCalCore::Event::Ptr inc = KCalCore::Event::Ptr(new KCalCore::Event());
+        inc->setDtStart(period.start());
+        inc->setDtEnd(period.end());
+        inc->setUid(QLatin1String("fb-") + fb->uid());
+        //TODO: set to correct status if it is added to KCalCore
+        inc->setCustomProperty("FREEBUSY", "STATUS", QString::number(Busy));
+        inc->setSummary(period.summary().isEmpty()? i18n("Busy") : period.summary());
+
+        mFbEvent.insert(index, inc);
+        mFbCalendar->getCalendar()->addEvent(inc);
+
+    }
+}
+
+void ResourceManagement::slotFbModelRowsRemoved(const QModelIndex &parent, int first, int last)
+{
+    if (!parent.isValid()) {
+        for (int i = first; i<=last; i--) {
+            QModelIndex index = mModel->index(i, 0);
+            slotFbModelRowsRemoved(index, 0, mModel->rowCount(index)-1);
+        }
+    } else {
+        for(int i=first; i<=last; i++) {
+            QModelIndex index = mModel->index(i, 0, parent);
+            KCalCore::Event::Ptr inc = mFbEvent.take(index);
+            mFbCalendar->getCalendar()->deleteEvent(inc);
+        }
+    }
+}
+
+void ResourceManagement::slotFbModelRowsChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
+{
+    if (!topLeft.parent().isValid()) {
+        return;
+    }
+    for (int i = topLeft.row(); i <= bottomRight.row(); i++) {
+        QModelIndex index = mModel->index(i, 0, topLeft.parent());
+        KCalCore::Event::Ptr inc = mFbEvent.value(index);
+        mFbCalendar->getCalendar()->beginChange(inc);
+        mFbCalendar->getCalendar()->endChange(inc);
+    }
+}
+
+
+
 
 #include "resourcemanagement.moc"
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
index 6929547..ee8dc19 100644
--- a/incidenceeditor-ng/resourcemanagement.h
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -30,7 +30,9 @@
 #include "freebusyitemmodel.h"
 #include "resourceitem.h"
 
-# include <KCalCore/FreeBusy>
+#include <calendarviews/agenda/viewcalendar.h>
+
+#include <KCalCore/FreeBusy>
 #include <KDialog>
 
 #include <QStringList>
@@ -38,6 +40,11 @@
 
 class  Ui_resourceManagement;
 
+namespace EventViews
+{
+    class AgendaView;
+}
+
 namespace IncidenceEditorNG
 {
 
@@ -48,9 +55,13 @@ class INCIDENCEEDITORS_NG_EXPORT ResourceManagement : public KDialog
     Q_OBJECT
 public:
     ResourceManagement();
+    ~ResourceManagement();
 
     ResourceItem::Ptr selectedItem() const;
 
+public slots:
+    void slotDateChanged(QDate start, QDate end);
+
 private:
     /* Shows the details of a resource
      *
@@ -77,11 +88,19 @@ private slots:
 
     void slotLayoutChanged();
 
+    void slotFbModelLayoutChanged();
+    void slotFbModelRowsRemoved(const QModelIndex &parent, int first, int last);
+    void slotFbModelRowsAdded(const QModelIndex &parent, int first, int last);
+    void slotFbModelRowsChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
 private:
     FreeBusyItemModel *mModel;
     ResourceItem::Ptr mOwnerItem;
     ResourceItem::Ptr mSelectedItem;
+    EventViews::ViewCalendar::Ptr mFbCalendar;
     Ui_resourceManagement *mUi;
+    QMap<QModelIndex,KCalCore::Event::Ptr> mFbEvent;
+    EventViews::AgendaView *mAgendaView;
 };
 
 }


commit 4bfba620dfa96975fe153192f244350dcc25a49f
Author: Sandro Knauß <knauss at kolabsys.com>
Date:   Mon Sep 15 16:25:04 2014 +0200

    strip out Akonadi::Item off Agendaview

diff --git a/calendarviews/CMakeLists.txt b/calendarviews/CMakeLists.txt
index 516233f..9dff9a8 100644
--- a/calendarviews/CMakeLists.txt
+++ b/calendarviews/CMakeLists.txt
@@ -53,6 +53,7 @@ set(eventviews_LIB_SRCS
   agenda/timelabels.cpp
   agenda/timelabelszone.cpp
   agenda/timescaleconfigdialog.cpp
+  agenda/viewcalendar.cpp
 
   journal/journalframe.cpp
   journal/journalview.cpp
diff --git a/calendarviews/agenda/agenda.cpp b/calendarviews/agenda/agenda.cpp
index 01c3d8d..6aace12 100644
--- a/calendarviews/agenda/agenda.cpp
+++ b/calendarviews/agenda/agenda.cpp
@@ -29,7 +29,7 @@
 #include "agenda.h"
 #include "agendaitem.h"
 #include "agendaview.h"
-#include "helper.h"
+#include "viewcalendar.h"
 #include "prefs.h"
 
 #include <Akonadi/Calendar/ETMCalendar>
@@ -207,7 +207,7 @@ class Agenda::Private
              int columns, int rows, int rowSize, bool isInteractive )
       : mAgendaView( agendaView ), mScrollArea( scrollArea ), mAllDayMode( false ),
         mColumns( columns ), mRows( rows ), mGridSpacingX( 0.0 ), mGridSpacingY( rowSize ),
-        mDesiredGridSpacingY( rowSize ), mCalendar( 0 ), mChanger( 0 ),
+        mDesiredGridSpacingY( rowSize ), mChanger( 0 ),
         mResizeBorderWidth( 0 ), mScrollBorderWidth( 0 ), mScrollDelay( 0 ), mScrollOffset( 0 ),
         mWorkingHoursEnable( false ), mHolidayMask( 0 ), mWorkingHoursYTop( 0 ),
         mWorkingHoursYBottom( 0 ), mHasSelection( 0 ), mSelectedId( -1 ), mMarcusBains( 0 ),
@@ -225,15 +225,15 @@ class Agenda::Private
       return mAgendaView->preferences();
     }
 
-    bool isQueuedForDeletion( Akonadi::Item::Id id ) const
+    bool isQueuedForDeletion( const QString &uid ) const
     {
       // if mAgendaItemsById contains it it means that a createAgendaItem() was called
       // before the previous agenda items were deleted.
-      return mItemsQueuedForDeletion.contains( id ) && !mAgendaItemsById.contains( id );
+      return mItemsQueuedForDeletion.contains( uid ) && !mAgendaItemsById.contains( uid );
     }
 
-    QMultiHash<Akonadi::Item::Id, AgendaItem::QPtr> mAgendaItemsById; // It's a QMultiHash because recurring incidences might have many agenda items
-    QSet<Akonadi::Item::Id> mItemsQueuedForDeletion;
+    QMultiHash<QString, AgendaItem::QPtr> mAgendaItemsById; // It's a QMultiHash because recurring incidences might have many agenda items
+    QSet<QString> mItemsQueuedForDeletion;
 
     AgendaView *mAgendaView;
     QScrollArea *mScrollArea;
@@ -251,8 +251,6 @@ class Agenda::Private
     double mGridSpacingY;
     double mDesiredGridSpacingY;
 
-    // We need the calendar for drag'n'drop and for paint the ResourceColor
-    Akonadi::ETMCalendar::Ptr mCalendar;
     Akonadi::IncidenceChanger *mChanger;
 
     // size of border, where mouse action will resize the AgendaItem
@@ -293,10 +291,10 @@ class Agenda::Private
 
     // Currently selected item
     QPointer<AgendaItem> mSelectedItem;
-    // Id of the last selected item. Used for reselecting in situations
+    // Uid of the last selected incidence. Used for reselecting in situations
     // where the selected item points to a no longer valid incidence, for
     // example during resource reload.
-    Akonadi::Item::Id mSelectedId;
+    QString mSelectedId;
 
     // The Marcus Bains Line widget.
     MarcusBains *mMarcusBains;
@@ -314,6 +312,8 @@ class Agenda::Private
 
     bool mReturnPressed;
     bool mIsInteractive;
+
+    MultiViewCalendar::Ptr mCalendar;
 };
 
 /*
@@ -349,9 +349,9 @@ Agenda::~Agenda()
   delete d;
 }
 
-Akonadi::Item Agenda::selectedIncidence() const
+KCalCore::Incidence::Ptr Agenda::selectedIncidence() const
 {
-  return d->mSelectedItem ? d->mSelectedItem->incidence() : Akonadi::Item();
+  return d->mSelectedItem ? d->mSelectedItem->incidence() : KCalCore::Incidence::Ptr();
 }
 
 QDate Agenda::selectedIncidenceDate() const
@@ -359,7 +359,7 @@ QDate Agenda::selectedIncidenceDate() const
   return d->mSelectedItem ? d->mSelectedItem->occurrenceDate() : QDate();
 }
 
-Akonadi::Item::Id Agenda::lastSelectedItemId() const
+QString Agenda::lastSelectedItemId() const
 {
   return d->mSelectedId;
 }
@@ -583,7 +583,7 @@ bool Agenda::eventFilter_drag( QObject *obj, QDropEvent *de )
 
     const QList<KUrl> incidenceUrls = CalendarSupport::incidenceItemUrls( md );
     const KCalCore::Incidence::List incidences =
-      CalendarSupport::incidences( md, d->mCalendar->timeSpec() );
+      CalendarSupport::incidences( md, d->mCalendar->mETMCalendar->timeSpec() );
 
     Q_ASSERT( !incidenceUrls.isEmpty() || !incidences.isEmpty() );
 
@@ -674,8 +674,7 @@ bool Agenda::eventFilter_mouse( QObject *object, QMouseEvent *me )
       } else {
         AgendaItem::QPtr item = dynamic_cast<AgendaItem *>(object);
         if (item) {
-          const Akonadi::Item aitem = item->incidence();
-          KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( aitem );
+          KCalCore::Incidence::Ptr incidence = item->incidence();
           if ( incidence->isReadOnly() ) {
             d->mActionItem = 0;
           } else {
@@ -736,8 +735,7 @@ bool Agenda::eventFilter_mouse( QObject *object, QMouseEvent *me )
     QPoint indicatorPos = gridToContents( contentsToGrid( viewportPos ) );
     if ( object != this ) {
       AgendaItem::QPtr moveItem = dynamic_cast<AgendaItem *>( object );
-      const Akonadi::Item aitem = moveItem ? moveItem->incidence() : Akonadi::Item();
-      KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( aitem );
+      KCalCore::Incidence::Ptr incidence =  moveItem ? moveItem->incidence() : KCalCore::Incidence::Ptr();
       if ( incidence && !incidence->isReadOnly() ) {
         if ( !d->mActionItem ) {
           setNoActionCursor( moveItem, viewportPos );
@@ -1165,8 +1163,7 @@ void Agenda::endItemAction()
 
   bool multiModify = false;
   // FIXME: do the cloning here...
-  Akonadi::Item inc = d->mActionItem->incidence();
-  const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( inc );
+  const KCalCore::Incidence::Ptr incidence = d->mActionItem->incidence();
   d->mItemMoved = d->mItemMoved && !( d->mStartCell.x() == d->mEndCell.x() &&
                                       d->mStartCell.y() == d->mEndCell.y() );
 
@@ -1174,8 +1171,7 @@ void Agenda::endItemAction()
   if ( d->mItemMoved ) {
     bool modify = false;
     if ( incidence->recurs() ) {
-      const int res = d->mAgendaView->showMoveRecurDialog(
-        CalendarSupport::incidence( d->mActionItem->incidence() ), d->mActionItem->occurrenceDate() );
+      const int res = d->mAgendaView->showMoveRecurDialog( d->mActionItem->incidence(), d->mActionItem->occurrenceDate() );
       switch ( res ) {
       case KCalUtils::RecurrenceActions::AllOccurrences: // All occurrences
         // Moving the whole sequene of events is handled by the itemModified below.
@@ -1194,9 +1190,7 @@ void Agenda::endItemAction()
           // don't recreate items, they already have the correct position
           d->mAgendaView->enableAgendaUpdate( false );
 
-          Akonadi::Item item;
-          item.setPayload( newInc );
-          d->mActionItem->setIncidence( item );
+          d->mActionItem->setIncidence( newInc );
           d->mActionItem->dissociateFromMultiItem();
 
           addIncidence = true;
@@ -1248,8 +1242,10 @@ void Agenda::endItemAction()
       // calling when we move item.
       // Not perfect need to improve it!
       //mChanger->endChange( inc );
-      d->mAgendaView->updateEventDates( modif, addIncidence, inc.parentCollection().id() );
-
+      Akonadi::Item item = d->mCalendar->item(incidence);
+      if (item.isValid()) {
+        d->mAgendaView->updateEventDates( modif, addIncidence, item.parentCollection().id() );
+      }
       if ( addIncidence ) {
         // delete the one we dragged, there's a new one being added async, due to dissociation.
         delete modif;
@@ -1257,7 +1253,10 @@ void Agenda::endItemAction()
     } else {
       // the item was moved, but not further modified, since it's not recurring
       // make sure the view updates anyhow, with the right item
-      d->mAgendaView->updateEventDates( placeItem, addIncidence, inc.parentCollection().id() );
+      Akonadi::Item item = d->mCalendar->item(incidence);
+      if (item.isValid()) {
+        d->mAgendaView->updateEventDates( placeItem, addIncidence, item.parentCollection().id() );
+      }
     }
   }
 
@@ -1296,7 +1295,7 @@ void Agenda::setActionCursor( int actionType, bool acting )
 
 void Agenda::setNoActionCursor( AgendaItem::QPtr moveItem, const QPoint &pos )
 {
-  const Akonadi::Item item = moveItem ? moveItem->incidence() : Akonadi::Item();
+  const KCalCore::Incidence::Ptr item = moveItem ? moveItem->incidence() : KCalCore::Incidence::Ptr();
 
   const bool noResize = CalendarSupport::hasTodo( item );
 
@@ -1697,7 +1696,7 @@ void Agenda::setStartTime( const QTime &startHour )
 /*
   Insert AgendaItem into agenda.
 */
-AgendaItem::QPtr Agenda::insertItem( const Akonadi::Item &incidence, const KDateTime &qd,
+AgendaItem::QPtr Agenda::insertItem( const KCalCore::Incidence::Ptr &incidence, const KDateTime &qd,
                                      int X, int YTop, int YBottom, int itemPos, int itemCount,
                                      bool isSelected )
 {
@@ -1724,8 +1723,7 @@ AgendaItem::QPtr Agenda::insertItem( const Akonadi::Item &incidence, const KDate
                       int( ( YBottom + 1 ) * d->mGridSpacingY ) );
   agendaItem->setCellXY( X, YTop, YBottom );
   agendaItem->setCellXRight( X );
-  agendaItem->setResourceColor( EventViews::resourceColor( incidence,
-                                                           d->preferences() ) );
+  agendaItem->setResourceColor(d->mCalendar->resourceColor(incidence));
   agendaItem->installEventFilter( this );
 
   agendaItem->move( int( X * d->mGridSpacingX ), int( YTop * d->mGridSpacingY ) );
@@ -1744,7 +1742,7 @@ AgendaItem::QPtr Agenda::insertItem( const Akonadi::Item &incidence, const KDate
 /*
   Insert all-day AgendaItem into agenda.
 */
-AgendaItem::QPtr Agenda::insertAllDayItem( const Akonadi::Item &incidence, const KDateTime &occurrenceDateTime,
+AgendaItem::QPtr Agenda::insertAllDayItem( const KCalCore::Incidence::Ptr &incidence, const KDateTime &occurrenceDateTime,
                                            int XBegin, int XEnd, bool isSelected )
 {
   if ( !d->mAllDayMode ) {
@@ -1769,8 +1767,7 @@ AgendaItem::QPtr Agenda::insertAllDayItem( const Akonadi::Item &incidence, const
   agendaItem->resize( int( endIt ) - int( startIt ), int( d->mGridSpacingY ) );
 
   agendaItem->installEventFilter( this );
-  agendaItem->setResourceColor( EventViews::resourceColor( incidence,
-                                                           d->preferences() ) );
+  agendaItem->setResourceColor(d->mCalendar->resourceColor(incidence));
   agendaItem->move( int( XBegin * d->mGridSpacingX ), 0 ) ;
   d->mItems.append( agendaItem );
 
@@ -1781,26 +1778,26 @@ AgendaItem::QPtr Agenda::insertAllDayItem( const Akonadi::Item &incidence, const
   return agendaItem;
 }
 
-AgendaItem::QPtr Agenda::createAgendaItem( const Akonadi::Item &item, int itemPos,
+AgendaItem::QPtr Agenda::createAgendaItem( const KCalCore::Incidence::Ptr &incidence, int itemPos,
                                            int itemCount, const KDateTime &qd, bool isSelected )
 {
-  if ( !item.isValid() ) {
+  if ( !incidence ) {
     kWarning() << "Agenda::createAgendaItem() item is invalid.";
     return AgendaItem::QPtr();
   }
 
-  AgendaItem::QPtr agendaItem = new AgendaItem( d->mAgendaView, d->mCalendar, item,
+  AgendaItem::QPtr agendaItem = new AgendaItem( d->mAgendaView, d->mCalendar, incidence,
                                                 itemPos, itemCount, qd, isSelected, this );
 
   connect( agendaItem, SIGNAL(removeAgendaItem(AgendaItem::QPtr)), SLOT(removeAgendaItem(AgendaItem::QPtr)) );
   connect( agendaItem, SIGNAL(showAgendaItem(AgendaItem::QPtr)), SLOT(showAgendaItem(AgendaItem::QPtr)) );
 
-  d->mAgendaItemsById.insert( item.id(), agendaItem );
+  d->mAgendaItemsById.insert( incidence->uid(), agendaItem );
 
   return agendaItem;
 }
 
-void Agenda::insertMultiItem( const Akonadi::Item &event, const KDateTime &occurrenceDateTime, int XBegin,
+void Agenda::insertMultiItem( const KCalCore::Incidence::Ptr &event, const KDateTime &occurrenceDateTime, int XBegin,
                               int XEnd, int YTop, int YBottom, bool isSelected )
 {
   KCalCore::Event::Ptr ev = CalendarSupport::event( event );
@@ -1873,26 +1870,19 @@ void Agenda::removeIncidence( const KCalCore::Incidence::Ptr &incidence )
     return;
   }
 
-  // we get the id from the property, because the item might have been deleted from the etm/mCalendar
-  bool ok = false;
-  Akonadi::Item::Id id = incidence->customProperty( "VOLATILE", "AKONADI-ID" ).toLongLong( &ok );
-
-  if ( id == -1 || !ok ) {
-    id = d->mCalendar->item( incidence->instanceIdentifier() ).id();
-
-    if ( id == -1 ) {
+  /*
+  if ( !d->mViewCalendar->item(incidence).isValid() ) {
       // Ok, we really don't know the ID, give up.
       kWarning() << "Agenda::removeIncidence() Item to remove is invalid. uid = "
                  << incidence->instanceIdentifier();
       return;
-    }
-  }
+  } */
 
-  if ( d->isQueuedForDeletion( id ) ) {
+  if ( d->isQueuedForDeletion( incidence->uid() ) ) {
     return; // It's already queued for deletion
   }
 
-  AgendaItem::List agendaItems = d->mAgendaItemsById.values( id );
+  AgendaItem::List agendaItems = d->mAgendaItemsById.values( incidence->uid() );
   if ( agendaItems.isEmpty() ) {
     // We're not displaying such item
     // kDebug() << "Ignoring";
@@ -1933,7 +1923,7 @@ bool Agenda::removeAgendaItem( AgendaItem::QPtr agendaItem )
   // removeChild( thisItem );
 
   taken = d->mItems.removeAll( agendaItem ) > 0;
-  d->mAgendaItemsById.remove( agendaItem->incidence().id(), agendaItem );
+  d->mAgendaItemsById.remove( agendaItem->incidence()->uid(), agendaItem );
 
   QList<AgendaItem::QPtr>::iterator it;
   for ( it = conflictItems.begin(); it != conflictItems.end(); ++it ) {
@@ -1949,7 +1939,7 @@ bool Agenda::removeAgendaItem( AgendaItem::QPtr agendaItem )
     }
   }
   d->mItemsToDelete.append( agendaItem );
-  d->mItemsQueuedForDeletion.insert( agendaItem->incidence().id() );
+  d->mItemsQueuedForDeletion.insert( agendaItem->incidence()->uid() );
   agendaItem->setVisible( false );
   QTimer::singleShot( 0, this, SLOT(deleteItemsToDelete()) );
   return taken;
@@ -2132,12 +2122,12 @@ void Agenda::deselectItem()
     return;
   }
 
-  const Akonadi::Item selectedItem = d->mSelectedItem->incidence();
+  const KCalCore::Incidence::Ptr selectedItem = d->mSelectedItem->incidence();
 
   foreach ( AgendaItem::QPtr item, d->mItems ) {
     if ( item ) {
-      const Akonadi::Item itemInc = item->incidence();
-      if( itemInc.isValid() && selectedItem.isValid() && itemInc.id() == selectedItem.id() ) {
+      const KCalCore::Incidence::Ptr itemInc = item->incidence();
+      if( itemInc && selectedItem && itemInc->uid() == selectedItem->uid() ) {
         item->select( false );
       }
     }
@@ -2153,26 +2143,26 @@ void Agenda::selectItem( AgendaItem::QPtr item )
   }
   deselectItem();
   if ( item == 0 ) {
-    emit incidenceSelected( Akonadi::Item(), QDate() );
+    emit incidenceSelected( KCalCore::Incidence::Ptr(), QDate() );
     return;
   }
   d->mSelectedItem = item;
   d->mSelectedItem->select();
-  Q_ASSERT( CalendarSupport::hasIncidence( d->mSelectedItem->incidence() ) );
-  d->mSelectedId = d->mSelectedItem->incidence().id();
+  Q_ASSERT( d->mSelectedItem->incidence() );
+  d->mSelectedId = d->mSelectedItem->incidence()->uid();
 
   foreach ( AgendaItem::QPtr item, d->mItems ) {
-    if( item && item->incidence().id() == d->mSelectedId ) {
+    if( item && item->incidence()->uid() == d->mSelectedId ) {
       item->select();
     }
   }
   emit incidenceSelected( d->mSelectedItem->incidence(), d->mSelectedItem->occurrenceDate() );
 }
 
-void Agenda::selectItemByItemId( const Akonadi::Item::Id &id )
+void Agenda::selectIncidenceByUid( const QString &uid )
 {
   foreach ( AgendaItem::QPtr item, d->mItems ) {
-    if ( item && item->incidence().id() == id ) {
+    if ( item && item->incidence()->uid() == uid ) {
       selectItem( item );
       break;
     }
@@ -2181,7 +2171,7 @@ void Agenda::selectItemByItemId( const Akonadi::Item::Id &id )
 
 void Agenda::selectItem( const Akonadi::Item &item )
 {
-  selectItemByItemId( item.id() );
+  selectIncidenceByUid( CalendarSupport::incidence(item)->uid() );
 }
 
 // This function seems never be called.
@@ -2230,7 +2220,7 @@ KCalCore::DateList Agenda::dateList() const
   return d->mSelectedDates;
 }
 
-void Agenda::setCalendar( const Akonadi::ETMCalendar::Ptr &cal )
+void Agenda::setCalendar( const MultiViewCalendar::Ptr &cal )
 {
   d->mCalendar = cal;
 }
@@ -2269,9 +2259,9 @@ QScrollArea *Agenda::scrollArea() const
   return d->mScrollArea;
 }
 
-AgendaItem::List Agenda::agendaItems( Akonadi::Item::Id id ) const
+AgendaItem::List Agenda::agendaItems( const QString &uid ) const
 {
-  return d->mAgendaItemsById.values( id );
+  return d->mAgendaItemsById.values( uid );
 }
 
 AgendaScrollArea::AgendaScrollArea( bool isAllDay, AgendaView *agendaView,
diff --git a/calendarviews/agenda/agenda.h b/calendarviews/agenda/agenda.h
index e2a2607..e1dd790 100644
--- a/calendarviews/agenda/agenda.h
+++ b/calendarviews/agenda/agenda.h
@@ -27,6 +27,7 @@
 
 #include "eventviews_export.h"
 #include "agendaitem.h"
+#include "viewcalendar.h"
 
 #include <Akonadi/Item>
 
@@ -72,7 +73,7 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
 
     virtual ~Agenda();
 
-    Akonadi::Item selectedIncidence() const;
+    KCalCore::Incidence::Ptr selectedIncidence() const;
     QDate selectedIncidenceDate() const;
     QSize sizeHint() const;
     QSize minimumSizeHint() const;
@@ -93,14 +94,14 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
 
     QScrollArea *scrollArea() const;
 
-    AgendaItem::List agendaItems( Akonadi::Entity::Id id ) const;
+    AgendaItem::List agendaItems( const QString &uid ) const;
 
     /**
       Returns the uid of the last incidence that was selected. This
       persists across reloads and clear, so that if the same uid
       reappears, it can be reselected.
     */
-    Akonadi::Item::Id lastSelectedItemId() const;
+    QString lastSelectedItemId() const;
 
     bool eventFilter ( QObject *, QEvent * );
 
@@ -120,13 +121,13 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
 
     void setStartTime( const QTime &startHour );
 
-    AgendaItem::QPtr insertItem ( const Akonadi::Item &incidence, const KDateTime &occurrenceDateTime, int X, int YTop,
+    AgendaItem::QPtr insertItem ( const KCalCore::Incidence::Ptr &incidence, const KDateTime &occurrenceDateTime, int X, int YTop,
                                   int YBottom, int itemPos, int itemCount, bool isSelected );
 
-    AgendaItem::QPtr insertAllDayItem ( const Akonadi::Item &event, const KDateTime &occurrenceDateTime, int XBegin,
+    AgendaItem::QPtr insertAllDayItem ( const KCalCore::Incidence::Ptr &event, const KDateTime &occurrenceDateTime, int XBegin,
                                         int XEnd, bool isSelected );
 
-    void insertMultiItem ( const Akonadi::Item &event, const KDateTime &occurrenceDateTime, int XBegin, int XEnd,
+    void insertMultiItem ( const KCalCore::Incidence::Ptr &event, const KDateTime &occurrenceDateTime, int XBegin, int XEnd,
                            int YTop, int YBottom, bool isSelected );
 
     /**
@@ -158,7 +159,7 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
     void setDateList( const KCalCore::DateList &selectedDates );
     KCalCore::DateList dateList() const;
 
-    void setCalendar( const Akonadi::ETMCalendar::Ptr &cal );
+    void setCalendar( const EventViews::MultiViewCalendar::Ptr &cal );
 
     void setIncidenceChanger( Akonadi::IncidenceChanger *changer );
 
@@ -186,7 +187,7 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
       @param id the item id of the item that should be selected. If no such
       item exists, the selection is not changed.
     */
-    void selectItemByItemId( const Akonadi::Item::Id &id );
+    void selectIncidenceByUid( const QString &id );
     void selectItem( const Akonadi::Item &item );
 
     bool removeAgendaItem( AgendaItem::QPtr item );
@@ -197,19 +198,19 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
     void newTimeSpanSignal( const QPoint &, const QPoint & );
     void newStartSelectSignal();
 
-    void showIncidenceSignal( const Akonadi::Item & );
-    void editIncidenceSignal( const Akonadi::Item & );
-    void deleteIncidenceSignal( const Akonadi::Item & );
-    void showIncidencePopupSignal( const Akonadi::Item &, const QDate &);
+    void showIncidenceSignal( const KCalCore::Incidence::Ptr & );
+    void editIncidenceSignal( const KCalCore::Incidence::Ptr & );
+    void deleteIncidenceSignal( const KCalCore::Incidence::Ptr & );
+    void showIncidencePopupSignal( const KCalCore::Incidence::Ptr &, const QDate &);
 
     void showNewEventPopupSignal();
 
-    void incidenceSelected( const Akonadi::Item &, const QDate & );
+    void incidenceSelected( const KCalCore::Incidence::Ptr &, const QDate & );
 
     void lowerYChanged( int );
     void upperYChanged( int );
 
-    void startDragSignal( const Akonadi::Item & );
+    void startDragSignal( const KCalCore::Incidence::Ptr & );
     void droppedIncidences( const KCalCore::Incidence::List &, const QPoint &gpos, bool allDay );
     void droppedIncidences( const QList<KUrl> &, const QPoint &gpos, bool allDay );
 
@@ -233,7 +234,7 @@ class EVENTVIEWS_EXPORT Agenda : public QWidget
       RESIZERIGHT
     };
 
-    AgendaItem::QPtr createAgendaItem( const Akonadi::Item &item, int itemPos,
+    AgendaItem::QPtr createAgendaItem( const KCalCore::Incidence::Ptr &item, int itemPos,
                                        int itemCount, const KDateTime &qd, bool isSelected );
 
   protected:
diff --git a/calendarviews/agenda/agendaitem.cpp b/calendarviews/agenda/agendaitem.cpp
index bcb022c..6625dd1 100644
--- a/calendarviews/agenda/agendaitem.cpp
+++ b/calendarviews/agenda/agendaitem.cpp
@@ -22,6 +22,7 @@
 */
 #include "agendaitem.h"
 #include "eventview.h"
+#include "viewcalendar.h"
 #include "helper.h"
 #include "prefs.h"
 #include "prefs_base.h" // for enums
@@ -62,35 +63,32 @@ QPixmap *AgendaItem::eventPxmp = 0;
 
 //-----------------------------------------------------------------------------
 
-AgendaItem::AgendaItem( EventView *eventView, const Akonadi::ETMCalendar::Ptr &calendar,
-                        const Akonadi::Item &item,
+
+AgendaItem::AgendaItem( EventView *eventView, const MultiViewCalendar::Ptr &calendar,
+                        const KCalCore::Incidence::Ptr &item,
                         int itemPos, int itemCount,
                         const KDateTime &qd, bool isSelected, QWidget *parent )
   : QWidget( parent ), mEventView( eventView ), mCalendar( calendar ), mIncidence( item ),
     mOccurrenceDateTime( qd ), mValid( true ), mCloned( false ), mSelected( isSelected ), mSpecialEvent( false )
 {
-  if ( !CalendarSupport::hasIncidence( mIncidence ) ) {
+  if ( !mIncidence ) {
     mValid = false;
     return;
   }
 
-  KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( item );
-  mIncidence.setPayload( KCalCore::Incidence::Ptr( incidence->clone() ) );
-  Q_ASSERT( incidence );
-  if ( incidence->customProperty( "KABC", "BIRTHDAY" ) == QLatin1String("YES") ||
-       incidence->customProperty( "KABC", "ANNIVERSARY" ) == QLatin1String("YES") ) {
-    const int years = EventViews::yearDiff( incidence->dtStart().date(), qd.toTimeSpec( mEventView->preferences()->timeSpec() ).date() );
+  mIncidence = Incidence::Ptr(mIncidence->clone());
+  if ( mIncidence->customProperty( "KABC", "BIRTHDAY" ) == QLatin1String("YES") ||
+       mIncidence->customProperty( "KABC", "ANNIVERSARY" ) == QLatin1String("YES") ) {
+    const int years = EventViews::yearDiff( mIncidence->dtStart().date(), qd.toTimeSpec( mEventView->preferences()->timeSpec() ).date() );
     if ( years > 0 ) {
-      incidence = KCalCore::Incidence::Ptr( incidence->clone() );
-      incidence->setReadOnly( false );
-      incidence->setSummary( i18np( "%2 (1 year)", "%2 (%1 years)", years, incidence->summary() ) );
-      incidence->setReadOnly( true );
+      mIncidence->setReadOnly( false );
+      mIncidence->setSummary( i18np( "%2 (1 year)", "%2 (%1 years)", years, mIncidence->summary() ) );
+      mIncidence->setReadOnly( true );
       mCloned = true;
-      mIncidence.setPayload<KCalCore::Incidence::Ptr>( incidence );
     }
   }
 
-  mLabelText = incidence->summary();
+  mLabelText = mIncidence->summary();
   mIconAlarm = false;
   mIconRecur = false;
   mIconReadonly = false;
@@ -126,20 +124,18 @@ void AgendaItem::updateIcons()
   if ( !mValid ) {
     return;
   }
-  KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( mIncidence );
-  Q_ASSERT( incidence );
-  mIconReadonly = incidence->isReadOnly();
-  mIconRecur = incidence->recurs() || incidence->hasRecurrenceId();
-  mIconAlarm = incidence->hasEnabledAlarms();
-  if ( incidence->attendeeCount() > 1 ) {
-    if ( mEventView->kcalPreferences()->thatIsMe( incidence->organizer()->email() ) ) {
+  mIconReadonly = mIncidence->isReadOnly();
+  mIconRecur = mIncidence->recurs() || mIncidence->hasRecurrenceId();
+  mIconAlarm = mIncidence->hasEnabledAlarms();
+  if ( mIncidence->attendeeCount() > 1 ) {
+    if ( mEventView->kcalPreferences()->thatIsMe( mIncidence->organizer()->email() ) ) {
       mIconReply = false;
       mIconGroup = false;
       mIconGroupTent = false;
       mIconOrganizer = true;
     } else {
       KCalCore::Attendee::Ptr me =
-        incidence->attendeeByMails( mEventView->kcalPreferences()->allEmails() );
+        mIncidence->attendeeByMails( mEventView->kcalPreferences()->allEmails() );
 
       if ( me ) {
         if ( me->status() == KCalCore::Attendee::NeedsAction && me->RSVP() ) {
@@ -207,13 +203,13 @@ bool AgendaItem::dissociateFromMultiItem()
   return true;
 }
 
-void AgendaItem::setIncidence( const Akonadi::Item &incidence )
+void AgendaItem::setIncidence( const KCalCore::Incidence::Ptr &incidence )
 {
   mValid = false;
-  if ( CalendarSupport::hasIncidence( incidence ) ) {
+  if ( incidence ) {
     mValid = true;
     mIncidence = incidence;
-    mLabelText = CalendarSupport::incidence( incidence )->summary();
+    mLabelText = mIncidence->summary();
     updateIcons();
   }
 }
@@ -638,11 +634,10 @@ void AgendaItem::addAttendee( const QString &newAttendee )
     return;
   }
 
-  const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( mIncidence );
   QString name, email;
   KPIMUtils::extractEmailAddressAndName( newAttendee, email, name );
   if ( !( name.isEmpty() && email.isEmpty() ) ) {
-    incidence->addAttendee( KCalCore::Attendee::Ptr( new KCalCore::Attendee( name, email ) ) );
+    mIncidence->addAttendee( KCalCore::Attendee::Ptr( new KCalCore::Attendee( name, email ) ) );
     KMessageBox::information(
       this,
       i18n( "Attendee \"%1\" added to the calendar item \"%2\"",
@@ -667,8 +662,7 @@ void AgendaItem::dropEvent( QDropEvent *e )
   bool decoded = md->hasText();
   QString text = md->text();
   if ( decoded && text.startsWith( QLatin1String( "file:" ) ) ) {
-    const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( mIncidence );
-    incidence->addAttachment( KCalCore::Attachment::Ptr( new KCalCore::Attachment( text ) ) );
+    mIncidence->addAttachment( KCalCore::Attachment::Ptr( new KCalCore::Attachment( text ) ) );
     return;
   }
 
@@ -739,11 +733,10 @@ static void conditionalPaint( QPainter *p, bool condition, int &x, int y,
 void AgendaItem::paintIcon( QPainter *p, int &x, int y, int ft )
 {
   QString iconName;
-  Incidence::Ptr incidence = mIncidence.payload<KCalCore::Incidence::Ptr>();
-  if ( incidence->customProperty( "KABC", "ANNIVERSARY" ) == QLatin1String("YES") ) {
+  if ( mIncidence->customProperty( "KABC", "ANNIVERSARY" ) == QLatin1String("YES") ) {
     mSpecialEvent = true;
     iconName =  QLatin1String("view-calendar-wedding-anniversary");
-  } else if ( incidence->customProperty( "KABC", "BIRTHDAY" ) == QLatin1String("YES") ) {
+  } else if ( mIncidence->customProperty( "KABC", "BIRTHDAY" ) == QLatin1String("YES") ) {
     mSpecialEvent = true;
     // We don't draw icon. The icon is drawn already, because it's the Akonadi::Collection's icon
   }
@@ -762,17 +755,16 @@ void AgendaItem::paintIcons( QPainter *p, int &x, int y, int ft )
   QSet<EventView::ItemIcon> icons = mEventView->preferences()->agendaViewIcons();
 
   if ( icons.contains( EventViews::EventView::CalendarCustomIcon ) ) {
-    const QString iconName = mEventView->iconForItem( mIncidence );
+    const QString iconName = mCalendar->iconForIncidence( mIncidence );
     if ( !iconName.isEmpty() && iconName != QLatin1String("view-calendar") && iconName != QLatin1String("office-calendar") ) {
       conditionalPaint( p, true, x, y, ft, SmallIcon( iconName ) );
     }
   }
 
-  Incidence::Ptr incidence = mIncidence.payload<KCalCore::Incidence::Ptr>();
-  const bool isTodo = incidence && incidence->type() == Incidence::TypeTodo;
+  const bool isTodo = mIncidence && mIncidence->type() == Incidence::TypeTodo;
 
   if ( isTodo && icons.contains( EventViews::EventView::TaskIcon ) ) {
-    const QString iconName = incidence->iconName( mOccurrenceDateTime.toTimeSpec( incidence->dtStart().timeSpec() ) );
+    const QString iconName = mIncidence->iconName( mOccurrenceDateTime.toTimeSpec( mIncidence->dtStart().timeSpec() ) );
     conditionalPaint( p, !mSpecialEvent, x, y, ft, SmallIcon( iconName ) );
   }
 
@@ -860,10 +852,8 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
     }
   }
 
-  const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( mIncidence );
-  Q_ASSERT( incidence );
   QColor categoryColor;
-  const QStringList categories = incidence->categories();
+  const QStringList categories = mIncidence->categories();
   QString cat;
   if ( !categories.isEmpty() ) {
     cat = categories.first();
@@ -939,25 +929,25 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
   QString shortH;
   QString longH;
   if ( !isMultiItem() ) {
-    shortH = KGlobal::locale()->formatTime(incidence->dateTime( KCalCore::Incidence::RoleDisplayStart ).
+    shortH = KGlobal::locale()->formatTime(mIncidence->dateTime( KCalCore::Incidence::RoleDisplayStart ).
              toTimeSpec( mEventView->preferences()->timeSpec() ).time() );
 
     if ( CalendarSupport::hasEvent( mIncidence ) ) {
       longH = i18n( "%1 - %2",
                     shortH,
                     KGlobal::locale()->formatTime(
-                      incidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
+                      mIncidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
                         mEventView->preferences()->timeSpec() ).time() ) );
     } else {
       longH = shortH;
     }
   } else if ( !mMultiItemInfo->mFirstMultiItem ) {
     shortH = KGlobal::locale()->formatTime(
-      incidence->dtStart().toTimeSpec( mEventView->preferences()->timeSpec() ).time() );
+      mIncidence->dtStart().toTimeSpec( mEventView->preferences()->timeSpec() ).time() );
     longH = shortH;
   } else {
     shortH = KGlobal::locale()->formatTime(
-      incidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
+      mIncidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
         mEventView->preferences()->timeSpec() ).time() );
     longH = i18n( "- %1", shortH );
   }
@@ -992,7 +982,7 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
   if ( ( 2 * singleLineHeight ) > ( height() - 2 * margin ) ) {
     int x = margin, txtWidth;
 
-    if ( incidence->allDay() ) {
+    if ( mIncidence->allDay() ) {
       x += visRect.left();
       const int y =  qRound( ( height() - 16 ) / 2.0 );
       paintIcons( &p, x, y, ft );
@@ -1015,7 +1005,7 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
        ( isMultiItem() && mMultiItemInfo->mNextMultiItem && mMultiItemInfo->mFirstMultiItem ) ) {
     int x = margin, txtWidth;
 
-    if ( incidence->allDay() ) {
+    if ( mIncidence->allDay() ) {
       x += visRect.left();
       paintIcons( &p, x, margin, ft );
       txtWidth = visRect.right() - margin - x;
@@ -1041,7 +1031,7 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
 
   int x = margin, txtWidth, hTxtWidth, eventX;
 
-  if ( incidence->allDay() ) {
+  if ( mIncidence->allDay() ) {
     shortH.clear();
     longH.clear();
 
@@ -1051,9 +1041,9 @@ void AgendaItem::paintEvent( QPaintEvent *ev )
         shortH =
           i18n( "%1 - %2",
                 KGlobal::locale()->formatDate(
-                  incidence->dtStart().toTimeSpec( mEventView->preferences()->timeSpec() ).date() ),
+                  mIncidence->dtStart().toTimeSpec( mEventView->preferences()->timeSpec() ).date() ),
                 KGlobal::locale()->formatDate(
-                  incidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
+                  mIncidence->dateTime( KCalCore::Incidence::RoleEnd ).toTimeSpec(
                     mEventView->preferences()->timeSpec() ).date() ) );
         longH = shortH;
 
@@ -1219,12 +1209,9 @@ void AgendaItem::drawRoundedRect( QPainter *p, const QRect &rect,
 
   QLinearGradient gradient( QPointF( r.x(), r.y() ), QPointF( r.x(), r.height() ) );
 
-  const KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( mIncidence );
-  Q_ASSERT( incidence );
-
   if ( r.height() > 50 ) {
-    if ( incidence->allDay() &&
-         incidence->dtStart() == incidence->dateTime( KCalCore::Incidence::RoleEnd ) &&
+    if ( mIncidence->allDay() &&
+         mIncidence->dtStart() == mIncidence->dateTime( KCalCore::Incidence::RoleEnd ) &&
          CalendarSupport::hasEvent( mIncidence ) ) {
       gradient.setColorAt( 0, bgColor.light( 130 ) );
       qreal t = 1.0 - ( r.height() - 18.0 ) / r.height();
@@ -1238,8 +1225,8 @@ void AgendaItem::drawRoundedRect( QPainter *p, const QRect &rect,
     }
     gradient.setColorAt( 1, bgColor.dark( 110 ) );
   } else {
-    if ( incidence->allDay() &&
-         incidence->dtStart() == incidence->dateTime( KCalCore::Incidence::RoleEnd ) &&
+    if ( mIncidence->allDay() &&
+         mIncidence->dtStart() == mIncidence->dateTime( KCalCore::Incidence::RoleEnd ) &&
          !CalendarSupport::hasTodo( mIncidence ) ) {
       gradient.setColorAt( 0, bgColor.light( 130 ) );
       gradient.setColorAt( 0.35, bgColor.light( 115 ) );
@@ -1373,8 +1360,8 @@ bool AgendaItem::event( QEvent *event )
       QToolTip::showText(
         helpEvent->globalPos(),
         KCalUtils::IncidenceFormatter::toolTipStr(
-          CalendarSupport::displayName( mCalendar.data(), mIncidence.parentCollection() ),
-          CalendarSupport::incidence( mIncidence ),
+          mCalendar->displayName(mIncidence),
+          mIncidence,
           mOccurrenceDateTime.toTimeSpec( mEventView->preferences()->timeSpec() ).date(), true, mEventView->preferences()->timeSpec() ),
         this );
     }
diff --git a/calendarviews/agenda/agendaitem.h b/calendarviews/agenda/agendaitem.h
index fcc48a5..74b8a53 100644
--- a/calendarviews/agenda/agendaitem.h
+++ b/calendarviews/agenda/agendaitem.h
@@ -24,6 +24,7 @@
 #define EVENTVIEWS_AGENDAITEM_H
 
 #include "eventviews_export.h"
+#include "viewcalendar.h"
 
 #include <calendarsupport/cellitem.h>
 
@@ -85,8 +86,8 @@ class EVENTVIEWS_EXPORT AgendaItem : public QWidget, public CalendarSupport::Cel
     typedef QList<QPtr> List;
 
     AgendaItem( EventView *eventView,
-                const Akonadi::ETMCalendar::Ptr &calendar,
-                const Akonadi::Item &incidence,
+                const MultiViewCalendar::Ptr &calendar,
+                const KCalCore::Incidence::Ptr &incidence,
                 int itemPos,
                 int itemCount,
                 const KDateTime &qd,
@@ -207,9 +208,9 @@ class EVENTVIEWS_EXPORT AgendaItem : public QWidget, public CalendarSupport::Cel
 
     bool dissociateFromMultiItem();
 
-    void setIncidence( const Akonadi::Item &incidence );
+    void setIncidence( const KCalCore::Incidence::Ptr &incidence );
 
-    const Akonadi::Item & incidence() const
+    const KCalCore::Incidence::Ptr& incidence() const
     {
       return mIncidence;
     }
@@ -295,8 +296,8 @@ class EVENTVIEWS_EXPORT AgendaItem : public QWidget, public CalendarSupport::Cel
     int mCellYTop, mCellYBottom;
 
     EventView *mEventView;
-    Akonadi::ETMCalendar::Ptr mCalendar;
-    Akonadi::Item mIncidence;
+    MultiViewCalendar::Ptr mCalendar;
+    KCalCore::Incidence::Ptr mIncidence;
     KDateTime mOccurrenceDateTime;
     bool mValid;
     bool mCloned;
diff --git a/calendarviews/agenda/agendaview.cpp b/calendarviews/agenda/agendaview.cpp
index 3c8d56d..b77b0b7 100644
--- a/calendarviews/agenda/agendaview.cpp
+++ b/calendarviews/agenda/agendaview.cpp
@@ -26,6 +26,7 @@
 #include "agendaview.h"
 #include "agenda.h"
 #include "agendaitem.h"
+#include "viewcalendar.h"
 #include "alternatelabel.h"
 #include "calendardecoration.h"
 #include "decorationlabel.h"
@@ -61,6 +62,7 @@
 #include <QSplitter>
 #include <QStyle>
 #include <QTimer>
+#include <boost/graph/buffer_concepts.hpp>
 
 using namespace EventViews;
 
@@ -195,8 +197,11 @@ class AgendaView::Private : public Akonadi::ETMCalendar::CalendarObserver
         mUpdateAllDayAgenda( true ),
         mUpdateAgenda( true ),
         mIsInteractive( isInteractive ),
-        mUpdateEventIndicatorsScheduled( false )
+        mUpdateEventIndicatorsScheduled( false ),
+        mViewCalendar(MultiViewCalendar::Ptr( new MultiViewCalendar()))
     {
+      mViewCalendar->mAgendaView = q;
+      mViewCalendar->setETMCalendar(q->calendar());
     }
 
   public:
@@ -250,6 +255,7 @@ class AgendaView::Private : public Akonadi::ETMCalendar::CalendarObserver
     // color
     QMap<QDate, KCalCore::Event::List > mBusyDays;
 
+    EventViews::MultiViewCalendar::Ptr mViewCalendar;
     bool makesWholeDayBusy( const KCalCore::Incidence::Ptr &incidence ) const;
     CalendarDecoration::Decoration *loadCalendarDecoration( const QString &name );
     void clearView();
@@ -265,10 +271,10 @@ class AgendaView::Private : public Akonadi::ETMCalendar::CalendarObserver
 
     void changeColumns( int numColumns );
 
-    AgendaItem::List agendaItems( Akonadi::Entity::Id id ) const;
+    AgendaItem::List agendaItems( const QString &uid ) const;
 
     // insertAtDateTime is in the view's timezone
-    void insertIncidence( const Akonadi::Item &,
+    void insertIncidence( const KCalCore::Incidence::Ptr &,
                           const KDateTime &insertAtDateTime, bool createSelected );
     void reevaluateIncidence( const KCalCore::Incidence::Ptr &incidence );
 
@@ -313,10 +319,10 @@ bool AgendaView::Private::datesEqual( const KCalCore::Incidence::Ptr &one, const
   return true;
 }
 
-AgendaItem::List AgendaView::Private::agendaItems( Akonadi::Item::Id id ) const
+AgendaItem::List AgendaView::Private::agendaItems( const QString &uid ) const
 {
-  AgendaItem::List allDayAgendaItems = mAllDayAgenda->agendaItems( id );
-  return allDayAgendaItems.isEmpty() ? mAgenda->agendaItems( id ) : allDayAgendaItems;
+  AgendaItem::List allDayAgendaItems = mAllDayAgenda->agendaItems( uid );
+  return allDayAgendaItems.isEmpty() ? mAgenda->agendaItems( uid ) : allDayAgendaItems;
 }
 
 bool AgendaView::Private::mightBeVisible( const KCalCore::Incidence::Ptr &incidence ) const
@@ -389,34 +395,32 @@ QList<QDate> AgendaView::Private::generateDateList( const QDate &start, const QD
 
 void AgendaView::Private::reevaluateIncidence( const KCalCore::Incidence::Ptr &incidence )
 {
-  const Akonadi::Item item = q->calendar()->item( incidence );
-  if ( !incidence || !item.isValid() ) {
-    kWarning() << "invalid incidence or item not found." << item.isValid() << incidence;
+  if (!incidence || !mViewCalendar->isValid( incidence )) {
+    kWarning() << "invalid or unknown incidence." << incidence;
     return;
   }
 
   q->removeIncidence( incidence );
-  q->displayIncidence( item, false );
+  q->displayIncidence( incidence, false );
   mAgenda->checkScrollBoundaries();
   q->updateEventIndicators();
 }
 
 void AgendaView::Private::calendarIncidenceAdded( const KCalCore::Incidence::Ptr &incidence )
 {
-  Akonadi::Item item = q->calendar()->item( incidence );
-  if ( !incidence || incidence->uid().isEmpty() || !item.isValid()) {
-    kError() << "AgendaView::Private::calendarIncidenceAdded() Invalid incidence or item:" << incidence << item.isValid();
+  if (!incidence || !mViewCalendar->isValid( incidence )) {
+    kWarning() << "invalid or unknown incidence." << incidence;
     Q_ASSERT( false );
     return;
   }
 
-  if ( incidence->hasRecurrenceId() ) {
+  if ( incidence->hasRecurrenceId() && mViewCalendar->isValid(incidence)) {
     // Reevaluate the main event instead, if it was inserted before this one
-    KCalCore::Incidence::Ptr mainIncidence = q->calendar()->incidence( incidence->uid() );
+    KCalCore::Incidence::Ptr mainIncidence = mViewCalendar->findCalendar(incidence)->getCalendar()->incidence( incidence->uid() );
     if ( mainIncidence ) {
       reevaluateIncidence( mainIncidence );
     }
-  } else if ( q->displayIncidence( item, false ) ) {
+  } else if ( q->displayIncidence( incidence, false ) ) {
     mAgenda->checkScrollBoundaries();
     q->scheduleUpdateEventIndicators();
   }
@@ -430,13 +434,7 @@ void AgendaView::Private::calendarIncidenceChanged( const KCalCore::Incidence::P
     return;
   }
 
-  Akonadi::Item item = q->calendar()->item( incidence->instanceIdentifier() );
-  if ( !item.isValid() ) {
-    kWarning() << "AgendaView::calendarIncidenceChanged() Invalid item for incidence " << incidence->uid();
-    return;
-  }
-
-  AgendaItem::List agendaItems = this->agendaItems( item.id() );
+  AgendaItem::List agendaItems = this->agendaItems( incidence->uid() );
   if ( agendaItems.isEmpty() ) {
     kWarning() << "AgendaView::calendarIncidenceChanged() Invalid agendaItem for incidence " << incidence->uid();
     return;
@@ -445,22 +443,20 @@ void AgendaView::Private::calendarIncidenceChanged( const KCalCore::Incidence::P
   // Optimization: If the dates didn't change, just repaint it.
   // This optimization for now because we need to process collisions between agenda items.
   if ( false && !incidence->recurs() && agendaItems.count() == 1 ) {
-    KCalCore::Incidence::Ptr originalIncidence = agendaItems.first()->incidence().payload<KCalCore::Incidence::Ptr>();
+    KCalCore::Incidence::Ptr originalIncidence = agendaItems.first()->incidence();
 
     if ( datesEqual( originalIncidence, incidence ) ) {
       foreach ( const AgendaItem::QPtr &agendaItem, agendaItems ) {
-        Akonadi::Item itemClone = item;
-        itemClone.setPayload<KCalCore::Incidence::Ptr>( KCalCore::Incidence::Ptr( incidence->clone() ) );
-        agendaItem->setIncidence( itemClone );
+        agendaItem->setIncidence( KCalCore::Incidence::Ptr( incidence->clone() ) );
         agendaItem->update();
       }
       return;
     }
   }
 
-  if ( incidence->hasRecurrenceId() ) {
+    if ( incidence->hasRecurrenceId() && mViewCalendar->isValid(incidence) ) {
     // Reevaluate the main event instead, if it exists
-    KCalCore::Incidence::Ptr mainIncidence = q->calendar()->incidence( incidence->uid() );
+    KCalCore::Incidence::Ptr mainIncidence = mViewCalendar->findCalendar(incidence)->getCalendar()->incidence( incidence->uid() );
     reevaluateIncidence( mainIncidence ? mainIncidence : incidence );
   } else {
     reevaluateIncidence( incidence );
@@ -483,9 +479,11 @@ void AgendaView::Private::calendarIncidenceDeleted( const KCalCore::Incidence::P
   if ( incidence->hasRecurrenceId()) {
     // Reevaluate the main event, if it exists. The exception was removed so the main recurrent series
     // will no be bigger.
-    KCalCore::Incidence::Ptr mainIncidence = q->calendar()->incidence( incidence->uid() );
-    if ( mainIncidence ) {
-      reevaluateIncidence( mainIncidence  );
+    if ( mViewCalendar->isValid(incidence) ) {
+      KCalCore::Incidence::Ptr mainIncidence = mViewCalendar->findCalendar(incidence)->getCalendar()->incidence( incidence->uid() );
+      if ( mainIncidence ) {
+        reevaluateIncidence( mainIncidence  );
+      }
     }
   } else if ( mightBeVisible( incidence ) ) {
     // No need to call setChanges(), that triggers a fillAgenda()
@@ -532,17 +530,16 @@ void AgendaView::Private::clearView()
   mBusyDays.clear();
 }
 
-void AgendaView::Private::insertIncidence( const Akonadi::Item &aitem,
+void AgendaView::Private::insertIncidence( const KCalCore::Incidence::Ptr &incidence,
                                            const KDateTime &insertAtDateTime,
                                            bool createSelected )
 {
-  if ( !q->filterByCollectionSelection( aitem ) ) {
+  if ( !q->filterByCollectionSelection( incidence ) ) {
     return;
   }
 
-  KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( aitem );
-  KCalCore::Event::Ptr event = CalendarSupport::event( aitem );
-  KCalCore::Todo::Ptr todo = CalendarSupport::todo( aitem );
+  KCalCore::Event::Ptr event = CalendarSupport::event( incidence );
+  KCalCore::Todo::Ptr todo = CalendarSupport::todo( incidence );
 
   const QDate insertAtDate = insertAtDateTime.date();
 
@@ -591,10 +588,10 @@ void AgendaView::Private::insertIncidence( const Akonadi::Item &aitem,
   const KDateTime::Spec timeSpec = q->preferences()->timeSpec();
   const QDate today = KDateTime::currentDateTime( timeSpec ).date();
   if ( todo && todo->isOverdue() && today >= insertAtDate ) {
-    mAllDayAgenda->insertAllDayItem( aitem, insertAtDateTime, curCol, curCol,
+    mAllDayAgenda->insertAllDayItem( incidence, insertAtDateTime, curCol, curCol,
                                      createSelected );
   } else if ( incidence->allDay() ) {
-    mAllDayAgenda->insertAllDayItem( aitem, insertAtDateTime, beginX, endX,
+    mAllDayAgenda->insertAllDayItem( incidence, insertAtDateTime, beginX, endX,
                                      createSelected );
   } else if ( event && event->isMultiDay( timeSpec ) ) {
     // TODO: We need a better isMultiDay(), one that receives the occurrence.
@@ -615,7 +612,7 @@ void AgendaView::Private::insertIncidence( const Akonadi::Item &aitem,
     }
     const int endY = mAgenda->timeToY( endTime ) - 1;
     if ( ( beginX <= 0 && curCol == 0 ) || beginX == curCol ) {
-      mAgenda->insertMultiItem( aitem, insertAtDateTime, beginX, endX, startY, endY,
+      mAgenda->insertMultiItem( incidence, insertAtDateTime, beginX, endX, startY, endY,
                                 createSelected );
     }
     if ( beginX == curCol ) {
@@ -686,7 +683,7 @@ void AgendaView::Private::insertIncidence( const Akonadi::Item &aitem,
     if ( endY < startY ) {
       endY = startY;
     }
-    mAgenda->insertItem( aitem, insertAtDateTime, curCol, startY, endY, 1, 1,
+    mAgenda->insertItem( incidence, insertAtDateTime, curCol, startY, endY, 1, 1,
                          createSelected );
     if ( startY < mMinY[curCol] ) {
       mMinY[curCol] = startY;
@@ -836,8 +833,8 @@ void AgendaView::init( const QDate &start, const QDate &end )
 
 AgendaView::~AgendaView()
 {
-  if ( calendar() ) {
-    calendar()->unregisterObserver( d );
+  foreach(const ViewCalendar::Ptr &cal, d->mViewCalendar->mSubCalendars) {
+    cal->getCalendar()->unregisterObserver(d);
   }
 
   delete d;
@@ -851,19 +848,27 @@ void AgendaView::setCalendar( const Akonadi::ETMCalendar::Ptr &cal )
   Q_ASSERT( cal );
   EventView::setCalendar( cal );
   calendar()->registerObserver( d );
-  d->mAgenda->setCalendar( calendar() );
-  d->mAllDayAgenda->setCalendar( calendar() );
+  d->mViewCalendar->setETMCalendar(cal);
+  d->mAgenda->setCalendar( d->mViewCalendar );
+  d->mAllDayAgenda->setCalendar( d->mViewCalendar );
+}
+
+void AgendaView::addCalendar(const ViewCalendar::Ptr &cal)
+{
+  d->mViewCalendar->addCalendar(cal);
+  cal->getCalendar()->registerObserver(d);
 }
 
+
 void AgendaView::connectAgenda( Agenda *agenda, Agenda *otherAgenda )
 {
   connect( agenda, SIGNAL(showNewEventPopupSignal()),
            SIGNAL(showNewEventPopupSignal()) );
 
-  connect( agenda, SIGNAL(showIncidencePopupSignal(Akonadi::Item,QDate)),
-           SIGNAL(showIncidencePopupSignal(Akonadi::Item,QDate)));
+  connect( agenda, SIGNAL(showIncidencePopupSignal(KCalCore::Incidence::Ptr,QDate)),
+           SLOT(slotShowIncidencePopup(KCalCore::Incidence::Ptr,QDate)));
 
-  agenda->setCalendar( calendar() );
+  agenda->setCalendar( d->mViewCalendar );
 
   connect( agenda, SIGNAL(newEventSignal()), SIGNAL(newEventSignal()) );
 
@@ -872,22 +877,22 @@ void AgendaView::connectAgenda( Agenda *agenda, Agenda *otherAgenda )
   connect( agenda, SIGNAL(newStartSelectSignal()),
            SIGNAL(timeSpanSelectionChanged()) );
 
-  connect( agenda, SIGNAL(editIncidenceSignal(Akonadi::Item)),
-                   SIGNAL(editIncidenceSignal(Akonadi::Item)) );
-  connect( agenda, SIGNAL(showIncidenceSignal(Akonadi::Item)),
-                   SIGNAL(showIncidenceSignal(Akonadi::Item)) );
-  connect( agenda, SIGNAL(deleteIncidenceSignal(Akonadi::Item)),
-                   SIGNAL(deleteIncidenceSignal(Akonadi::Item)) );
+  connect( agenda, SIGNAL(editIncidenceSignal(KCalCore::Incidence::Ptr)),
+                   SLOT(slotEditIncidence(KCalCore::Incidence::Ptr)) );
+  connect( agenda, SIGNAL(showIncidenceSignal(KCalCore::Incidence::Ptr)),
+                  SLOT(slotShowIncidence(KCalCore::Incidence::Ptr)) );
+  connect( agenda, SIGNAL(deleteIncidenceSignal(KCalCore::Incidence::Ptr)),
+                  SLOT(slotDeleteIncidence(KCalCore::Incidence::Ptr)) );
 
   // drag signals
-  connect( agenda, SIGNAL(startDragSignal(Akonadi::Item)),
-           SLOT(startDrag(Akonadi::Item)) );
+  connect( agenda, SIGNAL(startDragSignal(KCalCore::Incidence::Ptr)),
+          SLOT(startDrag(KCalCore::Incidence::Ptr)) );
 
   // synchronize selections
-  connect( agenda, SIGNAL(incidenceSelected(Akonadi::Item,QDate)),
+  connect( agenda, SIGNAL(incidenceSelected(KCalCore::Incidence::Ptr,QDate)),
            otherAgenda, SLOT(deselectItem()) );
-  connect( agenda, SIGNAL(incidenceSelected(Akonadi::Item,QDate)),
-           SIGNAL(incidenceSelected(Akonadi::Item,QDate)) );
+  connect( agenda, SIGNAL(incidenceSelected(KCalCore::Incidence::Ptr,QDate)),
+           SLOT(slotIncidenceSelected(KCalCore::Incidence::Ptr,QDate)) );
 
   // rescheduling of todos by d'n'd
   connect( agenda, SIGNAL(droppedIncidences(KCalCore::Incidence::List,QPoint,bool)),
@@ -897,6 +902,47 @@ void AgendaView::connectAgenda( Agenda *agenda, Agenda *otherAgenda )
 
 }
 
+void AgendaView::slotIncidenceSelected(const KCalCore::Incidence::Ptr &incidence,QDate date)
+{
+  Akonadi::Item item = d->mViewCalendar->item(incidence);
+  if (item.isValid()) {
+    emit incidenceSelected(item, date);
+  }
+}
+
+void AgendaView::slotShowIncidencePopup(const KCalCore::Incidence::Ptr &incidence, QDate date)
+{
+  Akonadi::Item item = d->mViewCalendar->item(incidence);
+  kDebug() << "wanna see the popup for " << incidence->uid() << item.id();
+  if (item.isValid()) {
+    emit showIncidencePopupSignal(item, date);
+   }
+}
+
+void AgendaView::slotShowIncidence(const KCalCore::Incidence::Ptr &incidence)
+{
+  Akonadi::Item item = d->mViewCalendar->item(incidence);
+  if (item.isValid()) {
+    emit showIncidenceSignal(item);
+  }
+}
+
+void AgendaView::slotEditIncidence(const KCalCore::Incidence::Ptr &incidence)
+{
+  Akonadi::Item item = d->mViewCalendar->item(incidence);
+  if (item.isValid()) {
+    emit editIncidenceSignal(item);
+   }
+}
+
+void AgendaView::slotDeleteIncidence(const KCalCore::Incidence::Ptr &incidence)
+{
+  Akonadi::Item item = d->mViewCalendar->item(incidence);
+  if (item.isValid()) {
+    emit deleteIncidenceSignal(item);
+   }
+}
+
 void AgendaView::zoomInVertically( )
 {
   if ( !d->mIsSideBySide ) {
@@ -1237,14 +1283,14 @@ Akonadi::Item::List AgendaView::selectedIncidences() const
 {
   Akonadi::Item::List selected;
 
-  Akonadi::Item agendaitem = d->mAgenda->selectedIncidence();
-  if ( agendaitem.isValid() ) {
-    selected.append( agendaitem );
+  KCalCore::Incidence::Ptr agendaitem = d->mAgenda->selectedIncidence();
+  if ( agendaitem ) {
+    selected.append( d->mViewCalendar->item(agendaitem) );
   }
 
-  Akonadi::Item dayitem = d->mAllDayAgenda->selectedIncidence();
-  if ( dayitem.isValid() ) {
-    selected.append( dayitem );
+  KCalCore::Incidence::Ptr dayitem = d->mAllDayAgenda->selectedIncidence();
+  if ( dayitem ) {
+    selected.append( d->mViewCalendar->item(dayitem) );
   }
 
   return selected;
@@ -1419,9 +1465,9 @@ void AgendaView::updateEventDates( AgendaItem *item, bool addIncidence,
   int daysLength = 0;
   //  startDt.setDate( startDate );
 
-  const Akonadi::Item aitem = item->incidence();
+  Akonadi::Item aitem = d->mViewCalendar->item(item->incidence());
   KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( aitem );
-  if ( !incidence || !changer() ) {
+  if ( !aitem.isValid() || !incidence || !changer() ) {
     kWarning() << "changer is " << changer() << " and incidence is " << incidence.data();
     return;
   }
@@ -1460,7 +1506,7 @@ void AgendaView::updateEventDates( AgendaItem *item, bool addIncidence,
   }
 
   // FIXME: use a visitor here
-  if ( const KCalCore::Event::Ptr ev = CalendarSupport::event( aitem ) ) {
+  if ( const KCalCore::Event::Ptr ev = CalendarSupport::event( incidence ) ) {
     startDt = incidence->dtStart();
     // convert to calendar timespec because we then manipulate it
     // with time coming from the calendar
@@ -1479,7 +1525,7 @@ void AgendaView::updateEventDates( AgendaItem *item, bool addIncidence,
       QTimer::singleShot( 0, this, SLOT(updateView()) );
       return;
     }
-  } else if ( const KCalCore::Todo::Ptr td = CalendarSupport::todo( aitem ) ) {
+  } else if ( const KCalCore::Todo::Ptr td = CalendarSupport::todo( incidence ) ) {
     startDt = td->hasStartDate() ? td->dtStart() : td->dtDue();
     // convert to calendar timespec because we then manipulate it with time coming from
     // the calendar
@@ -1505,7 +1551,7 @@ void AgendaView::updateEventDates( AgendaItem *item, bool addIncidence,
   // A commented code block which had 150 lines to adjust recurrence was here.
   // I deleted it in rev 1180272 to make this function readable.
 
-  if ( const KCalCore::Event::Ptr ev = CalendarSupport::event( aitem ) ) {
+  if ( const KCalCore::Event::Ptr ev = CalendarSupport::event( incidence ) ) {
     /* setDtEnd() must be called before setDtStart(), otherwise, when moving
      * events, CalendarLocal::incidenceUpdated() will not remove the old hash
      * and that causes the event to be shown in the old date also (bug #179157).
@@ -1515,7 +1561,7 @@ void AgendaView::updateEventDates( AgendaItem *item, bool addIncidence,
     ev->setDtEnd(
       endDt.toTimeSpec( incidence->dateTime( KCalCore::Incidence::RoleEnd ).timeSpec() ) );
     incidence->setDtStart( startDt.toTimeSpec( incidence->dtStart().timeSpec() ) );
-  } else if ( const KCalCore::Todo::Ptr td = CalendarSupport::todo( aitem ) ) {
+  } else if ( const KCalCore::Todo::Ptr td = CalendarSupport::todo( incidence ) ) {
     if ( td->hasStartDate() ) {
       td->setDtStart( startDt.toTimeSpec( incidence->dtStart().timeSpec() ) );
     }
@@ -1652,7 +1698,7 @@ void AgendaView::fillAgenda()
     return;
   }
 
-  if ( !calendar() ) {
+  if ( d->mViewCalendar->calendars() == 0) {
     kWarning() << "No calendar is set";
     return;
   }
@@ -1664,8 +1710,8 @@ void AgendaView::fillAgenda()
 
   /* Remember the item Ids of the selected items. In case one of the
    * items was deleted and re-added, we want to reselect it. */
-  const Akonadi::Item::Id selectedAgendaId = d->mAgenda->lastSelectedItemId();
-  const Akonadi::Item::Id selectedAllDayAgendaId = d->mAllDayAgenda->lastSelectedItemId();
+  const QString selectedAgendaId = d->mAgenda->lastSelectedItemId();
+  const QString selectedAllDayAgendaId = d->mAllDayAgenda->lastSelectedItemId();
 
   enableAgendaUpdate( true );
   d->clearView();
@@ -1684,17 +1730,16 @@ void AgendaView::fillAgenda()
   setChanges( NothingChanged );
 
   bool somethingReselected = false;
-  const KCalCore::Incidence::List incidences = calendar()->incidences();
+  const KCalCore::Incidence::List incidences = d->mViewCalendar->incidences();
 
   foreach ( const KCalCore::Incidence::Ptr &incidence, incidences ) {
     Q_ASSERT( incidence );
-    Akonadi::Item aitem = calendar()->item( incidence );
-    const bool wasSelected = aitem.id() == selectedAgendaId  ||
-                             aitem.id() == selectedAllDayAgendaId;
+      const bool wasSelected = incidence->uid() == selectedAgendaId  ||
+                               incidence->uid() == selectedAllDayAgendaId;
 
     if ( ( incidence->allDay() && d->mUpdateAllDayAgenda ) ||
           ( !incidence->allDay() && d->mUpdateAgenda ) ) {
-      displayIncidence( aitem, wasSelected );
+      displayIncidence( incidence, wasSelected );
     }
 
     if ( wasSelected ) {
@@ -1719,19 +1764,18 @@ void AgendaView::fillAgenda()
   }
 }
 
-bool AgendaView::displayIncidence( const Akonadi::Item &aitem, bool createSelected )
+bool AgendaView::displayIncidence( const  KCalCore::Incidence::Ptr &incidence, bool createSelected )
 {
-  KCalCore::Incidence::Ptr incidence = CalendarSupport::incidence( aitem );
   if ( !incidence || incidence->hasRecurrenceId() ) {
     return false;
   }
 
-  KCalCore::Todo::Ptr todo = CalendarSupport::todo( aitem );
+  KCalCore::Todo::Ptr todo = CalendarSupport::todo( incidence );
   if ( todo && ( !preferences()->showTodosAgendaView() || !todo->hasDueDate() ) ) {
     return false;
   }
 
-  KCalCore::Event::Ptr event = CalendarSupport::event( aitem );
+  KCalCore::Event::Ptr event = CalendarSupport::event( incidence );
   const QDate today = QDate::currentDate();
   KCalCore::DateTimeList::iterator t;
 
@@ -1789,7 +1833,7 @@ bool AgendaView::displayIncidence( const Akonadi::Item &aitem, bool createSelect
       if ( occurrenceDate.date() == today ) {
         alreadyAddedToday = true;
       }
-      d->insertIncidence( item, occurrenceDate, createSelected );
+      d->insertIncidence( incidence, occurrenceDate, createSelected );
     }
 
   } else {
@@ -1844,7 +1888,7 @@ bool AgendaView::displayIncidence( const Akonadi::Item &aitem, bool createSelect
       busyEvents.append( event );
     }
 
-    d->insertIncidence( aitem, t->toTimeSpec( timeSpec ), createSelected );
+    d->insertIncidence( incidence, t->toTimeSpec( timeSpec ), createSelected );
   }
 
   // Can be multiday
@@ -1972,6 +2016,21 @@ void AgendaView::slotIncidencesDropped( const KCalCore::Incidence::List &inciden
     }
   }
 }
+
+void AgendaView::startDrag(const KCalCore::Incidence::Ptr &incidence)
+{
+  if ( !calendar() ) {
+    kError() << "No Calendar set";
+    return;
+  }
+
+  const Akonadi::Item item = d->mViewCalendar->item(incidence);
+  if (item.isValid()) {
+    startDrag(item);
+  }
+}
+
+
 void AgendaView::startDrag( const Akonadi::Item &incidence )
 {
   if ( !calendar() ) {
@@ -2114,8 +2173,8 @@ void AgendaView::removeIncidence( const KCalCore::Incidence::Ptr &incidence )
   d->mAllDayAgenda->removeIncidence( incidence );
   d->mAgenda->removeIncidence( incidence );
 
-  if ( !incidence->hasRecurrenceId() ) {
-    KCalCore::Incidence::List exceptions = calendar()->instances( incidence );
+  if ( !incidence->hasRecurrenceId() && d->mViewCalendar->isValid(incidence)) {
+    KCalCore::Incidence::List exceptions = d->mViewCalendar->findCalendar(incidence)->getCalendar()->instances( incidence );
     foreach ( const KCalCore::Incidence::Ptr &exception, exceptions ) {
       if ( exception->allDay() ) {
         d->mAllDayAgenda->removeIncidence( exception );
@@ -2166,16 +2225,22 @@ QSplitter *AgendaView::splitter() const
   return d->mSplitterAgenda;
 }
 
-bool AgendaView::filterByCollectionSelection( const Akonadi::Item &incidence )
+bool AgendaView::filterByCollectionSelection( const KCalCore::Incidence::Ptr &incidence )
 {
+  const Akonadi::Item item = d->mViewCalendar->item(incidence);
+
+  if (!item.isValid()) {
+    return true;
+  }
+
   if ( customCollectionSelection() ) {
-    return customCollectionSelection()->contains( incidence.parentCollection().id() );
+    return customCollectionSelection()->contains(item.parentCollection().id() );
   }
 
   if ( collectionId() < 0 ) {
     return true;
   } else {
-    return collectionId() == incidence.storageCollectionId();
+    return collectionId() == item.storageCollectionId();
   }
 }
 
diff --git a/calendarviews/agenda/agendaview.h b/calendarviews/agenda/agendaview.h
index 206a1ba..e8e0b99 100644
--- a/calendarviews/agenda/agendaview.h
+++ b/calendarviews/agenda/agendaview.h
@@ -28,6 +28,7 @@
 
 #include "eventviews_export.h"
 #include "eventview.h"
+#include "viewcalendar.h"
 
 #include <KCalCore/Todo>
 
@@ -135,6 +136,7 @@ class EVENTVIEWS_EXPORT AgendaView : public EventView
 
     /* reimp from EventView */
     virtual void setCalendar( const Akonadi::ETMCalendar::Ptr &cal );
+    virtual void addCalendar( const ViewCalendar::Ptr &cal);
 
     QSplitter *splitter() const;
 
@@ -164,6 +166,7 @@ class EVENTVIEWS_EXPORT AgendaView : public EventView
 
     void clearSelection();
 
+    void startDrag( const KCalCore::Incidence::Ptr & );
     void startDrag( const Akonadi::Item & );
 
     void readSettings();
@@ -239,11 +242,18 @@ class EVENTVIEWS_EXPORT AgendaView : public EventView
 
     void alignAgendas();
 
+  private slots:
+    void slotIncidenceSelected(const KCalCore::Incidence::Ptr &incidence, QDate date);
+    void slotShowIncidencePopup(const KCalCore::Incidence::Ptr &incidence, QDate date);
+    void slotEditIncidence(const KCalCore::Incidence::Ptr &incidence);
+    void slotShowIncidence(const KCalCore::Incidence::Ptr &incidence);
+    void slotDeleteIncidence(const KCalCore::Incidence::Ptr &incidence);
+
   private:
     void init( const QDate &start, const QDate &end );
-    bool filterByCollectionSelection( const Akonadi::Item &incidence );
+    bool filterByCollectionSelection( const  KCalCore::Incidence::Ptr &incidence );
     void setupTimeLabel( TimeLabels *timeLabel );
-    bool displayIncidence( const Akonadi::Item &incidence, bool createSelected );
+    bool displayIncidence( const KCalCore::Incidence::Ptr &incidence, bool createSelected );
 
 #ifndef EVENTVIEWS_NODECOS
     typedef QList<EventViews::CalendarDecoration::Decoration *> DecorationList;
diff --git a/calendarviews/agenda/viewcalendar.cpp b/calendarviews/agenda/viewcalendar.cpp
new file mode 100644
index 0000000..595c783
--- /dev/null
+++ b/calendarviews/agenda/viewcalendar.cpp
@@ -0,0 +1,169 @@
+#include "viewcalendar.h"
+#include "agendaview.h"
+#include "helper.h"
+
+#include <calendarsupport/utils.h>
+
+using namespace EventViews;
+
+ViewCalendar::~ViewCalendar()
+{
+}
+
+MultiViewCalendar::~MultiViewCalendar()
+{
+}
+
+KCalCore::Calendar::Ptr MultiViewCalendar::getCalendar() const
+{
+    return KCalCore::Calendar::Ptr();
+}
+
+KCalCore::Incidence::List MultiViewCalendar::incidences() const
+{
+    KCalCore::Incidence::List list;
+    foreach(const ViewCalendar::Ptr &cal, mSubCalendars) {
+        if (cal->getCalendar()) {
+            list += cal->getCalendar()->incidences();
+        }
+    }
+    return list;
+}
+
+int MultiViewCalendar::calendars() const
+{
+    return mSubCalendars.size();
+}
+
+
+ViewCalendar::Ptr MultiViewCalendar::findCalendar(const KCalCore::Incidence::Ptr &incidence) const
+{
+    foreach(const ViewCalendar::Ptr &cal, mSubCalendars) {
+        if (cal->isValid(incidence)) {
+            return cal;
+        }
+    }
+    return ViewCalendar::Ptr();
+}
+
+void MultiViewCalendar::addCalendar(const ViewCalendar::Ptr &calendar)
+{
+    if (!mSubCalendars.contains(calendar)) {
+        mSubCalendars.append(calendar);
+    }
+}
+
+void MultiViewCalendar::setETMCalendar(const Akonadi::ETMCalendar::Ptr &calendar)
+{
+    if (!mETMCalendar) {
+        mETMCalendar = AkonadiViewCalendar::Ptr(new AkonadiViewCalendar);
+        mETMCalendar->mAgendaView = mAgendaView;
+    }
+    mETMCalendar->mCalendar = calendar;
+    addCalendar(mETMCalendar);
+}
+
+QString MultiViewCalendar::displayName(const KCalCore::Incidence::Ptr &incidence) const
+{
+    ViewCalendar::Ptr cal = findCalendar(incidence);
+    if (cal) {
+        return cal->displayName(incidence);
+    }
+    return QString();
+}
+
+QString MultiViewCalendar::iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const
+{
+    ViewCalendar::Ptr cal = findCalendar(incidence);
+    if (cal) {
+        return cal->iconForIncidence(incidence);
+    }
+    return QString();
+}
+
+bool MultiViewCalendar::isValid(const KCalCore::Incidence::Ptr &incidence) const
+{
+    ViewCalendar::Ptr cal = findCalendar(incidence);
+    return cal;
+}
+
+QColor MultiViewCalendar::resourceColor(const KCalCore::Incidence::Ptr &incidence) const
+{
+    ViewCalendar::Ptr cal = findCalendar(incidence);
+    if (cal) {
+        return cal->resourceColor(incidence);
+    }
+    return QColor();
+}
+
+Akonadi::Item MultiViewCalendar::item(const KCalCore::Incidence::Ptr &incidence) const
+{
+    if (mETMCalendar->isValid(incidence)) {
+        return mETMCalendar->item(incidence);
+    }
+
+    return Akonadi::Item();
+}
+
+AkonadiViewCalendar::~AkonadiViewCalendar()
+{
+}
+
+bool AkonadiViewCalendar::isValid(const KCalCore::Incidence::Ptr &incidence) const
+{
+    if (!mCalendar) {
+        return false;
+    }
+
+    if (item(incidence).isValid()) {
+        return true;
+    }
+    return false;
+}
+
+Akonadi::Item AkonadiViewCalendar::item(const KCalCore::Incidence::Ptr &incidence) const
+{
+    if (!mCalendar) {
+        return Akonadi::Item();
+    }
+    bool ok = false;
+    Akonadi::Item::Id id = incidence->customProperty("VOLATILE", "AKONADI-ID").toLongLong(&ok);
+
+    if (id == -1 || !ok) {
+        id = mCalendar->item(incidence).id();
+
+        if (id == -1) {
+            // Ok, we really don't know the ID, give up.
+            kWarning() << "Agenda::removeIncidence() Item to remove is invalid. uid = "
+                       << incidence->instanceIdentifier();
+            return Akonadi::Item();
+        }
+        return mCalendar->item(incidence->instanceIdentifier());
+    }
+    return mCalendar->item(id);
+}
+
+QString AkonadiViewCalendar::displayName(const KCalCore::Incidence::Ptr &incidence) const
+{
+    return CalendarSupport::displayName( mCalendar.data(), item(incidence).parentCollection() );
+}
+
+QColor AkonadiViewCalendar::resourceColor(const KCalCore::Incidence::Ptr &incidence) const
+{
+    return EventViews::resourceColor( item(incidence), mAgendaView->preferences() );
+}
+
+QString AkonadiViewCalendar::iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const
+{
+    return mAgendaView->iconForItem(item(incidence));
+}
+
+KDateTime::Spec AkonadiViewCalendar::timeSpec() const
+{
+    return mCalendar->timeSpec();
+}
+
+KCalCore::Calendar::Ptr AkonadiViewCalendar::getCalendar() const
+{
+    return mCalendar;
+}
diff --git a/calendarviews/agenda/viewcalendar.h b/calendarviews/agenda/viewcalendar.h
new file mode 100644
index 0000000..53551e5
--- /dev/null
+++ b/calendarviews/agenda/viewcalendar.h
@@ -0,0 +1,103 @@
+/*
+Copyright (c) 2014 Sandro Knauß <knauss at kolabsys.com>
+
+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; either version 2 of the License, or
+(at your option) any later version.
+
+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.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+As a special exception, permission is given to link this program
+with any edition of Qt, and distribute the resulting executable,
+without including the source code for Qt in the source distribution.
+ */
+#ifndef EVENTVIEWS_VIEWCALENDAR_H
+#define EVENTVIEWS_VIEWCALENDAR_H
+
+#include "eventviews_export.h"
+
+#include <Akonadi/Item>
+#include <Akonadi/Calendar/ETMCalendar>
+#include <KCalCore/Incidence>
+
+#include <QColor>
+#include <QList>
+
+namespace EventViews {
+
+class AgendaView;
+
+class EVENTVIEWS_EXPORT ViewCalendar {
+
+public:
+  typedef QSharedPointer<ViewCalendar> Ptr;
+
+  virtual ~ViewCalendar();
+  virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const=0;
+  virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const=0;
+
+  virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const=0;
+  virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const=0;
+
+  virtual KCalCore::Calendar::Ptr getCalendar() const=0;
+};
+
+
+class EVENTVIEWS_EXPORT AkonadiViewCalendar: public ViewCalendar {
+public:
+    typedef QSharedPointer<AkonadiViewCalendar> Ptr;
+
+    virtual ~AkonadiViewCalendar();
+    virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const;
+    virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const;
+
+    virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const;
+    virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const;
+
+    virtual Akonadi::Item item(const KCalCore::Incidence::Ptr &incidence) const;
+
+    virtual KCalCore::Calendar::Ptr getCalendar() const;
+
+    KDateTime::Spec timeSpec() const;
+
+    Akonadi::ETMCalendar::Ptr mCalendar;
+    AgendaView *mAgendaView;
+};
+
+class EVENTVIEWS_EXPORT MultiViewCalendar {
+public:
+    typedef QSharedPointer<MultiViewCalendar> Ptr;
+
+    virtual ~MultiViewCalendar();
+    ViewCalendar::Ptr findCalendar(const KCalCore::Incidence::Ptr &incidence) const;
+    virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const;
+    virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const;
+
+    virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const;
+    virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const;
+
+    virtual Akonadi::Item item(const KCalCore::Incidence::Ptr &incidence) const;
+
+    void addCalendar(const ViewCalendar::Ptr &calendar);
+    void setETMCalendar(const Akonadi::ETMCalendar::Ptr &calendar);
+    int calendars() const;
+    KCalCore::Calendar::Ptr getCalendar() const;
+    KCalCore::Incidence::List incidences() const;
+
+    AgendaView *mAgendaView;
+    AkonadiViewCalendar::Ptr mETMCalendar;
+    QList<ViewCalendar::Ptr> mSubCalendars;
+};
+
+
+}
+
+#endif
\ No newline at end of file


commit 81cceb40d5f77b567d5e164f4a529a7fe55117b6
Author: Sandro Knauß <knauss at kolabsys.com>
Date:   Mon Sep 15 16:19:16 2014 +0200

    calendersupport handles now also KCalCore::Incidence::Ptr

diff --git a/calendarsupport/utils.cpp b/calendarsupport/utils.cpp
index 481de05..cdf0a0e 100644
--- a/calendarsupport/utils.cpp
+++ b/calendarsupport/utils.cpp
@@ -87,7 +87,7 @@ KCalCore::Event::Ptr CalendarSupport::event( const Akonadi::Item &item )
   //relying on exception for performance reasons
   try {
     KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
-    if ( incidence && incidence->type() == KCalCore::Incidence::TypeEvent ) {
+    if ( hasEvent(incidence) ) {
       return item.payload<KCalCore::Event::Ptr>();
     }
   } catch( Akonadi::PayloadException ) {
@@ -96,6 +96,14 @@ KCalCore::Event::Ptr CalendarSupport::event( const Akonadi::Item &item )
   return KCalCore::Event::Ptr();
 }
 
+KCalCore::Event::Ptr CalendarSupport::event(const KCalCore::Incidence::Ptr &incidence)
+{
+    if (hasEvent(incidence)) {
+        return incidence.dynamicCast<KCalCore::Event>();
+    }
+    return KCalCore::Event::Ptr();
+}
+
 KCalCore::Event::List CalendarSupport::eventsFromItems( const Akonadi::Item::List &items )
 {
   KCalCore::Event::List events;
@@ -122,7 +130,7 @@ KCalCore::Todo::Ptr CalendarSupport::todo( const Akonadi::Item &item )
 {
   try {
     KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
-    if ( incidence && incidence->type() == KCalCore::Incidence::TypeTodo ) {
+    if ( hasTodo(incidence) ) {
       return item.payload<KCalCore::Todo::Ptr>();
     }
   } catch( Akonadi::PayloadException ) {
@@ -131,11 +139,19 @@ KCalCore::Todo::Ptr CalendarSupport::todo( const Akonadi::Item &item )
   return KCalCore::Todo::Ptr();
 }
 
+KCalCore::Todo::Ptr CalendarSupport::todo(const KCalCore::Incidence::Ptr &incidence)
+{
+    if (hasTodo(incidence)) {
+        return incidence.dynamicCast<KCalCore::Todo>();
+    }
+    return KCalCore::Todo::Ptr();
+}
+
 KCalCore::Journal::Ptr CalendarSupport::journal( const Akonadi::Item &item )
 {
   try {
     KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
-    if ( incidence && incidence->type() == KCalCore::Incidence::TypeJournal ) {
+    if ( hasJournal(incidence) ) {
       return item.payload<KCalCore::Journal::Ptr>();
     }
   } catch( Akonadi::PayloadException ) {
@@ -144,6 +160,14 @@ KCalCore::Journal::Ptr CalendarSupport::journal( const Akonadi::Item &item )
   return KCalCore::Journal::Ptr();
 }
 
+KCalCore::Journal::Ptr CalendarSupport::journal(const KCalCore::Incidence::Ptr &incidence)
+{
+    if (hasJournal(incidence)) {
+        return incidence.dynamicCast<KCalCore::Journal>();
+    }
+    return KCalCore::Journal::Ptr();
+}
+
 bool CalendarSupport::hasIncidence( const Akonadi::Item &item )
 {
   return item.hasPayload<KCalCore::Incidence::Ptr>();
@@ -154,16 +178,31 @@ bool CalendarSupport::hasEvent( const Akonadi::Item &item )
   return item.hasPayload<KCalCore::Event::Ptr>();
 }
 
+bool CalendarSupport::hasEvent(const KCalCore::Incidence::Ptr &incidence)
+{
+    return incidence && incidence->type() ==  KCalCore::Incidence::TypeEvent;
+}
+
 bool CalendarSupport::hasTodo( const Akonadi::Item &item )
 {
   return item.hasPayload<KCalCore::Todo::Ptr>();
 }
 
+bool CalendarSupport::hasTodo(const KCalCore::Incidence::Ptr &incidence)
+{
+    return incidence && incidence->type() ==  KCalCore::Incidence::TypeTodo;
+}
+
 bool CalendarSupport::hasJournal( const Akonadi::Item &item )
 {
   return item.hasPayload<KCalCore::Journal::Ptr>();
 }
 
+bool CalendarSupport::hasJournal(const KCalCore::Incidence::Ptr &incidence)
+{
+    return incidence && incidence->type() ==  KCalCore::Incidence::TypeJournal;
+}
+
 QMimeData *CalendarSupport::createMimeData( const Akonadi::Item::List &items,
                                             const KDateTime::Spec &timeSpec )
 {
diff --git a/calendarsupport/utils.h b/calendarsupport/utils.h
index e96856a..d3f4567 100644
--- a/calendarsupport/utils.h
+++ b/calendarsupport/utils.h
@@ -72,6 +72,11 @@ namespace CalendarSupport {
   CALENDARSUPPORT_EXPORT KCalCore::Event::Ptr event( const Akonadi::Item &item );
 
   /**
+   * returns the event from an incidence, or a null pointer if the item has no such payload
+   */
+  CALENDARSUPPORT_EXPORT KCalCore::Event::Ptr event( const KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns event pointers from an akonadi item, or a null pointer if the item has no such payload
    */
   CALENDARSUPPORT_EXPORT KCalCore::Event::List eventsFromItems( const Akonadi::Item::List &items );
@@ -88,11 +93,21 @@ namespace CalendarSupport {
   CALENDARSUPPORT_EXPORT KCalCore::Todo::Ptr todo( const Akonadi::Item &item );
 
   /**
+   * returns the todo from an incidence, or a null pointer if the item has no such payload
+   */
+  CALENDARSUPPORT_EXPORT KCalCore::Todo::Ptr todo( const  KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns the journal from an akonadi item, or a null pointer if the item has no such payload
    */
   CALENDARSUPPORT_EXPORT KCalCore::Journal::Ptr journal( const Akonadi::Item &item );
 
   /**
+   * returns the journal from an incidence, or a null pointer if the item has no such payload
+   */
+  CALENDARSUPPORT_EXPORT KCalCore::Journal::Ptr journal( const KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns whether an Akonadi item contains an incidence
    */
   CALENDARSUPPORT_EXPORT bool hasIncidence( const Akonadi::Item &item );
@@ -103,16 +118,31 @@ namespace CalendarSupport {
   CALENDARSUPPORT_EXPORT bool hasEvent( const Akonadi::Item &item );
 
   /**
+   * returns whether an incidence contains an event
+   */
+  CALENDARSUPPORT_EXPORT bool hasEvent( const KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns whether an Akonadi item contains a todo
    */
   CALENDARSUPPORT_EXPORT bool hasTodo( const Akonadi::Item &item );
 
   /**
+   * returns whether an incidence contains a todo
+   */
+  CALENDARSUPPORT_EXPORT bool hasTodo( const KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns whether an Akonadi item contains a journal
    */
   CALENDARSUPPORT_EXPORT bool hasJournal( const Akonadi::Item &item );
 
   /**
+   * returns whether an incidence contains a journal
+   */
+  CALENDARSUPPORT_EXPORT bool hasJournal( const KCalCore::Incidence::Ptr &incidence );
+
+  /**
    * returns whether this item can be deleted
    */
   CALENDARSUPPORT_EXPORT bool hasDeleteRights( const Akonadi::Item &item );


commit 1691199ef49216a7e46d25ad29bb88a73df6d69b
Author: Sandro Knauß <knauss at kolabsys.com>
Date:   Fri Sep 12 13:42:32 2014 +0200

    Do not run a movejob, if access items through search collections

diff --git a/incidenceeditor-ng/editoritemmanager.cpp b/incidenceeditor-ng/editoritemmanager.cpp
index cb75c4f..20ddc7e 100644
--- a/incidenceeditor-ng/editoritemmanager.cpp
+++ b/incidenceeditor-ng/editoritemmanager.cpp
@@ -168,7 +168,8 @@ void ItemEditorPrivate::onModifyFinished( int, const Akonadi::Item &item,
 {
   Q_Q( EditorItemManager );
   if ( resultCode == Akonadi::IncidenceChanger::ResultCodeSuccess ) {
-    if ( mItem.parentCollection() == mItemUi->selectedCollection() ) {
+    if ( mItem.parentCollection() == mItemUi->selectedCollection() ||
+         mItem.storageCollectionId() == mItemUi->selectedCollection().id()) {
       mItem = item;
       emit q->itemSaveFinished( EditorItemManager::Modify );
       setupMonitor();




More information about the commits mailing list