Branch 'kolab/integration/4.13.0' - 3 commits - calendarviews/agenda incidenceeditor-ng/CMakeLists.txt incidenceeditor-ng/conflictresolver.cpp incidenceeditor-ng/conflictresolver.h incidenceeditor-ng/freebusyganttproxymodel.cpp incidenceeditor-ng/freebusyitem.cpp incidenceeditor-ng/freebusyitem.h incidenceeditor-ng/freebusyitemmodel.cpp incidenceeditor-ng/freebusyitemmodel.h incidenceeditor-ng/freeperiodmodel.cpp incidenceeditor-ng/freeperiodmodel.h incidenceeditor-ng/incidenceattendee.cpp incidenceeditor-ng/resourcemanagement.cpp incidenceeditor-ng/resourcemanagement.h incidenceeditor-ng/schedulingdialog.cpp incidenceeditor-ng/schedulingdialog.h incidenceeditor-ng/tests incidenceeditor-ng/visualfreebusywidget.cpp incidenceeditor-ng/visualfreebusywidget.h korganizer/akonadicollectionview.cpp korganizer/CMakeLists.txt korganizer/views libkdepim/CMakeLists.txt libkdepim/freebusymodel
Sandro Knauß
knauss at kolabsys.com
Thu Oct 9 13:57:03 CEST 2014
calendarviews/agenda/viewcalendar.cpp | 2
incidenceeditor-ng/CMakeLists.txt | 3
incidenceeditor-ng/conflictresolver.cpp | 2
incidenceeditor-ng/conflictresolver.h | 6
incidenceeditor-ng/freebusyganttproxymodel.cpp | 2
incidenceeditor-ng/freebusyitem.cpp | 84 -
incidenceeditor-ng/freebusyitem.h | 76 -
incidenceeditor-ng/freebusyitemmodel.cpp | 427 ---------
incidenceeditor-ng/freebusyitemmodel.h | 114 --
incidenceeditor-ng/freeperiodmodel.cpp | 208 ----
incidenceeditor-ng/freeperiodmodel.h | 66 -
incidenceeditor-ng/incidenceattendee.cpp | 2
incidenceeditor-ng/resourcemanagement.cpp | 106 --
incidenceeditor-ng/resourcemanagement.h | 8
incidenceeditor-ng/schedulingdialog.cpp | 2
incidenceeditor-ng/schedulingdialog.h | 3
incidenceeditor-ng/tests/CMakeLists.txt | 3
incidenceeditor-ng/tests/conflictresolvertest.h | 4
incidenceeditor-ng/tests/testfreebusyganttproxymodel.cpp | 4
incidenceeditor-ng/tests/testfreebusyitemmodel.cpp | 241 -----
incidenceeditor-ng/tests/testfreebusyitemmodel.h | 33
incidenceeditor-ng/tests/testfreeperiodmodel.cpp | 88 --
incidenceeditor-ng/tests/testfreeperiodmodel.h | 32
incidenceeditor-ng/visualfreebusywidget.cpp | 2
incidenceeditor-ng/visualfreebusywidget.h | 3
korganizer/CMakeLists.txt | 2
korganizer/akonadicollectionview.cpp | 27
korganizer/views/collectionview/calendardelegate.cpp | 32
korganizer/views/collectionview/calendardelegate.h | 3
korganizer/views/collectionview/controller.cpp | 27
korganizer/views/collectionview/controller.h | 3
korganizer/views/collectionview/quickview.cpp | 183 ++++
korganizer/views/collectionview/quickview.h | 62 +
korganizer/views/collectionview/quickview.ui | 112 ++
libkdepim/CMakeLists.txt | 8
libkdepim/freebusymodel/freebusycalendar.cpp | 160 +++
libkdepim/freebusymodel/freebusycalendar.h | 55 +
libkdepim/freebusymodel/freebusyitem.cpp | 82 +
libkdepim/freebusymodel/freebusyitem.h | 73 +
libkdepim/freebusymodel/freebusyitemmodel.cpp | 419 +++++++++
libkdepim/freebusymodel/freebusyitemmodel.h | 111 ++
libkdepim/freebusymodel/freeperiodmodel.cpp | 206 ++++
libkdepim/freebusymodel/freeperiodmodel.h | 62 +
libkdepim/freebusymodel/tests/CMakeLists.txt | 22
libkdepim/freebusymodel/tests/modeltest.cpp | 643 +++++++++++++++
libkdepim/freebusymodel/tests/modeltest.h | 80 +
libkdepim/freebusymodel/tests/testfreebusyitemmodel.cpp | 240 +++++
libkdepim/freebusymodel/tests/testfreebusyitemmodel.h | 33
libkdepim/freebusymodel/tests/testfreeperiodmodel.cpp | 87 ++
libkdepim/freebusymodel/tests/testfreeperiodmodel.h | 32
50 files changed, 2764 insertions(+), 1521 deletions(-)
New commits:
commit 8722a631dcd70b329f52d1060d0e1cebcb0f68ce
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Oct 8 17:06:28 2014 +0200
better errormessages
diff --git a/calendarviews/agenda/viewcalendar.cpp b/calendarviews/agenda/viewcalendar.cpp
index 595c783..aa1555d 100644
--- a/calendarviews/agenda/viewcalendar.cpp
+++ b/calendarviews/agenda/viewcalendar.cpp
@@ -134,7 +134,7 @@ Akonadi::Item AkonadiViewCalendar::item(const KCalCore::Incidence::Ptr &incidenc
if (id == -1) {
// Ok, we really don't know the ID, give up.
- kWarning() << "Agenda::removeIncidence() Item to remove is invalid. uid = "
+ kDebug() << "Item is invalid. uid = "
<< incidence->instanceIdentifier();
return Akonadi::Item();
}
commit e252dae1d9ef3d07ebd3fee788142f3f6a85f89e
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Oct 8 17:04:49 2014 +0200
Korganizer: Add quickview for person collections
KOLAB: #3054
diff --git a/korganizer/CMakeLists.txt b/korganizer/CMakeLists.txt
index b1e0bb3..5c7645e 100644
--- a/korganizer/CMakeLists.txt
+++ b/korganizer/CMakeLists.txt
@@ -176,6 +176,7 @@ set(korganizerprivate_LIB_SRCS
views/collectionview/reparentingmodel.cpp
views/collectionview/controller.cpp
views/collectionview/calendardelegate.cpp
+ views/collectionview/quickview.cpp
calendarview.cpp
datechecker.cpp
datenavigator.cpp
@@ -224,6 +225,7 @@ set(korganizerprivate_LIB_SRCS
publishdialog_base.ui
searchdialog_base.ui
timescaleedit_base.ui
+ views/collectionview/quickview.ui
)
qt4_add_resources(korganizerprivate_LIB_SRCS
diff --git a/korganizer/akonadicollectionview.cpp b/korganizer/akonadicollectionview.cpp
index c562255..0de456e 100644
--- a/korganizer/akonadicollectionview.cpp
+++ b/korganizer/akonadicollectionview.cpp
@@ -33,6 +33,8 @@
#include "koglobals.h"
#include "views/collectionview/reparentingmodel.h"
#include "views/collectionview/calendardelegate.h"
+#include "views/collectionview/quickview.h"
+
#include <calendarsupport/kcalprefs.h>
#include <calendarsupport/utils.h>
@@ -349,8 +351,8 @@ class CollectionFilter : public QSortFilterProxyModel
const Akonadi::Collection &col = sourceIndex.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
CollectionIdentificationAttribute *attr = col.attribute<CollectionIdentificationAttribute>();
//We filter the user folders because we insert person nodes for user folders.
- if (attr && ((attr->collectionNamespace() == "usertoplevel") || (attr->collectionNamespace() == "usertoplevel"))
- || (col.name().contains(QLatin1String("Other Users")))) {
+ if ( (attr && attr->collectionNamespace().startsWith("user"))
+ || col.name().contains(QLatin1String("Other Users"))) {
return false;
}
return true;
@@ -1018,7 +1020,7 @@ void AkonadiCollectionView::onAction(const QModelIndex &index, int a)
const StyledCalendarDelegate::Action action = static_cast<StyledCalendarDelegate::Action>(a);
switch (action) {
case StyledCalendarDelegate::AddToList: {
- const Akonadi::Collection col = index.data(CollectionRole).value<Akonadi::Collection>();
+ const Akonadi::Collection col = CalendarSupport::collectionFromIndex(index);
if (col.isValid()) {
mController->setCollectionState(col, Controller::Referenced);
} else {
@@ -1053,6 +1055,25 @@ void AkonadiCollectionView::onAction(const QModelIndex &index, int a)
}
}
break;
+ case StyledCalendarDelegate::Quickview: {
+ QVariant person = index.data(PersonRole);
+ Akonadi::Collection col = CalendarSupport::collectionFromIndex(index);
+ QModelIndex i = index;
+ while (!person.isValid()) {
+ i = i.parent();
+ if (!i.isValid()) {
+ break;
+ }
+ person = i.data(PersonRole);
+ }
+ if (person.isValid()) {
+ Quickview *quickview = new Quickview(person.value<Person>(), col);
+ quickview->show();
+ } else {
+ kWarning() << "No valid person found for" << index;
+ }
+ }
+ break;
}
}
diff --git a/korganizer/views/collectionview/calendardelegate.cpp b/korganizer/views/collectionview/calendardelegate.cpp
index ee29a3e..e77c9c1 100644
--- a/korganizer/views/collectionview/calendardelegate.cpp
+++ b/korganizer/views/collectionview/calendardelegate.cpp
@@ -28,6 +28,7 @@
#include <calendarsupport/utils.h>
#include <kohelper.h>
#include "controller.h"
+#include <akonadi/collectionidentificationattribute.h>
StyledCalendarDelegate::StyledCalendarDelegate(QObject * parent)
: QStyledItemDelegate(parent)
@@ -35,6 +36,7 @@ StyledCalendarDelegate::StyledCalendarDelegate(QObject * parent)
mPixmap.insert(Enable, KIconLoader().loadIcon(QLatin1String("bookmarks"), KIconLoader::Small));
mPixmap.insert(RemoveFromList, KIconLoader().loadIcon(QLatin1String("list-remove"), KIconLoader::Small));
mPixmap.insert(AddToList, KIconLoader().loadIcon(QLatin1String("list-add"), KIconLoader::Small));
+ mPixmap.insert(Quickview, KIconLoader().loadIcon(QLatin1String("quickview"), KIconLoader::Small));
}
StyledCalendarDelegate::~StyledCalendarDelegate()
@@ -94,6 +96,11 @@ QList<StyledCalendarDelegate::Action> StyledCalendarDelegate::getActions(const Q
// kDebug() << index.data().toString() << enabled;
QList<Action> buttons;
+
+ CollectionIdentificationAttribute *attr = col.attribute<CollectionIdentificationAttribute>();
+ if (attr && attr->collectionNamespace().startsWith("user")) {
+ buttons << Quickview;
+ }
if (isSearchResult) {
buttons << AddToList;
} else {
@@ -181,14 +188,11 @@ bool StyledCalendarDelegate::editorEvent(QEvent *event,
QMouseEvent *me = static_cast<QMouseEvent*>(event);
- if (enableButtonRect(option.rect, 1).contains(me->pos())) {
- button = 1;
- }
- if (enableButtonRect(option.rect, 2).contains(me->pos())) {
- button = 2;
- }
- if (enableButtonRect(option.rect, 3).contains(me->pos())) {
- button = 3;
+ for (int i = 1; i < 4; i++) {
+ if (enableButtonRect(option.rect, i).contains(me->pos())) {
+ button = i;
+ break;
+ }
}
if (me->button() != Qt::LeftButton || button < 0) {
return QStyledItemDelegate::editorEvent(event, model, option, index);
@@ -206,11 +210,13 @@ bool StyledCalendarDelegate::editorEvent(QEvent *event,
QStyleOptionViewItem opt = option;
opt.state |= QStyle::State_MouseOver;
- const Action a = getActions(opt, index).at(button - 1);
- // kDebug() << "Button clicked: " << a;
- emit action(index, a);
-
- return true;
+ QList<StyledCalendarDelegate::Action> actions = getActions(opt, index);
+ if (actions.count() >= button) {
+ const Action a = actions.at(button - 1);
+ emit action(index, a);
+ return true;
+ }
+ return QStyledItemDelegate::editorEvent(event, model, option, index);
}
QSize StyledCalendarDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
diff --git a/korganizer/views/collectionview/calendardelegate.h b/korganizer/views/collectionview/calendardelegate.h
index 788a1d3..0be37f6 100644
--- a/korganizer/views/collectionview/calendardelegate.h
+++ b/korganizer/views/collectionview/calendardelegate.h
@@ -35,7 +35,8 @@ public:
enum Action {
AddToList,
RemoveFromList,
- Enable
+ Enable,
+ Quickview
};
Q_SIGNALS:
diff --git a/korganizer/views/collectionview/controller.cpp b/korganizer/views/collectionview/controller.cpp
index 8f7808c..7c83a3c 100644
--- a/korganizer/views/collectionview/controller.cpp
+++ b/korganizer/views/collectionview/controller.cpp
@@ -111,15 +111,17 @@ bool CollectionNode::isDuplicateOf(const QModelIndex& sourceIndex)
}
-PersonNode::PersonNode(ReparentingModel& personModel, const Person& person)
+PersonNode::PersonNode(ReparentingModel& personModel, const Person& person, const QModelIndex &colIndex)
: Node(personModel),
mPerson(person),
mCheckState(Qt::Unchecked),
- isSearchNode(false)
+ isSearchNode(false),
+ mCollectionIndex(colIndex)
{
}
+
PersonNode::~PersonNode()
{
@@ -180,7 +182,12 @@ QVariant PersonNode::data(int role) const
if (role == NodeTypeRole) {
return PersonNodeRole;
}
- return QVariant();
+
+ if (mCollectionIndex.isValid()) {
+ return mCollectionIndex.data(role);
+ } else {
+ return QVariant();
+ }
}
bool PersonNode::setData(const QVariant& value, int role)
@@ -213,7 +220,7 @@ bool PersonNode::adopts(const QModelIndex& sourceIndex)
bool PersonNode::isDuplicateOf(const QModelIndex& sourceIndex)
{
- return (sourceIndex.data(PersonRole).value<Person>().name == mPerson.name);
+ return (sourceIndex.data(PersonRole).value<Person>().uid == mPerson.uid);
}
void PersonNodeManager::checkSourceIndex(const QModelIndex &sourceIndex)
@@ -231,7 +238,7 @@ void PersonNodeManager::checkSourceIndex(const QModelIndex &sourceIndex)
person.uid = col.name();
person.rootCollection = col.id();
- model.addNode(ReparentingModel::Node::Ptr(new PersonNode(model, person)));
+ model.addNode(ReparentingModel::Node::Ptr(new PersonNode(model, person, sourceIndex)));
}
}
}
@@ -250,7 +257,7 @@ void PersonNodeManager::checkSourceIndexRemoval(const QModelIndex &sourceIndex)
person.ou = QString::fromUtf8(attr->ou());
person.uid = col.name();
person.rootCollection = col.id();
- model.removeNode(PersonNode(model, person));
+ model.removeNode(PersonNode(model, person, sourceIndex));
}
}
}
@@ -649,7 +656,7 @@ void Controller::onCollectionsFound(KJob* job)
void Controller::onPersonsFound(const QList<Person> &persons)
{
Q_FOREACH(const Person &p, persons) {
- PersonNode *personNode = new PersonNode(*mSearchModel, p);
+ PersonNode *personNode = new PersonNode(*mSearchModel, p, QModelIndex());
personNode->isSearchNode = true;
//toggled by the checkbox, results in person getting added to main model
// connect(&personNode->emitter, SIGNAL(enabled(bool, Person)), this, SLOT(onPersonEnabled(bool, Person)));
@@ -659,7 +666,7 @@ void Controller::onPersonsFound(const QList<Person> &persons)
void Controller::onPersonUpdate(const Person &person)
{
- PersonNode *personNode = new PersonNode(*mSearchModel, person);
+ PersonNode *personNode = new PersonNode(*mSearchModel, person, QModelIndex());
personNode->isSearchNode = true;
mSearchModel->updateNode(ReparentingModel::Node::Ptr(personNode));
}
@@ -755,7 +762,7 @@ void Controller::addPerson(const Person &person)
//TODO: use the found collection and update attribute
}
- PersonNode *personNode = new PersonNode(*mPersonModel, person);
+ PersonNode *personNode = new PersonNode(*mPersonModel, person, QModelIndex());
personNode->setChecked(true);
mPersonModel->addNode(ReparentingModel::Node::Ptr(personNode));
@@ -770,7 +777,7 @@ void Controller::addPerson(const Person &person)
void Controller::removePerson(const Person &person)
{
kDebug() << person.uid << person.name << person.rootCollection;
- mPersonModel->removeNode(PersonNode(*mPersonModel, person));
+ mPersonModel->removeNode(PersonNode(*mPersonModel, person, QModelIndex()));
if (person.rootCollection > -1) {
setCollectionState(Akonadi::Collection(person.rootCollection), Disabled, true);
diff --git a/korganizer/views/collectionview/controller.h b/korganizer/views/collectionview/controller.h
index 916078e..0f404a0 100644
--- a/korganizer/views/collectionview/controller.h
+++ b/korganizer/views/collectionview/controller.h
@@ -89,7 +89,7 @@ public:
class PersonNode : public ReparentingModel::Node
{
public:
- PersonNode(ReparentingModel &personModel, const Person &person);
+ PersonNode(ReparentingModel &personModel, const Person &person, const QModelIndex &colIndex);
virtual ~PersonNode();
virtual bool operator==(const Node &) const;
@@ -107,6 +107,7 @@ private:
Person mPerson;
Qt::CheckState mCheckState;
+ QModelIndex mCollectionIndex;
};
class CollectionNode : public ReparentingModel::Node
diff --git a/korganizer/views/collectionview/quickview.cpp b/korganizer/views/collectionview/quickview.cpp
new file mode 100644
index 0000000..f9a7963
--- /dev/null
+++ b/korganizer/views/collectionview/quickview.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright 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) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+//http://stackoverflow.com/questions/18831242/qt-start-editing-of-cell-after-one-click
+
+#include "quickview.h"
+#include "ui_quickview.h"
+
+#include <KCalCore/Event>
+#include <KCalCore/FreeBusy>
+#include <KCalCore/MemoryCalendar>
+#include <akonadi/entitydisplayattribute.h>
+#include <akonadi/changerecorder.h>
+#include <akonadi/itemfetchscope.h>
+
+#include <calendarviews/agenda/agendaview.h>
+#include <calendarviews/agenda/viewcalendar.h>
+#include <calendarsupport/calendarsingleton.h>
+
+#include <freebusymodel/freebusycalendar.h>
+
+#include <KDebug>
+#include <KSystemTimeZones>
+#include <KCheckableProxyModel>
+
+class FreebusyViewCalendar : public EventViews::ViewCalendar
+{
+public:
+ virtual ~FreebusyViewCalendar() {};
+ virtual bool isValid(const KCalCore::Incidence::Ptr &incidence) const
+ {
+ return incidence->uid().startsWith(QLatin1String("fb-"));
+ }
+
+ virtual QString displayName(const KCalCore::Incidence::Ptr &incidence) const
+ {
+ Q_UNUSED(incidence);
+ return i18n("Freebusycalendar from %1").arg(name);
+ }
+
+ virtual QColor resourceColor(const KCalCore::Incidence::Ptr &incidence) const
+ {
+ bool ok = false;
+ int status = incidence->customProperty("FREEBUSY", "STATUS").toInt(&ok);
+
+ if (!ok) {
+ return QColor("#555");
+ }
+
+ switch (status) {
+ case KCalCore::FreeBusyPeriod::Busy:
+ return QColor("#f00");
+ case KCalCore::FreeBusyPeriod::BusyTentative:
+ case KCalCore::FreeBusyPeriod::BusyUnavailable:
+ return QColor("#f70");
+ case KCalCore::FreeBusyPeriod::Free:
+ return QColor("#0f0");
+ default:
+ return QColor("#555");
+ }
+ }
+
+ virtual QString iconForIncidence(const KCalCore::Incidence::Ptr &incidence) const
+ {
+ return QString();
+ }
+
+ virtual KCalCore::Calendar::Ptr getCalendar() const
+ {
+ return mCalendar;
+ }
+
+ KCalCore::Calendar::Ptr mCalendar;
+ QString name;
+};
+
+Quickview::Quickview(const Person &person, const Akonadi::Collection &col)
+ : mPerson(person)
+ , mCollection(col)
+ , mDayRange(7)
+{
+ mUi = new Ui_quickview;
+
+ QWidget *w = new QWidget( this );
+ mUi->setupUi( w );
+ setMainWidget( w );
+
+ mAgendaView = new EventViews::AgendaView(QDate(), QDate(), false, false);
+
+ //show fbcalendar for person in quickview
+ if (!person.mail.isEmpty()) {
+ FreeBusyItemModel *model = new FreeBusyItemModel(this);
+ FreeBusyCalendar *fbCal = new FreeBusyCalendar(this);
+ FreebusyViewCalendar *fbCalendar = new FreebusyViewCalendar();
+ KCalCore::Attendee::Ptr attendee(new KCalCore::Attendee(person.name, person.mail));
+ FreeBusyItem::Ptr freebusy( new FreeBusyItem( attendee, this ));
+
+ fbCal->setModel(model);
+ model->addItem(freebusy);
+ fbCalendar->mCalendar = fbCal->calendar();
+ fbCalendar->name = attendee->fullName();
+ mAgendaView->addCalendar(EventViews::ViewCalendar::Ptr(fbCalendar));
+ }
+
+ if (mCollection.isValid()) {
+ //create etm for mCollection
+ Akonadi::ChangeRecorder *monitor = new Akonadi::ChangeRecorder(this);
+ Akonadi::ItemFetchScope scope;
+ QStringList allMimeTypes;
+
+ allMimeTypes << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType()
+ << KCalCore::Journal::journalMimeType();
+
+ scope.fetchFullPayload(true);
+ scope.fetchAttribute<Akonadi::EntityDisplayAttribute>();
+
+ monitor->setCollectionMonitored(mCollection);
+ monitor->fetchCollection(true);
+ monitor->setItemFetchScope(scope);
+ monitor->setAllMonitored(true);
+
+ foreach(const QString &mimetype, allMimeTypes) {
+ monitor->setMimeTypeMonitored(mimetype, true);
+ }
+
+ Akonadi::ETMCalendar::Ptr calendar = Akonadi::ETMCalendar::Ptr(new Akonadi::ETMCalendar(monitor));
+
+ calendar->setCollectionFilteringEnabled(false);
+ mAgendaView->setCalendar(calendar);
+ }
+ mUi->calender->addWidget( mAgendaView );
+
+ connect(mUi->mTodayBtn, SIGNAL(clicked(bool)), SLOT(onTodayClicked()));
+ connect(mUi->mNextBtn, SIGNAL(clicked(bool)), SLOT(onNextClicked()));
+ connect(mUi->mPreviousBtn, SIGNAL(clicked(bool)), SLOT(onPreviousClicked()));
+
+ onTodayClicked();
+}
+
+Quickview::~Quickview()
+{
+
+}
+
+void Quickview::onNextClicked()
+{
+ QDate start = mAgendaView->startDate().addDays(mDayRange);
+ mAgendaView->showDates(start, start.addDays(mDayRange-1));
+}
+
+void Quickview::onPreviousClicked()
+{
+ QDate start = mAgendaView->startDate().addDays(-mDayRange);
+ mAgendaView->showDates(start, start.addDays(mDayRange-1));
+}
+
+void Quickview::onTodayClicked()
+{
+ QDate start = QDate::currentDate();
+ start = start.addDays(-QDate::currentDate().dayOfWeek()+1);
+ mAgendaView->showDates(start, start.addDays(mDayRange-1));
+}
+
+
+#include "quickview.moc"
diff --git a/korganizer/views/collectionview/quickview.h b/korganizer/views/collectionview/quickview.h
new file mode 100644
index 0000000..d296887
--- /dev/null
+++ b/korganizer/views/collectionview/quickview.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 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) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef KORG_QUICKVIEW_H
+#define KORG_QUICKVIEW_H
+
+#include "controller.h"
+
+#include <calendarviews/agenda/viewcalendar.h>
+
+#include <KCalCore/FreeBusy>
+#include <KDialog>
+
+#include <QStringList>
+#include <QStringListModel>
+
+class Ui_quickview;
+
+namespace EventViews
+{
+ class AgendaView;
+}
+
+class Quickview : public KDialog
+{
+ Q_OBJECT
+public:
+ Quickview(const Person &person, const Akonadi::Collection &col);
+ virtual ~Quickview();
+
+private slots:
+ void onTodayClicked();
+ void onNextClicked();
+ void onPreviousClicked();
+
+private:
+ Ui_quickview *mUi;
+ EventViews::AgendaView *mAgendaView;
+ Person mPerson;
+ Akonadi::Collection mCollection;
+ int mDayRange;
+};
+
+#endif // QUICKVIEW_H
diff --git a/korganizer/views/collectionview/quickview.ui b/korganizer/views/collectionview/quickview.ui
new file mode 100644
index 0000000..8854b60
--- /dev/null
+++ b/korganizer/views/collectionview/quickview.ui
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>quickview</class>
+ <widget class="QWidget" name="quickview">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>552</width>
+ <height>566</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="mDayBtn">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Day</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mWeekBtn">
+ <property name="text">
+ <string>Week</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mMothBtn">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Month</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mAgendaBtn">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Agenda</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mPreviousBtn">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string><</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mTodayBtn">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Today</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mNextBtn">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>></string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="calender">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetDefaultConstraint</enum>
+ </property>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
commit 17d17a084b69bbae1a2f1421c19fd2f5adabb981
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Wed Oct 8 16:58:16 2014 +0200
Moving freebusy model to libkdepim to reuse it for quickview.
KOLAB: #3122
diff --git a/incidenceeditor-ng/CMakeLists.txt b/incidenceeditor-ng/CMakeLists.txt
index eb53e5b..0659bf0 100644
--- a/incidenceeditor-ng/CMakeLists.txt
+++ b/incidenceeditor-ng/CMakeLists.txt
@@ -47,10 +47,7 @@ set(incidenceeditors_ng_shared_LIB_SRCS
incidenceresource.cpp
incidencesecrecy.cpp
- freebusyitem.cpp
- freebusyitemmodel.cpp
freebusyganttproxymodel.cpp
- freeperiodmodel.cpp
conflictresolver.cpp
schedulingdialog.cpp
groupwareuidelegate.cpp
diff --git a/incidenceeditor-ng/conflictresolver.cpp b/incidenceeditor-ng/conflictresolver.cpp
index 38b7c56..e8691a1 100644
--- a/incidenceeditor-ng/conflictresolver.cpp
+++ b/incidenceeditor-ng/conflictresolver.cpp
@@ -21,7 +21,7 @@
*/
#include "conflictresolver.h"
-#include "freebusyitemmodel.h"
+#include "freebusymodel/freebusyitemmodel.h"
#include <KCalendarSystem>
#include <KDebug>
diff --git a/incidenceeditor-ng/conflictresolver.h b/incidenceeditor-ng/conflictresolver.h
index 82e3708..d01f202 100644
--- a/incidenceeditor-ng/conflictresolver.h
+++ b/incidenceeditor-ng/conflictresolver.h
@@ -24,16 +24,16 @@
#define INCIDENCEEDITOR_CONFLICTRESOLVER_H
#include "incidenceeditors-ng_export.h"
-#include "freebusyitem.h"
+#include "freebusymodel/freebusyitem.h"
#include <QBitArray>
#include <QSet>
#include <QTimer>
-namespace IncidenceEditorNG {
-
class FreeBusyItemModel;
+namespace IncidenceEditorNG {
+
/**
* Takes a list of attendees and event info (e.g., min time start, max time end)
* fetches their freebusy information, then identifies conflicts and periods of non-conflict.
diff --git a/incidenceeditor-ng/freebusyganttproxymodel.cpp b/incidenceeditor-ng/freebusyganttproxymodel.cpp
index 7b5bc21..25cbc03 100644
--- a/incidenceeditor-ng/freebusyganttproxymodel.cpp
+++ b/incidenceeditor-ng/freebusyganttproxymodel.cpp
@@ -19,7 +19,7 @@
*/
#include "freebusyganttproxymodel.h"
-#include "freebusyitemmodel.h"
+#include "freebusymodel/freebusyitemmodel.h"
#include <kdgantt2/kdganttgraphicsview.h>
diff --git a/incidenceeditor-ng/freebusyitem.cpp b/incidenceeditor-ng/freebusyitem.cpp
deleted file mode 100644
index 8752a51..0000000
--- a/incidenceeditor-ng/freebusyitem.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- Copyright (c) 2000,2001,2004 Cornelius Schumacher <schumacher at kde.org>
- Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info at kdab.com
- Copyright (c) 2010 Andras Mantia <andras at kdab.com>
- Copyright (C) 2010 Casey Link <casey at kdab.com>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "freebusyitem.h"
-
-#include <akonadi/calendar/freebusymanager.h>
-
-using namespace IncidenceEditorNG;
-
-FreeBusyItem::FreeBusyItem( const KCalCore::Attendee::Ptr &attendee, QWidget *parentWidget )
- : mAttendee( attendee ), mTimerID( 0 ), mIsDownloading( false ), mParentWidget( parentWidget )
-{
- Q_ASSERT( attendee );
- setFreeBusy( KCalCore::FreeBusy::Ptr() );
-}
-
-KCalCore::Attendee::Ptr FreeBusyItem::attendee() const
-{
- return mAttendee;
-}
-
-void FreeBusyItem::setFreeBusy( const KCalCore::FreeBusy::Ptr &fb )
-{
- mFreeBusy = fb;
- mIsDownloading = false;
-}
-
-KCalCore::FreeBusy::Ptr FreeBusyItem::freeBusy() const
-{
- return mFreeBusy;
-}
-
-QString FreeBusyItem::email() const
-{
- return mAttendee->email();
-}
-
-void FreeBusyItem::setUpdateTimerID( int id )
-{
- mTimerID = id;
-}
-
-int FreeBusyItem::updateTimerID() const
-{
- return mTimerID;
-}
-
-void FreeBusyItem::startDownload( bool forceDownload )
-{
- mIsDownloading = true;
- Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
- if ( !m->retrieveFreeBusy( attendee()->email(), forceDownload, mParentWidget ) ) {
- mIsDownloading = false;
- }
-}
-
-void FreeBusyItem::setIsDownloading( bool d )
-{
- mIsDownloading = d;
-}
-
-bool FreeBusyItem::isDownloading() const
-{
- return mIsDownloading;
-}
diff --git a/incidenceeditor-ng/freebusyitem.h b/incidenceeditor-ng/freebusyitem.h
deleted file mode 100644
index 036adbb..0000000
--- a/incidenceeditor-ng/freebusyitem.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- Copyright (c) 2000,2001,2004 Cornelius Schumacher <schumacher at kde.org>
- Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info at kdab.com
- Copyright (c) 2010 Andras Mantia <andras at kdab.com>
- Copyright (C) 2010 Casey Link <casey at kdab.com>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef INCIDENCEEDITOR_FREEBUSYITEM_H
-#define INCIDENCEEDITOR_FREEBUSYITEM_H
-
-#include "incidenceeditors-ng_export.h"
-
-#include <KCalCore/FreeBusy>
-
-namespace IncidenceEditorNG {
-
-/**
- * The FreeBusyItem is the whole line for a given attendee..
- */
-class INCIDENCEEDITORS_NG_EXPORT FreeBusyItem
-{
- public:
- typedef QSharedPointer<FreeBusyItem> Ptr;
-
- /**
- * @param parentWidget is passed to Akonadi when fetching free/busy data.
- */
- FreeBusyItem( const KCalCore::Attendee::Ptr &attendee, QWidget *parentWidget );
- ~FreeBusyItem() {}
-
- KCalCore::Attendee::Ptr attendee() const;
- void setFreeBusy( const KCalCore::FreeBusy::Ptr &fb );
- KCalCore::FreeBusy::Ptr freeBusy() const;
-
- QString email() const;
- void setUpdateTimerID( int id );
- int updateTimerID() const;
-
- void startDownload( bool forceDownload );
- void setIsDownloading( bool d );
- bool isDownloading() const;
-
- signals:
- void attendeeChanged( const KCalCore::Attendee::Ptr &attendee );
- void freebusyChanged( const KCalCore::FreeBusy::Ptr fb );
-
- private:
- KCalCore::Attendee::Ptr mAttendee;
- KCalCore::FreeBusy::Ptr mFreeBusy;
-
- // This is used for the update timer
- int mTimerID;
-
- // Only run one download job at a time
- bool mIsDownloading;
-
- QWidget *mParentWidget;
-};
-
-}
-#endif
diff --git a/incidenceeditor-ng/freebusyitemmodel.cpp b/incidenceeditor-ng/freebusyitemmodel.cpp
deleted file mode 100644
index 62141f9..0000000
--- a/incidenceeditor-ng/freebusyitemmodel.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "freebusyitemmodel.h"
-
-#include <akonadi/calendar/freebusymanager.h>
-
-#include <KDebug>
-#include <KGlobal>
-#include <KLocalizedString>
-#include <KLocale>
-
-#include <QTimerEvent>
-
-using namespace IncidenceEditorNG;
-
-namespace IncidenceEditorNG {
-
-class ItemPrivateData
-{
- public:
- ItemPrivateData( ItemPrivateData *parent ) : parentItem( parent )
- {
- }
-
- ~ItemPrivateData()
- {
- qDeleteAll( childItems );
- }
-
- ItemPrivateData *child( int row )
- {
- return childItems.value( row );
- }
-
- void appendChild( ItemPrivateData *item )
- {
- childItems.append(item);
- }
-
- ItemPrivateData *removeChild( int row )
- {
- return childItems.takeAt( row );
- }
-
- int childCount() const
- {
- return childItems.count();
- }
-
- int row() const
- {
- if ( parentItem ) {
- return parentItem->childItems.indexOf( const_cast<ItemPrivateData*>(this) );
- }
- return 0;
- }
-
- ItemPrivateData *parent()
- {
- return parentItem;
- }
-
- private:
- QList<ItemPrivateData*> childItems;
- ItemPrivateData *parentItem;
-};
-
-}
-
-FreeBusyItemModel::FreeBusyItemModel( QObject *parent )
- : QAbstractItemModel( parent ), mForceDownload( false )
-{
- qRegisterMetaType<KCalCore::Attendee::Ptr>( "KCalCore::Attendee::Ptr" );
- qRegisterMetaType<KCalCore::FreeBusy::Ptr>( "KCalCore::FreeBusy::Ptr" );
- qRegisterMetaType<KCalCore::Period>( "KCalCore::Period" );
-
- Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
- connect( m, SIGNAL(freeBusyRetrieved(KCalCore::FreeBusy::Ptr,QString)),
- SLOT(slotInsertFreeBusy(KCalCore::FreeBusy::Ptr,QString)) );
-
- connect( &mReloadTimer, SIGNAL(timeout()), SLOT(autoReload()) );
- mReloadTimer.setSingleShot( true );
-
- mRootData = new ItemPrivateData( 0 );
-}
-
-FreeBusyItemModel::~FreeBusyItemModel()
-{
- delete mRootData;
-}
-
-QVariant FreeBusyItemModel::data( const QModelIndex &index, int role ) const
-{
- if ( !index.isValid() ) {
- return QVariant();
- }
-
- ItemPrivateData *data = (ItemPrivateData*) index.internalPointer();
-
- if ( data->parent() == mRootData ) {
- int row = index.row();
- if ( row >= mFreeBusyItems.size() ) {
- return QVariant();
- }
-
- switch( role ) {
- case Qt::DisplayRole:
- return mFreeBusyItems.at( row )->attendee()->fullName();
- case FreeBusyItemModel::AttendeeRole:
- return QVariant::fromValue( mFreeBusyItems.at( row )->attendee() );
- case FreeBusyItemModel::FreeBusyRole:
- if ( mFreeBusyItems.at( row )->freeBusy() ) {
- return QVariant::fromValue( mFreeBusyItems.at( row )->freeBusy() );
- } else {
- return QVariant();
- }
- default:
- return QVariant();
- }
- }
-
- FreeBusyItem::Ptr fbitem = mFreeBusyItems.at( data->parent()->row() );
- if ( !fbitem->freeBusy() || index.row() >= fbitem->freeBusy()->busyPeriods().size() ) {
- return QVariant();
- }
-
- KCalCore::FreeBusyPeriod period = fbitem->freeBusy()->fullBusyPeriods().at( index.row() );
- switch( role ) {
- case Qt::DisplayRole: // return something to make modeltest happy
- return QString( "%1 - %2" ).
- arg( KGlobal::locale()->formatDateTime( period.start() ) ).
- arg( KGlobal::locale()->formatDateTime( period.end() ) );
- case FreeBusyItemModel::FreeBusyPeriodRole:
- return QVariant::fromValue( period );
- default:
- return QVariant();
- }
-}
-
-int FreeBusyItemModel::rowCount( const QModelIndex &parent ) const
-{
- ItemPrivateData *parentData;
- if ( parent.column() > 0 ) {
- return 0;
- }
-
- if ( !parent.isValid() ) {
- parentData = mRootData;
- } else {
- parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
- }
-
- return parentData->childCount();
-}
-
-int FreeBusyItemModel::columnCount( const QModelIndex &parent ) const
-{
- Q_UNUSED( parent );
- return 1;
-}
-
-QModelIndex FreeBusyItemModel::index( int row, int column, const QModelIndex &parent ) const
-{
- if ( !hasIndex( row, column, parent ) ) {
- return QModelIndex();
- }
-
- ItemPrivateData *parentData;
- if ( !parent.isValid() ) {
- parentData = mRootData;
- } else {
- parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
- }
-
- ItemPrivateData *childData = parentData->child( row );
- if ( childData ) {
- return createIndex( row, column, childData );
- } else {
- return QModelIndex();
- }
-// FreeBusyItem::Ptr item = mFreeBusyItems.at( parent.row() );
-// KCalCore::FreeBusy::Ptr fb = item->freeBusy();
-// if( !fb )
-// return QModelIndex();
-//
-// QList<KCalCore::FreeBusyPeriod> busyPeriods = fb->fullBusyPeriods();
-// if( row < busyPeriods.size() )
-// return createIndex( row, column, new ItemPrivateData( parent.row() ) );
-// else
-// return QModelIndex();
-// }
-}
-
-QModelIndex FreeBusyItemModel::parent( const QModelIndex &child ) const
-{
- if ( !child.isValid() ) {
- return QModelIndex();
- }
-
- ItemPrivateData *childData = static_cast<ItemPrivateData*>( child.internalPointer() );
- ItemPrivateData *parentData = childData->parent();
- if ( parentData == mRootData ) {
- return QModelIndex();
- }
-
- return createIndex( parentData->row(), 0, parentData );
-}
-
-QVariant FreeBusyItemModel::headerData( int section, Qt::Orientation orientation, int role ) const
-{
- if ( role == Qt::DisplayRole && orientation == Qt::Horizontal && section == 0 ) {
- return i18n( "Attendee" );
- }
- return QVariant();
-}
-
-void FreeBusyItemModel::addItem( const IncidenceEditorNG::FreeBusyItem::Ptr &freebusy )
-{
- kDebug() << freebusy->attendee()->fullName();
- int row = mFreeBusyItems.size();
- beginInsertRows( QModelIndex(), row, row );
- mFreeBusyItems.append( freebusy );
- ItemPrivateData *data = new ItemPrivateData( mRootData );
- mRootData->appendChild( data );
- endInsertRows();
-
- if ( freebusy->freeBusy() && freebusy->freeBusy()->fullBusyPeriods().size() > 0 ) {
- QModelIndex parent = index( row, 0 );
- setFreeBusyPeriods( parent, freebusy->freeBusy()->fullBusyPeriods() );
- }
- updateFreeBusyData( freebusy );
-}
-
-void FreeBusyItemModel::setFreeBusyPeriods( const QModelIndex &parent,
- const KCalCore::FreeBusyPeriod::List &list )
-{
- if(!parent.isValid())
- return;
-
- ItemPrivateData *parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
- QModelIndex first = index( 0, 0, parent );
- QModelIndex last = index( parentData->childCount() - 1, 0, parent );
- int fb_count = list.size();
- int childCount = parentData->childCount();
-
- if ( childCount > 0 && fb_count < childCount ) {
- beginRemoveRows( parent, fb_count-1<0 ? 0 : fb_count-1 , childCount - 1 );
- for ( int i = childCount - 1; i > fb_count; --i ) {
- delete parentData->removeChild( i );
- }
- endRemoveRows();
- if (fb_count > 0) {
- last = index(fb_count-1, 0, parent);
- emit dataChanged(first, last);
- }
- } else if (fb_count > childCount) {
- beginInsertRows( parent, childCount-1 < 0 ? 0 : childCount-1, fb_count - 1 );
- for ( int i=childCount-1; i < fb_count; ++i ) {
- ItemPrivateData *childData= new ItemPrivateData( parentData );
- parentData->appendChild( childData );
- }
- endInsertRows();
- if (childCount > 0) {
- last = index(childCount-1, 0, parent);
- emit dataChanged(first, last);
- }
- } else if (fb_count == childCount && fb_count > 0) {
- emit dataChanged( first, last );
- }
-}
-
-void FreeBusyItemModel::clear()
-{
- beginResetModel();
- mFreeBusyItems.clear();
- delete mRootData;
- mRootData = new ItemPrivateData( 0 );
- endResetModel();
-}
-
-void IncidenceEditorNG::FreeBusyItemModel::removeRow( int row )
-{
- beginRemoveRows( QModelIndex(), row, row );
- mFreeBusyItems.removeAt( row );
- ItemPrivateData *data = mRootData->removeChild( row );
- delete data;
- endRemoveRows();
-}
-
-void FreeBusyItemModel::removeItem( const IncidenceEditorNG::FreeBusyItem::Ptr &freebusy )
-{
- int row = mFreeBusyItems.indexOf( freebusy );
- if( row >= 0 ) {
- removeRow( row );
- }
-}
-
-void FreeBusyItemModel::removeAttendee( const KCalCore::Attendee::Ptr &attendee )
-{
- FreeBusyItem::Ptr anItem;
- for ( int i = 0; i < mFreeBusyItems.count(); ++i ) {
- anItem = mFreeBusyItems[i];
- if ( *anItem->attendee() == *attendee ) {
- if ( anItem->updateTimerID() != 0 ) {
- killTimer( anItem->updateTimerID() );
- }
- removeRow( i );
- break;
- }
- }
-}
-
-bool FreeBusyItemModel::containsAttendee( const KCalCore::Attendee::Ptr &attendee )
-{
- FreeBusyItem::Ptr anItem;
- for ( int i = 0; i < mFreeBusyItems.count(); ++i ) {
- anItem = mFreeBusyItems[i];
- if ( *anItem->attendee() == *attendee ) {
- return true;
- }
- }
- return false;
-}
-
-void FreeBusyItemModel::updateFreeBusyData( const FreeBusyItem::Ptr &item )
-{
- if ( item->isDownloading() ) {
- // This item is already in the process of fetching the FB list
- return;
- }
-
- if ( item->updateTimerID() != 0 ) {
- // An update timer is already running. Reset it
- killTimer( item->updateTimerID() );
- }
-
- // This item does not have a download running, and no timer is set
- // Do the download in one second
- item->setUpdateTimerID( startTimer( 1000 ) );
-}
-
-void FreeBusyItemModel::timerEvent( QTimerEvent *event )
-{
- killTimer( event->timerId() );
- Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
- if ( item->updateTimerID() == event->timerId() ) {
- item->setUpdateTimerID( 0 );
- item->startDownload( mForceDownload );
- return;
- }
- }
-}
-
-void FreeBusyItemModel::slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb,
- const QString &email )
-{
- if ( !fb ) {
- return;
- }
-
- if ( fb->fullBusyPeriods().isEmpty() ) {
- return;
- }
-
- fb->sortList();
-
- Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
- if ( item->email() == email ) {
- item->setFreeBusy( fb );
- const int row = mFreeBusyItems.indexOf( item );
- const QModelIndex parent = index( row, 0 );
- emit dataChanged(parent, parent);
- setFreeBusyPeriods( parent, fb->fullBusyPeriods() );
- }
- }
-}
-
-void FreeBusyItemModel::autoReload()
-{
- mForceDownload = false;
- reload();
-}
-
-void FreeBusyItemModel::reload()
-{
- Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
- if ( mForceDownload ) {
- item->startDownload( mForceDownload );
- } else {
- updateFreeBusyData( item );
- }
- }
-}
-
-void FreeBusyItemModel::triggerReload()
-{
- mReloadTimer.start( 1000 );
-}
-
-void FreeBusyItemModel::cancelReload()
-{
- mReloadTimer.stop();
-}
-
-void FreeBusyItemModel::manualReload()
-{
- mForceDownload = true;
- reload();
-}
diff --git a/incidenceeditor-ng/freebusyitemmodel.h b/incidenceeditor-ng/freebusyitemmodel.h
deleted file mode 100644
index 8123b8e..0000000
--- a/incidenceeditor-ng/freebusyitemmodel.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef INCIDENCEEDITOR_FREEBUSYITEMMODEL_H
-#define INCIDENCEEDITOR_FREEBUSYITEMMODEL_H
-
-#include "incidenceeditors-ng_export.h"
-#include "freebusyitem.h"
-
-#include <QAbstractItemModel>
-#include <QTimer>
-
-namespace IncidenceEditorNG {
-
-class ItemPrivateData;
-
-/**
- * The FreeBusyItemModel is a 2-level tree structure.
- *
- * The top level parent nodes represent the freebusy items, and
- * the 2nd-level child nodes represent the FreeBusyPeriods of the parent
- * freebusy item.
- */
-class INCIDENCEEDITORS_NG_EXPORT FreeBusyItemModel : public QAbstractItemModel
-{
- Q_OBJECT
- public:
- enum Roles {
- AttendeeRole = Qt::UserRole,
- FreeBusyRole,
- FreeBusyPeriodRole
- };
-
- explicit FreeBusyItemModel( QObject *parent = 0 );
- virtual ~FreeBusyItemModel();
-
- virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
- virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
- virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
- virtual QModelIndex index( int row, int column = 0,
- const QModelIndex &parent = QModelIndex() ) const;
- virtual QModelIndex parent( const QModelIndex &child ) const;
- virtual QVariant headerData( int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole ) const;
-
- void addItem( const FreeBusyItem::Ptr &freebusy );
-
- void clear();
- void removeAttendee( const KCalCore::Attendee::Ptr &attendee );
- void removeItem( const FreeBusyItem::Ptr &freebusy );
- void removeRow( int row );
-
- bool containsAttendee( const KCalCore::Attendee::Ptr &attendee );
-
- /**
- * Queues a reload of free/busy data.
- * All current attendees will have their free/busy data
- * redownloaded from Akonadi.
- */
- void triggerReload();
-
- /**
- * cancel reloading
- */
- void cancelReload();
-
- /**
- * Reload FB items
- */
- void reload();
-
- public slots:
- void slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb, const QString &email );
-
- protected:
- void timerEvent( QTimerEvent * );
-
- private slots:
- // Force the download of FB information
- void manualReload();
- // Only download FB if the auto-download option is set in config
- void autoReload();
-
- private:
- void setFreeBusyPeriods( const QModelIndex &parent,
- const KCalCore::FreeBusyPeriod::List &list );
- void updateFreeBusyData( const FreeBusyItem::Ptr & );
-
- QTimer mReloadTimer;
- bool mForceDownload;
- QList<FreeBusyItem::Ptr> mFreeBusyItems;
- ItemPrivateData *mRootData;
-};
-
-}
-
-#endif
diff --git a/incidenceeditor-ng/freeperiodmodel.cpp b/incidenceeditor-ng/freeperiodmodel.cpp
deleted file mode 100644
index 2446a9f..0000000
--- a/incidenceeditor-ng/freeperiodmodel.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "freeperiodmodel.h"
-
-#include <KCalCore/Period>
-
-#include <KCalendarSystem>
-#include <KGlobal>
-#include <KSystemTimeZones>
-
-#include <QSet>
-
-using namespace IncidenceEditorNG;
-
-FreePeriodModel::FreePeriodModel( QObject *parent ): QAbstractTableModel( parent )
-{
-}
-
-IncidenceEditorNG::FreePeriodModel::~FreePeriodModel()
-{
-}
-
-QVariant FreePeriodModel::data( const QModelIndex &index, int role ) const
-{
- if ( !index.isValid() || !hasIndex( index.row(), index.column() ) ) {
- return QVariant();
- }
-
- if( index.column() == 0 ) { //day
- switch( role ) {
- case Qt::DisplayRole:
- return day( index.row() );
- case Qt::ToolTipRole:
- return tooltipify( index.row() );
- case FreePeriodModel::PeriodRole:
- return QVariant::fromValue( mPeriodList.at( index.row() ) );
- case Qt::TextAlignmentRole:
- return static_cast<int>( Qt::AlignRight | Qt::AlignVCenter );
- default:
- return QVariant();
- }
- } else { // everything else
- switch( role ) {
- case Qt::DisplayRole:
- return date( index.row() );
- case Qt::ToolTipRole:
- return tooltipify( index.row() );
- case FreePeriodModel::PeriodRole:
- return QVariant::fromValue( mPeriodList.at( index.row() ) );
- case Qt::TextAlignmentRole:
- return static_cast<int>( Qt::AlignLeft | Qt::AlignVCenter );
- default:
- return QVariant();
- }
- }
-}
-
-int FreePeriodModel::rowCount( const QModelIndex &parent ) const
-{
- if ( !parent.isValid() ) {
- return mPeriodList.size();
- }
- return 0;
-}
-
-int FreePeriodModel::columnCount( const QModelIndex &parent ) const
-{
- Q_UNUSED( parent );
- return 2;
-}
-
-QVariant FreePeriodModel::headerData( int section, Qt::Orientation orientation, int role ) const
-{
- return QAbstractItemModel::headerData( section, orientation, role );
-}
-
-void FreePeriodModel::slotNewFreePeriods( const KCalCore::Period::List &freePeriods )
-{
- beginResetModel();
- mPeriodList.clear();
- mPeriodList = splitPeriodsByDay( freePeriods );
- qSort( mPeriodList );
- endResetModel();
-}
-
-KCalCore::Period::List FreePeriodModel::splitPeriodsByDay(
- const KCalCore::Period::List &freePeriods )
-{
- KCalCore::Period::List splitList;
- foreach ( const KCalCore::Period &period, freePeriods ) {
- if ( period.start().date() == period.end().date() ) {
- splitList << period; // period occurs on the same day
- continue;
- }
-
- const int validPeriodSecs = 5 * 60; // 5 minutes
- KCalCore::Period tmpPeriod = period;
- while ( tmpPeriod.start().date() != tmpPeriod.end().date() ) {
- const KDateTime midnight( tmpPeriod.start().date(), QTime( 23, 59, 59, 999 ),
- tmpPeriod.start().timeSpec() );
- KCalCore::Period firstPeriod( tmpPeriod.start(), midnight );
- KCalCore::Period secondPeriod( midnight.addMSecs( 1 ), tmpPeriod.end() );
- if ( firstPeriod.duration().asSeconds() >= validPeriodSecs ) {
- splitList << firstPeriod;
- }
- tmpPeriod = secondPeriod;
- }
- if ( tmpPeriod.duration().asSeconds() >= validPeriodSecs ) {
- splitList << tmpPeriod;
- }
- }
-
- // Perform some jiggery pokery to remove duplicates
- QList<KCalCore::Period> tmpList = splitList.toList();
- QSet<KCalCore::Period>set = tmpList.toSet();
- tmpList = QList<KCalCore::Period>::fromSet( set );
- return KCalCore::Period::List::fromList( tmpList );
-}
-
-QString FreePeriodModel::day( int index ) const
-{
- KCalCore::Period period = mPeriodList.at( index );
- const KCalendarSystem *calSys = KGlobal::locale()->calendar();
- const QDate startDate = period.start().date();
- return ki18nc( "@label Day of the week name, example: Monday,", "%1," ).
- subs( calSys->weekDayName( startDate.dayOfWeek(), KCalendarSystem::LongDayName ) ).toString();
-}
-
-QString FreePeriodModel::date( int index ) const
-{
- KCalCore::Period period = mPeriodList.at( index );
- const KCalendarSystem *calSys = KGlobal::locale()->calendar();
-
- const QDate startDate = period.start().date();
- const QString startTime = KGlobal::locale()->formatTime( period.start().time() );
- const QString endTime = KGlobal::locale()->formatTime( period.end().time() );
- const QString longMonthName = calSys->monthName( startDate );
- return ki18nc( "@label A time period duration. It is preceded/followed (based on the "
- "orientation) by the name of the week, see the message above. "
- "example: 12 June, 8:00am to 9:30am",
- "%1 %2, %3 to %4" ).
- subs( startDate.day() ).
- subs( longMonthName ).
- subs( startTime ).
- subs( endTime ).toString();
-}
-
-QString FreePeriodModel::stringify( int index ) const
-{
- KCalCore::Period period = mPeriodList.at( index );
- const KCalendarSystem *calSys = KGlobal::locale()->calendar();
-
- const QDate startDate = period.start().date();
- const QString startTime = KGlobal::locale()->formatTime( period.start().time(), false, true );
- const QString endTime = KGlobal::locale()->formatTime( period.end().time(), false, true );
- const QString longMonthName = calSys->monthName( startDate );
- const QString dayofWeek = calSys->weekDayName( startDate.dayOfWeek(),
- KCalendarSystem::LongDayName );
-
- // TODO i18n, ping chusslove
- return ki18nc( "@label A time period duration. KLocale is used to format the components. "
- "example: Monday, 12 June, 8:00am to 9:30am",
- "%1, %2 %3, %4 to %5" ).
- subs( dayofWeek ).
- subs( startDate.day() ).
- subs( longMonthName ).
- subs( startTime ).
- subs( endTime ).toString();
-}
-
-QString FreePeriodModel::tooltipify( int index ) const
-{
- KDateTime::Spec timeSpec = KSystemTimeZones::local();
- KCalCore::Period period = mPeriodList.at( index );
- unsigned long duration = period.duration().asSeconds() * 1000; // we want milliseconds
- QString toolTip = "<qt>";
- toolTip += "<b>" + i18nc( "@info:tooltip", "Free Period" ) + "</b>";
- toolTip += "<hr>";
- toolTip += "<i>" + i18nc( "@info:tooltip period start time", "Start:" ) + "</i>" + " ";
- toolTip += KGlobal::locale()->formatDateTime( period.start().toTimeSpec( timeSpec ).dateTime() );
- toolTip += "<br>";
- toolTip += "<i>" + i18nc( "@info:tooltip period end time", "End:" ) + "</i>" + " ";
- toolTip += KGlobal::locale()->formatDateTime( period.end().toTimeSpec( timeSpec ).dateTime() );
- toolTip += "<br>";
- toolTip += "<i>" + i18nc( "@info:tooltip period duration", "Duration:" ) + "</i>" + " ";
- toolTip += KGlobal::locale()->prettyFormatDuration( duration );
- toolTip += "</qt>";
- return toolTip;
-}
-
diff --git a/incidenceeditor-ng/freeperiodmodel.h b/incidenceeditor-ng/freeperiodmodel.h
deleted file mode 100644
index c3eee9c..0000000
--- a/incidenceeditor-ng/freeperiodmodel.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#ifndef INCIDENCEEDITOR_FREEPERIODMODEL_H
-#define INCIDENCEEDITOR_FREEPERIODMODEL_H
-
-#include "incidenceeditors-ng_export.h"
-
-#include <KCalCore/Period>
-
-#include <QAbstractTableModel>
-
-namespace IncidenceEditorNG {
-
-class INCIDENCEEDITORS_NG_EXPORT FreePeriodModel : public QAbstractTableModel
-{
- Q_OBJECT
- public:
- enum Roles {
- PeriodRole = Qt::UserRole
- };
- explicit FreePeriodModel( QObject *parent = 0 );
- virtual ~FreePeriodModel();
-
- virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
- virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
- virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
- virtual QVariant headerData( int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole ) const;
-
- public slots:
- void slotNewFreePeriods( const KCalCore::Period::List &freePeriods );
-
- private:
- /** Splits period blocks in the provided list, so that each period occurs on one day */
- KCalCore::Period::List splitPeriodsByDay( const KCalCore::Period::List &freePeriods );
-
- QString day( int index ) const;
- QString date( int index ) const;
- QString stringify( int index ) const;
- QString tooltipify( int index ) const;
-
- KCalCore::Period::List mPeriodList;
- friend class FreePeriodModelTest;
-};
-
-}
-
-#endif
diff --git a/incidenceeditor-ng/incidenceattendee.cpp b/incidenceeditor-ng/incidenceattendee.cpp
index bab0c00..1c859be 100644
--- a/incidenceeditor-ng/incidenceattendee.cpp
+++ b/incidenceeditor-ng/incidenceattendee.cpp
@@ -30,7 +30,7 @@
#include "incidencedatetime.h"
#include "schedulingdialog.h"
#include "attendeecomboboxdelegate.h"
-#include "freebusyitemmodel.h"
+#include "freebusymodel/freebusyitemmodel.h"
#ifdef KDEPIM_MOBILE_UI
#include "ui_dialogmoremobile.h"
#else
diff --git a/incidenceeditor-ng/resourcemanagement.cpp b/incidenceeditor-ng/resourcemanagement.cpp
index b69d2bb..b75c9d3 100644
--- a/incidenceeditor-ng/resourcemanagement.cpp
+++ b/incidenceeditor-ng/resourcemanagement.cpp
@@ -24,7 +24,8 @@
#include "resourcemanagement.h"
#include "ui_resourcemanagement.h"
#include "resourcemodel.h"
-#include "freebusyitem.h"
+#include "freebusymodel/freebusyitem.h"
+#include "freebusymodel/freebusycalendar.h"
#include "ldaputils.h"
#include "freebusyganttproxymodel.h"
@@ -52,17 +53,9 @@
#include <QColor>
#include <KDebug>
-#include <KSystemTimeZones>
using namespace IncidenceEditorNG;
-enum FbStatus {
- Unkown,
- Free,
- Busy,
- Tentative
-};
-
class FreebusyViewCalendar : public EventViews::ViewCalendar
{
public:
@@ -88,11 +81,12 @@ public:
}
switch (status) {
- case Busy:
+ case KCalCore::FreeBusyPeriod::Busy:
return QColor("#f00");
- case Tentative:
+ case KCalCore::FreeBusyPeriod::BusyTentative:
+ case KCalCore::FreeBusyPeriod::BusyUnavailable:
return QColor("#f70");
- case Free:
+ case KCalCore::FreeBusyPeriod::Free:
return QColor("#0f0");
default:
return QColor("#555");
@@ -124,21 +118,12 @@ ResourceManagement::ResourceManagement()
QVariantList list;
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)));
+ mFreebusyCalendar.setModel(mModel);
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;
+ fbCalendar->mCalendar = mFreebusyCalendar.calendar();
mFbCalendar = EventViews::ViewCalendar::Ptr(fbCalendar);
mAgendaView->addCalendar(mFbCalendar);
@@ -243,8 +228,6 @@ void ResourceManagement::showDetails(const KLDAP::LdapObject &obj, const KLDAP::
FreeBusyItem::Ptr freebusy( new FreeBusyItem( attendee, this ));
mModel->clear();
mModel->addItem(freebusy);
-
-
}
void ResourceManagement::slotLayoutChanged()
@@ -295,7 +278,6 @@ void ResourceManagement::slotOwnerSearchFinished()
mUi->formOwner->addRow(translateLDAPAttributeForDisplay(key), new QLabel(list.join("\n")));
}
}
-
}
void ResourceManagement::slotDateChanged(QDate start, QDate end)
@@ -307,74 +289,4 @@ void ResourceManagement::slotDateChanged(QDate start, QDate end)
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"
+#include "resourcemanagement.moc"
\ No newline at end of file
diff --git a/incidenceeditor-ng/resourcemanagement.h b/incidenceeditor-ng/resourcemanagement.h
index ee8dc19..1943e5b 100644
--- a/incidenceeditor-ng/resourcemanagement.h
+++ b/incidenceeditor-ng/resourcemanagement.h
@@ -27,7 +27,7 @@
#include <ldap/ldapclient.h>
#include <ldap/ldapclientsearch.h>
-#include "freebusyitemmodel.h"
+#include "freebusymodel/freebusycalendar.h"
#include "resourceitem.h"
#include <calendarviews/agenda/viewcalendar.h>
@@ -88,13 +88,9 @@ 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;
+ FreeBusyCalendar mFreebusyCalendar;
ResourceItem::Ptr mOwnerItem;
ResourceItem::Ptr mSelectedItem;
EventViews::ViewCalendar::Ptr mFbCalendar;
diff --git a/incidenceeditor-ng/schedulingdialog.cpp b/incidenceeditor-ng/schedulingdialog.cpp
index 3c8f006..25cc208 100644
--- a/incidenceeditor-ng/schedulingdialog.cpp
+++ b/incidenceeditor-ng/schedulingdialog.cpp
@@ -20,7 +20,7 @@
#include "schedulingdialog.h"
#include "conflictresolver.h"
-#include "freeperiodmodel.h"
+#include "freebusymodel/freeperiodmodel.h"
#ifndef KDEPIM_MOBILE_UI
#include "visualfreebusywidget.h"
#endif
diff --git a/incidenceeditor-ng/schedulingdialog.h b/incidenceeditor-ng/schedulingdialog.h
index b90a77d..4eda936 100644
--- a/incidenceeditor-ng/schedulingdialog.h
+++ b/incidenceeditor-ng/schedulingdialog.h
@@ -30,9 +30,10 @@
#include <KDialog>
+class FreePeriodModel;
+
namespace IncidenceEditorNG {
-class FreePeriodModel;
class ConflictResolver;
class VisualFreeBusyWidget;
diff --git a/incidenceeditor-ng/tests/CMakeLists.txt b/incidenceeditor-ng/tests/CMakeLists.txt
index 5403c0f..edf9f35 100644
--- a/incidenceeditor-ng/tests/CMakeLists.txt
+++ b/incidenceeditor-ng/tests/CMakeLists.txt
@@ -20,8 +20,6 @@ ENDMACRO(IE_EXECUTABLE_TESTS)
IE_UNIT_TESTS(
conflictresolvertest
- testfreebusyitemmodel
- testfreeperiodmodel
testfreebusyganttproxymodel
)
@@ -60,4 +58,5 @@ target_link_libraries(resourcemanagement_gui
${KDE4_KDEUI_LIBS}
${KDEPIMLIBS_KMIME_LIBS}
incidenceeditorsng
+ kdepim
)
diff --git a/incidenceeditor-ng/tests/conflictresolvertest.h b/incidenceeditor-ng/tests/conflictresolvertest.h
index 99b9a61..82d643c 100644
--- a/incidenceeditor-ng/tests/conflictresolvertest.h
+++ b/incidenceeditor-ng/tests/conflictresolvertest.h
@@ -21,7 +21,7 @@
#ifndef CONFLICTRESOLVERTEST_H
#define CONFLICTRESOLVERTEST_H
-#include "../freebusyitem.h"
+#include "freebusymodel/freebusyitem.h"
#include <KCalCore/FreeBusy>
#include <KCalCore/Attendee>
@@ -51,7 +51,7 @@ class ConflictResolverTest : public QObject
void insertAttendees();
void addAttendee( const QString &email, const KCalCore::FreeBusy::Ptr &fb,
KCalCore::Attendee::Role role = KCalCore::Attendee::ReqParticipant ) ;
- QList<IncidenceEditorNG::FreeBusyItem::Ptr> attendees;
+ QList<FreeBusyItem::Ptr> attendees;
QWidget *parent;
IncidenceEditorNG::ConflictResolver *resolver;
KDateTime base, end;
diff --git a/incidenceeditor-ng/tests/testfreebusyganttproxymodel.cpp b/incidenceeditor-ng/tests/testfreebusyganttproxymodel.cpp
index 3c60fac..849c6aa 100644
--- a/incidenceeditor-ng/tests/testfreebusyganttproxymodel.cpp
+++ b/incidenceeditor-ng/tests/testfreebusyganttproxymodel.cpp
@@ -20,8 +20,8 @@
#include "testfreebusyganttproxymodel.h"
#include "modeltest.h"
-#include "../freebusyitem.h"
-#include "../freebusyitemmodel.h"
+#include "freebusymodel/freebusyitem.h"
+#include "freebusymodel/freebusyitemmodel.h"
#include "../freebusyganttproxymodel.h"
#include <kdgantt2/kdganttgraphicsview.h>
diff --git a/incidenceeditor-ng/tests/testfreebusyitemmodel.cpp b/incidenceeditor-ng/tests/testfreebusyitemmodel.cpp
deleted file mode 100644
index 62fa13a..0000000
--- a/incidenceeditor-ng/tests/testfreebusyitemmodel.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "testfreebusyitemmodel.h"
-#include "modeltest.h"
-#include "../freebusyitemmodel.h"
-#include "../freebusyitem.h"
-
-#include <KCalCore/Attendee>
-
-#include <qtest_kde.h>
-
-QTEST_KDEMAIN( FreeBusyItemModelTest, NoGUI )
-using namespace IncidenceEditorNG;
-
-void FreeBusyItemModelTest::testModelValidity()
-{
- FreeBusyItemModel * model = new FreeBusyItemModel( this );
- new ModelTest( model, this );
-
- QVERIFY( model->rowCount() == 0 );
-
- const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
- const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
- KCalCore::Attendee::Ptr a1( new KCalCore::Attendee( "fred", "fred at example.com" ) );
- KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
-
- fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
-
- FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
- item1->setFreeBusy( fb1 );
-
- model->addItem( item1 );
- QVERIFY( model->rowCount() == 1 );
- QVERIFY( model->containsAttendee( a1 ) );
-
- QModelIndex i = model->index( 0, 0 );
- QCOMPARE( a1->fullName(), model->data( i, Qt::DisplayRole ).toString() );
- QCOMPARE( a1,
- model->data( i, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
- QCOMPARE( item1->freeBusy(),
- model->data( i, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
-
- QCOMPARE( model->rowCount( i ), 2 );
-
- model->removeRow( 0 );
- QVERIFY( model->rowCount() == 0 );
-
- model->addItem( item1 );
- QVERIFY( model->rowCount() == 1 );
-
- model->removeAttendee( a1 );
- QVERIFY( model->rowCount() == 0 );
-
- model->addItem( item1 );
- QVERIFY( model->rowCount() == 1 );
-
- model->removeItem( item1 );
- QVERIFY( model->rowCount() == 0 );
-
- model->addItem( item1 );
- QVERIFY( model->rowCount() == 1 );
-
- model->clear();
- QVERIFY( model->rowCount() == 0 );
-}
-
-void FreeBusyItemModelTest::testModelValidity2()
-{
- FreeBusyItemModel * model = new FreeBusyItemModel( this );
- new ModelTest( model, this );
-
- const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
- const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
- const KDateTime dt3( QDate( 2010, 7, 24 ), QTime( 12, 0, 0 ), KDateTime::UTC );
- const KDateTime dt4( QDate( 2010, 7, 24 ), QTime( 14, 0, 0 ), KDateTime::UTC );
-
- KCalCore::Attendee::Ptr a1( new KCalCore::Attendee( "fred", "fred at example.com" ) );
- KCalCore::Attendee::Ptr a2( new KCalCore::Attendee( "joe", "joe at example.com" ) );
- KCalCore::Attendee::Ptr a3( new KCalCore::Attendee( "max", "max at example.com" ) );
- KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
- KCalCore::FreeBusy::Ptr fb2( new KCalCore::FreeBusy() );
- KCalCore::FreeBusy::Ptr fb3( new KCalCore::FreeBusy() );
-
- fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
-
- fb2->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb2->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
- fb2->addPeriod( dt3, KCalCore::Duration( 60 * 60 ) );
-
- fb3->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb3->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
- fb3->addPeriod( dt4, KCalCore::Duration( 60 * 60 * 2 ) );
-
- FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
- item1->setFreeBusy( fb1 );
- FreeBusyItem::Ptr item2( new FreeBusyItem( a2, 0 ) );
- FreeBusyItem::Ptr item3( new FreeBusyItem( a3, 0 ) );
-
- model->addItem( item1 );
- model->addItem( item2 );
- model->addItem( item3 );
-
- QCOMPARE( model->rowCount(), 3 );
-
- QVERIFY( model->containsAttendee( a1 ) );
- QVERIFY( model->containsAttendee( a2 ) );
- QVERIFY( model->containsAttendee( a3 ) );
-
- QModelIndex i1 = model->index( 0, 0 );
- QCOMPARE( a1->fullName(), model->data( i1, Qt::DisplayRole ).toString() );
- QCOMPARE( a1,
- model->data( i1, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
- QCOMPARE( item1->freeBusy(),
- model->data( i1, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
-
- QModelIndex i2 = model->index( 1, 0 );
- QCOMPARE( a2->fullName(), model->data( i2, Qt::DisplayRole ).toString() );
- QCOMPARE( a2,
- model->data( i2, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
- QVERIFY( model->rowCount( i2 ) == 0 );
- QVERIFY( model->data( i2, FreeBusyItemModel::FreeBusyRole ).isValid() == false );
-
- QModelIndex i3 = model->index( 2, 0 );
- QCOMPARE( a3->fullName(),
- model->data( i3, Qt::DisplayRole ).toString() );
- QCOMPARE( a3,
- model->data( i3, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
- QVERIFY( model->rowCount( i3 ) == 0 );
- QVERIFY( model->data( i3, FreeBusyItemModel::FreeBusyRole ).isValid() == false );
-
- model->slotInsertFreeBusy( fb2, "joe at example.com" );
- QCOMPARE( item2->freeBusy(),
- model->data( i2, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
- QVERIFY( model->rowCount( i2 ) == fb2->fullBusyPeriods().size() );
-
- QModelIndex i2_0 = model->index( 0, 0, i2 );
- QCOMPARE( fb2->fullBusyPeriods().first(),
- model->data(
- i2_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- QModelIndex i2_1 = model->index( 1, 0, i2 );
- QCOMPARE( fb2->fullBusyPeriods().at( 1 ),
- model->data(
- i2_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- QModelIndex i2_2 = model->index( 2, 0, i2 );
- QCOMPARE( fb2->fullBusyPeriods().last(),
- model->data(
- i2_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
-
- model->slotInsertFreeBusy( fb3, "max at example.com" );
- QCOMPARE( item3->freeBusy(),
- model->data( i3, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
- QVERIFY( model->rowCount( i3 ) == fb3->fullBusyPeriods().size() );
-
- QModelIndex i3_0 = model->index( 0, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().first(),
- model->data(
- i3_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- QModelIndex i3_1 = model->index( 1, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().at( 1 ),
- model->data(
- i3_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- QModelIndex i3_2 = model->index( 2, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().last(),
- model->data(
- i3_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
-
- model->removeAttendee( a2 );
-
- QCOMPARE( 2, model->rowCount() );
-
- QVERIFY( model->containsAttendee( a1 ) == true );
- QVERIFY( model->containsAttendee( a2 ) == false );
- QVERIFY( model->containsAttendee( a3 ) == true );
-
- i3_0 = model->index( 0, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().first(),
- model->data(
- i3_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- i3_1 = model->index( 1, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().at( 1 ),
- model->data(
- i3_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
- i3_2 = model->index( 2, 0, i3 );
- QCOMPARE( fb3->fullBusyPeriods().last(),
- model->data(
- i3_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
-}
-
-void FreeBusyItemModelTest::testInsertFreeBusy()
-{
- FreeBusyItemModel * model = new FreeBusyItemModel( this );
- new ModelTest( model, this );
-
- const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
- const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
- KCalCore::Attendee::Ptr a1( new KCalCore::Attendee( "fred", "fred at example.com" ) );
- KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
- fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
-
- const KDateTime dt3( QDate( 2010, 7, 24 ), QTime( 12, 0, 0 ), KDateTime::UTC );
- const KDateTime dt4( QDate( 2010, 7, 24 ), QTime( 14, 0, 0 ), KDateTime::UTC );
- KCalCore::FreeBusy::Ptr fb2( new KCalCore::FreeBusy() );
- fb2->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
- fb2->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
- fb2->addPeriod( dt3, KCalCore::Duration( 60 * 60 ) );
- fb2->addPeriod( dt4, KCalCore::Duration( 60 * 60 * 2 ) );
-
- FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
- item1->setFreeBusy( fb1 );
-
- model->addItem( item1 );
-
- QModelIndex i = model->index( 0, 0 );
- QCOMPARE( model->rowCount( i ), 2 );
-
- model->slotInsertFreeBusy( fb2, "fred at example.com" );
-
- QCOMPARE( model->rowCount( i ), 4 );
-}
-
diff --git a/incidenceeditor-ng/tests/testfreebusyitemmodel.h b/incidenceeditor-ng/tests/testfreebusyitemmodel.h
deleted file mode 100644
index 2a16694..0000000
--- a/incidenceeditor-ng/tests/testfreebusyitemmodel.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-#ifndef TESTFREEBUSYITEMMODEL_H
-#define TESTFREEBUSYITEMMODEL_H
-
-#include <QObject>
-
-class FreeBusyItemModelTest: public QObject
-{
- Q_OBJECT
- private Q_SLOTS:
- void testModelValidity();
- void testModelValidity2();
- void testInsertFreeBusy();
-};
-#endif
diff --git a/incidenceeditor-ng/tests/testfreeperiodmodel.cpp b/incidenceeditor-ng/tests/testfreeperiodmodel.cpp
deleted file mode 100644
index f9096cc..0000000
--- a/incidenceeditor-ng/tests/testfreeperiodmodel.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-
-#include "testfreeperiodmodel.h"
-#include "modeltest.h"
-#include "../freeperiodmodel.h"
-
-#include <KCalCore/Period>
-#include <KCalCore/Duration>
-
-#include <KDebug>
-
-#include <qtest_kde.h>
-
-QTEST_KDEMAIN( FreePeriodModelTest, NoGUI )
-using namespace IncidenceEditorNG;
-
-void FreePeriodModelTest::testModelValidity()
-{
- FreePeriodModel * model = new FreePeriodModel( this );
- new ModelTest( model, this );
-
- const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
- const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
-
- KCalCore::Period::List list;
-
- list << KCalCore::Period( dt1, KCalCore::Duration( 60 * 60 ) );
- list << KCalCore::Period( dt2, KCalCore::Duration( 60 * 60 ) );
-
- QVERIFY( model->rowCount() == 0 );
- model->slotNewFreePeriods( list );
- QCOMPARE( model->rowCount(), 2 );
-}
-
-void FreePeriodModelTest::testSplitByDay()
-{
- FreePeriodModel * model = new FreePeriodModel( this );
- new ModelTest( model, this );
-
- const KDateTime startDt( QDate( 2010, 7, 24 ), QTime( 8, 0, 0 ), KDateTime::UTC );
- const KDateTime endDt( QDate( 2010, 7, 25 ), QTime( 8, 0, 0 ), KDateTime::UTC );
-
- KCalCore::Period::List list;
-
- // This period goes from 8am on the 24th to 8am on the 25th
- list << KCalCore::Period( startDt, endDt );
-
- QVERIFY( model->rowCount() == 0 );
-
- // as part of adding the new periods
- // the model should split the above period into two
- // one from 8am-12 on the 24th, and the second from 00-08 on the 25th
- model->slotNewFreePeriods( list );
-
- const KDateTime endPeriod1( QDate( 2010, 7, 24 ), QTime( 23, 59, 59, 999 ), KDateTime::UTC );
- const KDateTime startPeriod2( QDate( 2010, 7, 25 ), QTime( 0, 0, 0, 0 ), KDateTime::UTC );
-
- QModelIndex index = model->index( 0, 0 );
- KCalCore::Period period1 =
- model->data( index, FreePeriodModel::PeriodRole ).value<KCalCore::Period>();
- index = model->index( 1, 0 );
- KCalCore::Period period2 =
- model->data( index, FreePeriodModel::PeriodRole ).value<KCalCore::Period>();
-
- QCOMPARE( period1.start(), startDt );
- QCOMPARE( period1.end(), endPeriod1 );
- QCOMPARE( period2.start(), startPeriod2 );
- QCOMPARE( period2.end(), endDt );
-}
-
diff --git a/incidenceeditor-ng/tests/testfreeperiodmodel.h b/incidenceeditor-ng/tests/testfreeperiodmodel.h
deleted file mode 100644
index 7d60b62..0000000
--- a/incidenceeditor-ng/tests/testfreeperiodmodel.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
- Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
-
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
-
- This library 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 Library General Public
- License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-*/
-#ifndef TESTFREEPERIODMODEL_H
-#define TESTFREEPERIODMODEL_H
-
-#include <QObject>
-
-class FreePeriodModelTest: public QObject
-{
- Q_OBJECT
- private Q_SLOTS:
- void testModelValidity();
- void testSplitByDay();
-};
-#endif
diff --git a/incidenceeditor-ng/visualfreebusywidget.cpp b/incidenceeditor-ng/visualfreebusywidget.cpp
index 4166f1e..f73c190 100644
--- a/incidenceeditor-ng/visualfreebusywidget.cpp
+++ b/incidenceeditor-ng/visualfreebusywidget.cpp
@@ -20,7 +20,7 @@
#include "visualfreebusywidget.h"
#include "freebusyganttproxymodel.h"
-#include "freebusyitemmodel.h"
+#include "freebusymodel/freebusyitemmodel.h"
#include <kdgantt2/kdganttgraphicsview.h>
#include <kdgantt2/kdganttview.h>
diff --git a/incidenceeditor-ng/visualfreebusywidget.h b/incidenceeditor-ng/visualfreebusywidget.h
index 223c378..265ddfe 100644
--- a/incidenceeditor-ng/visualfreebusywidget.h
+++ b/incidenceeditor-ng/visualfreebusywidget.h
@@ -36,9 +36,10 @@ class KComboBox;
class QTreeView;
+class FreeBusyItemModel;
+
namespace IncidenceEditorNG {
-class FreeBusyItemModel;
class FreeBusyGanttProxyModel;
class RowController;
diff --git a/libkdepim/CMakeLists.txt b/libkdepim/CMakeLists.txt
index a603408..448fdd5 100644
--- a/libkdepim/CMakeLists.txt
+++ b/libkdepim/CMakeLists.txt
@@ -6,8 +6,8 @@ add_definitions(-DKDE_DEFAULT_DEBUG_AREA=5300)
add_definitions( -DQT_NO_CAST_FROM_ASCII )
add_definitions( -DQT_NO_CAST_TO_ASCII )
-
add_subdirectory(tests)
+add_subdirectory(freebusymodel/tests)
add_subdirectory(pics)
add_definitions(${QT_QTDBUS_DEFINITIONS})
@@ -64,6 +64,10 @@ set(kdepim_LIB_SRCS
widgets/pimmessagebox.cpp
widgets/overlaywidget.cpp
widgets/tagwidgets.cpp
+ freebusymodel/freeperiodmodel.cpp
+ freebusymodel/freebusyitem.cpp
+ freebusymodel/freebusyitemmodel.cpp
+ freebusymodel/freebusycalendar.cpp
)
if (KDEPIM_INPROCESS_LDAP)
@@ -88,6 +92,7 @@ target_link_libraries(kdepim
${KDEPIMLIBS_KMIME_LIBS}
${KDEPIMLIBS_AKONADI_LIBS}
${KDEPIMLIBS_AKONADI_CONTACT_LIBS}
+ ${KDEPIMLIBS_AKONADI_CALENDAR_LIBS}
${BALOO_LIBRARIES}
)
@@ -101,6 +106,7 @@ target_link_libraries(kdepim LINK_INTERFACE_LIBRARIES
${KDEPIMLIBS_KPIMTEXTEDIT_LIBS}
${KDEPIMLIBS_AKONADI_LIBS}
${KDEPIMLIBS_AKONADI_CONTACT_LIBS}
+ ${KDEPIMLIBS_AKONADI_CALENDAR_LIBS}
)
if(MINGW)
diff --git a/libkdepim/freebusymodel/freebusycalendar.cpp b/libkdepim/freebusymodel/freebusycalendar.cpp
new file mode 100644
index 0000000..953a46f
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusycalendar.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright 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) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freebusycalendar.h"
+
+#include <KCalCore/Event>
+#include <KCalCore/FreeBusyPeriod>
+#include <KCalCore/MemoryCalendar>
+#include <kcalcore/calformat.h>
+
+#include <QStringList>
+#include <klocalizedstring.h>
+#include <KSystemTimeZones>
+
+#include <KDebug>
+
+FreeBusyCalendar::FreeBusyCalendar(QObject *parent)
+: QObject(parent)
+, mModel(0)
+{
+ mCalendar = KCalCore::Calendar::Ptr(new KCalCore::MemoryCalendar(KSystemTimeZones::local()));
+ kDebug() << "creating" << this;
+}
+
+FreeBusyCalendar::~FreeBusyCalendar()
+{
+ kDebug() << "deleting" << this;
+}
+
+
+KCalCore::Calendar::Ptr FreeBusyCalendar::calendar() const
+{
+ return mCalendar;
+}
+
+FreeBusyItemModel *FreeBusyCalendar::model() const
+{
+ return mModel;
+}
+
+void FreeBusyCalendar::setModel(FreeBusyItemModel *model)
+{
+ if (model != mModel) {
+ if (mModel) {
+ disconnect(mModel, 0, 0, 0);
+ }
+ mModel = model;
+ connect(mModel, SIGNAL(layoutChanged()), SLOT(onLayoutChanged()));
+ connect(mModel, SIGNAL(modelReset()), SLOT(onLayoutChanged()));
+ connect(mModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
+ SLOT(onRowsRemoved(QModelIndex,int,int)));
+ connect(mModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+ SLOT(onRowsInserted(QModelIndex,int,int)));
+ connect(mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ SLOT(onRowsChanged(QModelIndex,QModelIndex)));
+ }
+}
+
+void FreeBusyCalendar::onLayoutChanged()
+{
+ if (mFbEvent.count() > 0) {
+ mCalendar->deleteAllEvents();
+ mFbEvent.clear();
+ for (int i = mModel->rowCount()-1; i>=0; i--) {
+ QModelIndex parent = mModel->index(i, 0);
+ onRowsInserted(parent, 0, mModel->rowCount(parent)-1);
+ }
+ }
+}
+
+void FreeBusyCalendar::onRowsInserted(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() + QLatin1String("-") + QString::number(i));
+
+ inc->setCustomProperty("FREEBUSY", "STATUS", QString::number(period.type()));
+ QString summary = period.summary();
+ if (summary.isEmpty()) {
+ switch (period.type()) {
+ case KCalCore::FreeBusyPeriod::Free:
+ summary = i18n("Free");
+ break;
+ case KCalCore::FreeBusyPeriod::Busy:
+ summary = i18n("Busy");
+ break;
+ case KCalCore::FreeBusyPeriod::BusyUnavailable:
+ summary = i18n("Unavailable");
+ break;
+ case KCalCore::FreeBusyPeriod::BusyTentative:
+ summary = i18n("Tentative");
+ break;
+ default:
+ summary = i18n("Unknown");
+ }
+ }
+ inc->setSummary(summary);
+
+ mFbEvent.insert(index, inc);
+ mCalendar->addEvent(inc);
+ }
+}
+
+void FreeBusyCalendar::onRowsRemoved(const QModelIndex &parent, int first, int last)
+{
+ if (!parent.isValid()) {
+ for (int i = first; i<=last; i--) {
+ QModelIndex index = mModel->index(i, 0);
+ onRowsRemoved(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);
+ mCalendar->deleteEvent(inc);
+ }
+ }
+}
+
+void FreeBusyCalendar::onRowsChanged(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);
+ mCalendar->beginChange(inc);
+ mCalendar->endChange(inc);
+ }
+}
\ No newline at end of file
diff --git a/libkdepim/freebusymodel/freebusycalendar.h b/libkdepim/freebusymodel/freebusycalendar.h
new file mode 100644
index 0000000..ac2e6f6
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusycalendar.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 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) version 3 or any later version
+ * accepted by the membership of KDE e.V. (or its successor approved
+ * by the membership of KDE e.V.), which shall act as a proxy
+ * defined in Section 14 of version 3 of the license.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FBMODEL_FBCALENDAR_H
+#define FBMODEL_FBCALENDAR_H
+
+#include "libkdepim/kdepim_export.h"
+
+#include "freebusyitemmodel.h"
+
+#include <KCalCore/Calendar>
+#include <KCalCore/Event>
+
+class KDEPIM_EXPORT FreeBusyCalendar : QObject {
+ Q_OBJECT
+public:
+ explicit FreeBusyCalendar(QObject *parent = 0);
+
+ virtual ~FreeBusyCalendar();
+
+ void setModel(FreeBusyItemModel *model);
+ FreeBusyItemModel *model() const;
+ KCalCore::Calendar::Ptr calendar() const;
+
+private slots:
+ void onRowsChanged(const QModelIndex &, const QModelIndex &);
+ void onRowsInserted(const QModelIndex &,int,int);
+ void onRowsRemoved(const QModelIndex &,int,int);
+ void onLayoutChanged();
+
+private:
+ FreeBusyItemModel *mModel;
+ KCalCore::Calendar::Ptr mCalendar;
+ QMap<QModelIndex,KCalCore::Event::Ptr> mFbEvent;
+};
+
+#endif // FBMODEL_FBCALENDAR_H
diff --git a/libkdepim/freebusymodel/freebusyitem.cpp b/libkdepim/freebusymodel/freebusyitem.cpp
new file mode 100644
index 0000000..ac4468f
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusyitem.cpp
@@ -0,0 +1,82 @@
+/*
+ Copyright (c) 2000,2001,2004 Cornelius Schumacher <schumacher at kde.org>
+ Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info at kdab.com
+ Copyright (c) 2010 Andras Mantia <andras at kdab.com>
+ Copyright (C) 2010 Casey Link <casey at kdab.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "freebusyitem.h"
+
+#include <akonadi/calendar/freebusymanager.h>
+
+FreeBusyItem::FreeBusyItem( const KCalCore::Attendee::Ptr &attendee, QWidget *parentWidget )
+ : mAttendee( attendee ), mTimerID( 0 ), mIsDownloading( false ), mParentWidget( parentWidget )
+{
+ Q_ASSERT( attendee );
+ setFreeBusy( KCalCore::FreeBusy::Ptr() );
+}
+
+KCalCore::Attendee::Ptr FreeBusyItem::attendee() const
+{
+ return mAttendee;
+}
+
+void FreeBusyItem::setFreeBusy( const KCalCore::FreeBusy::Ptr &fb )
+{
+ mFreeBusy = fb;
+ mIsDownloading = false;
+}
+
+KCalCore::FreeBusy::Ptr FreeBusyItem::freeBusy() const
+{
+ return mFreeBusy;
+}
+
+QString FreeBusyItem::email() const
+{
+ return mAttendee->email();
+}
+
+void FreeBusyItem::setUpdateTimerID( int id )
+{
+ mTimerID = id;
+}
+
+int FreeBusyItem::updateTimerID() const
+{
+ return mTimerID;
+}
+
+void FreeBusyItem::startDownload( bool forceDownload )
+{
+ mIsDownloading = true;
+ Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
+ if ( !m->retrieveFreeBusy( attendee()->email(), forceDownload, mParentWidget ) ) {
+ mIsDownloading = false;
+ }
+}
+
+void FreeBusyItem::setIsDownloading( bool d )
+{
+ mIsDownloading = d;
+}
+
+bool FreeBusyItem::isDownloading() const
+{
+ return mIsDownloading;
+}
diff --git a/libkdepim/freebusymodel/freebusyitem.h b/libkdepim/freebusymodel/freebusyitem.h
new file mode 100644
index 0000000..ef7d007
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusyitem.h
@@ -0,0 +1,73 @@
+/*
+ Copyright (c) 2000,2001,2004 Cornelius Schumacher <schumacher at kde.org>
+ Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info at kdab.com
+ Copyright (c) 2010 Andras Mantia <andras at kdab.com>
+ Copyright (C) 2010 Casey Link <casey at kdab.com>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef INCIDENCEEDITOR_FREEBUSYITEM_H
+#define INCIDENCEEDITOR_FREEBUSYITEM_H
+
+#include "libkdepim/kdepim_export.h"
+
+#include <KCalCore/FreeBusy>
+
+/**
+ * The FreeBusyItem is the whole line for a given attendee..
+ */
+class KDEPIM_EXPORT FreeBusyItem
+{
+ public:
+ typedef QSharedPointer<FreeBusyItem> Ptr;
+
+ /**
+ * @param parentWidget is passed to Akonadi when fetching free/busy data.
+ */
+ FreeBusyItem( const KCalCore::Attendee::Ptr &attendee, QWidget *parentWidget );
+ ~FreeBusyItem() {}
+
+ KCalCore::Attendee::Ptr attendee() const;
+ void setFreeBusy( const KCalCore::FreeBusy::Ptr &fb );
+ KCalCore::FreeBusy::Ptr freeBusy() const;
+
+ QString email() const;
+ void setUpdateTimerID( int id );
+ int updateTimerID() const;
+
+ void startDownload( bool forceDownload );
+ void setIsDownloading( bool d );
+ bool isDownloading() const;
+
+ signals:
+ void attendeeChanged( const KCalCore::Attendee::Ptr &attendee );
+ void freebusyChanged( const KCalCore::FreeBusy::Ptr fb );
+
+ private:
+ KCalCore::Attendee::Ptr mAttendee;
+ KCalCore::FreeBusy::Ptr mFreeBusy;
+
+ // This is used for the update timer
+ int mTimerID;
+
+ // Only run one download job at a time
+ bool mIsDownloading;
+
+ QWidget *mParentWidget;
+};
+
+#endif
diff --git a/libkdepim/freebusymodel/freebusyitemmodel.cpp b/libkdepim/freebusymodel/freebusyitemmodel.cpp
new file mode 100644
index 0000000..1415d60
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusyitemmodel.cpp
@@ -0,0 +1,419 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "freebusyitemmodel.h"
+
+#include <akonadi/calendar/freebusymanager.h>
+
+#include <KGlobal>
+#include <KLocalizedString>
+#include <KLocale>
+
+#include <QTimerEvent>
+
+class ItemPrivateData
+{
+ public:
+ ItemPrivateData( ItemPrivateData *parent ) : parentItem( parent )
+ {
+ }
+
+ ~ItemPrivateData()
+ {
+ qDeleteAll( childItems );
+ }
+
+ ItemPrivateData *child( int row )
+ {
+ return childItems.value( row );
+ }
+
+ void appendChild( ItemPrivateData *item )
+ {
+ childItems.append(item);
+ }
+
+ ItemPrivateData *removeChild( int row )
+ {
+ return childItems.takeAt( row );
+ }
+
+ int childCount() const
+ {
+ return childItems.count();
+ }
+
+ int row() const
+ {
+ if ( parentItem ) {
+ return parentItem->childItems.indexOf( const_cast<ItemPrivateData*>(this) );
+ }
+ return 0;
+ }
+
+ ItemPrivateData *parent()
+ {
+ return parentItem;
+ }
+
+ private:
+ QList<ItemPrivateData*> childItems;
+ ItemPrivateData *parentItem;
+};
+
+FreeBusyItemModel::FreeBusyItemModel( QObject *parent )
+ : QAbstractItemModel( parent ), mForceDownload( false )
+{
+ qRegisterMetaType<KCalCore::Attendee::Ptr>( "KCalCore::Attendee::Ptr" );
+ qRegisterMetaType<KCalCore::FreeBusy::Ptr>( "KCalCore::FreeBusy::Ptr" );
+ qRegisterMetaType<KCalCore::Period>( "KCalCore::Period" );
+
+ Akonadi::FreeBusyManager *m = Akonadi::FreeBusyManager::self();
+ connect( m, SIGNAL(freeBusyRetrieved(KCalCore::FreeBusy::Ptr,QString)),
+ SLOT(slotInsertFreeBusy(KCalCore::FreeBusy::Ptr,QString)) );
+
+ connect( &mReloadTimer, SIGNAL(timeout()), SLOT(autoReload()) );
+ mReloadTimer.setSingleShot( true );
+
+ mRootData = new ItemPrivateData( 0 );
+}
+
+FreeBusyItemModel::~FreeBusyItemModel()
+{
+ delete mRootData;
+}
+
+QVariant FreeBusyItemModel::data( const QModelIndex &index, int role ) const
+{
+ if ( !index.isValid() ) {
+ return QVariant();
+ }
+
+ ItemPrivateData *data = (ItemPrivateData*) index.internalPointer();
+
+ if ( data->parent() == mRootData ) {
+ int row = index.row();
+ if ( row >= mFreeBusyItems.size() ) {
+ return QVariant();
+ }
+
+ switch( role ) {
+ case Qt::DisplayRole:
+ return mFreeBusyItems.at( row )->attendee()->fullName();
+ case FreeBusyItemModel::AttendeeRole:
+ return QVariant::fromValue( mFreeBusyItems.at( row )->attendee() );
+ case FreeBusyItemModel::FreeBusyRole:
+ if ( mFreeBusyItems.at( row )->freeBusy() ) {
+ return QVariant::fromValue( mFreeBusyItems.at( row )->freeBusy() );
+ } else {
+ return QVariant();
+ }
+ default:
+ return QVariant();
+ }
+ }
+
+ FreeBusyItem::Ptr fbitem = mFreeBusyItems.at( data->parent()->row() );
+ if ( !fbitem->freeBusy() || index.row() >= fbitem->freeBusy()->busyPeriods().size() ) {
+ return QVariant();
+ }
+
+ KCalCore::FreeBusyPeriod period = fbitem->freeBusy()->fullBusyPeriods().at( index.row() );
+ switch( role ) {
+ case Qt::DisplayRole: // return something to make modeltest happy
+ return QString(QLatin1String( "%1 - %2" )).
+ arg( KGlobal::locale()->formatDateTime( period.start() ) ).
+ arg( KGlobal::locale()->formatDateTime( period.end() ) );
+ case FreeBusyItemModel::FreeBusyPeriodRole:
+ return QVariant::fromValue( period );
+ default:
+ return QVariant();
+ }
+}
+
+int FreeBusyItemModel::rowCount( const QModelIndex &parent ) const
+{
+ ItemPrivateData *parentData;
+ if ( parent.column() > 0 ) {
+ return 0;
+ }
+
+ if ( !parent.isValid() ) {
+ parentData = mRootData;
+ } else {
+ parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
+ }
+
+ return parentData->childCount();
+}
+
+int FreeBusyItemModel::columnCount( const QModelIndex &parent ) const
+{
+ Q_UNUSED( parent );
+ return 1;
+}
+
+QModelIndex FreeBusyItemModel::index( int row, int column, const QModelIndex &parent ) const
+{
+ if ( !hasIndex( row, column, parent ) ) {
+ return QModelIndex();
+ }
+
+ ItemPrivateData *parentData;
+ if ( !parent.isValid() ) {
+ parentData = mRootData;
+ } else {
+ parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
+ }
+
+ ItemPrivateData *childData = parentData->child( row );
+ if ( childData ) {
+ return createIndex( row, column, childData );
+ } else {
+ return QModelIndex();
+ }
+// FreeBusyItem::Ptr item = mFreeBusyItems.at( parent.row() );
+// KCalCore::FreeBusy::Ptr fb = item->freeBusy();
+// if( !fb )
+// return QModelIndex();
+//
+// QList<KCalCore::FreeBusyPeriod> busyPeriods = fb->fullBusyPeriods();
+// if( row < busyPeriods.size() )
+// return createIndex( row, column, new ItemPrivateData( parent.row() ) );
+// else
+// return QModelIndex();
+// }
+}
+
+QModelIndex FreeBusyItemModel::parent( const QModelIndex &child ) const
+{
+ if ( !child.isValid() ) {
+ return QModelIndex();
+ }
+
+ ItemPrivateData *childData = static_cast<ItemPrivateData*>( child.internalPointer() );
+ ItemPrivateData *parentData = childData->parent();
+ if ( parentData == mRootData ) {
+ return QModelIndex();
+ }
+
+ return createIndex( parentData->row(), 0, parentData );
+}
+
+QVariant FreeBusyItemModel::headerData( int section, Qt::Orientation orientation, int role ) const
+{
+ if ( role == Qt::DisplayRole && orientation == Qt::Horizontal && section == 0 ) {
+ return i18n( "Attendee" );
+ }
+ return QVariant();
+}
+
+void FreeBusyItemModel::addItem( const FreeBusyItem::Ptr &freebusy )
+{
+ int row = mFreeBusyItems.size();
+ beginInsertRows( QModelIndex(), row, row );
+ mFreeBusyItems.append( freebusy );
+ ItemPrivateData *data = new ItemPrivateData( mRootData );
+ mRootData->appendChild( data );
+ endInsertRows();
+
+ if ( freebusy->freeBusy() && freebusy->freeBusy()->fullBusyPeriods().size() > 0 ) {
+ QModelIndex parent = index( row, 0 );
+ setFreeBusyPeriods( parent, freebusy->freeBusy()->fullBusyPeriods() );
+ }
+ updateFreeBusyData( freebusy );
+}
+
+void FreeBusyItemModel::setFreeBusyPeriods( const QModelIndex &parent,
+ const KCalCore::FreeBusyPeriod::List &list )
+{
+ if(!parent.isValid())
+ return;
+
+ ItemPrivateData *parentData = static_cast<ItemPrivateData*>( parent.internalPointer() );
+ int fb_count = list.size();
+ int childCount = parentData->childCount();
+ QModelIndex first = index( 0, 0, parent );
+ QModelIndex last = index( childCount-1, 0, parent );
+
+ if ( childCount > 0 && fb_count < childCount ) {
+ beginRemoveRows( parent, fb_count-1<0 ? 0 : fb_count-1 , childCount - 1 );
+ for ( int i = childCount - 1; i > fb_count; --i ) {
+ delete parentData->removeChild( i );
+ }
+ endRemoveRows();
+ if (fb_count > 0) {
+ last = index(fb_count-1, 0, parent);
+ emit dataChanged(first, last);
+ }
+ } else if (fb_count > childCount) {
+ beginInsertRows( parent, childCount, fb_count - 1 );
+ for ( int i=childCount; i < fb_count; ++i ) {
+ ItemPrivateData *childData= new ItemPrivateData( parentData );
+ parentData->appendChild( childData );
+ }
+ endInsertRows();
+ if (childCount > 0) {
+ last = index(childCount-1, 0, parent);
+ emit dataChanged(first, last);
+ }
+ } else if (fb_count == childCount && fb_count > 0) {
+ emit dataChanged( first, last );
+ }
+}
+
+void FreeBusyItemModel::clear()
+{
+ beginResetModel();
+ mFreeBusyItems.clear();
+ delete mRootData;
+ mRootData = new ItemPrivateData( 0 );
+ endResetModel();
+}
+
+void FreeBusyItemModel::removeRow( int row )
+{
+ beginRemoveRows( QModelIndex(), row, row );
+ mFreeBusyItems.removeAt( row );
+ ItemPrivateData *data = mRootData->removeChild( row );
+ delete data;
+ endRemoveRows();
+}
+
+void FreeBusyItemModel::removeItem( const FreeBusyItem::Ptr &freebusy )
+{
+ int row = mFreeBusyItems.indexOf( freebusy );
+ if( row >= 0 ) {
+ removeRow( row );
+ }
+}
+
+void FreeBusyItemModel::removeAttendee( const KCalCore::Attendee::Ptr &attendee )
+{
+ FreeBusyItem::Ptr anItem;
+ for ( int i = 0; i < mFreeBusyItems.count(); ++i ) {
+ anItem = mFreeBusyItems[i];
+ if ( *anItem->attendee() == *attendee ) {
+ if ( anItem->updateTimerID() != 0 ) {
+ killTimer( anItem->updateTimerID() );
+ }
+ removeRow( i );
+ break;
+ }
+ }
+}
+
+bool FreeBusyItemModel::containsAttendee( const KCalCore::Attendee::Ptr &attendee )
+{
+ FreeBusyItem::Ptr anItem;
+ for ( int i = 0; i < mFreeBusyItems.count(); ++i ) {
+ anItem = mFreeBusyItems[i];
+ if ( *anItem->attendee() == *attendee ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void FreeBusyItemModel::updateFreeBusyData( const FreeBusyItem::Ptr &item )
+{
+ if ( item->isDownloading() ) {
+ // This item is already in the process of fetching the FB list
+ return;
+ }
+
+ if ( item->updateTimerID() != 0 ) {
+ // An update timer is already running. Reset it
+ killTimer( item->updateTimerID() );
+ }
+
+ // This item does not have a download running, and no timer is set
+ // Do the download in one second
+ item->setUpdateTimerID( startTimer( 1000 ) );
+}
+
+void FreeBusyItemModel::timerEvent( QTimerEvent *event )
+{
+ killTimer( event->timerId() );
+ Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
+ if ( item->updateTimerID() == event->timerId() ) {
+ item->setUpdateTimerID( 0 );
+ item->startDownload( mForceDownload );
+ return;
+ }
+ }
+}
+
+void FreeBusyItemModel::slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb,
+ const QString &email )
+{
+ if ( !fb ) {
+ return;
+ }
+
+ if ( fb->fullBusyPeriods().isEmpty() ) {
+ return;
+ }
+
+ fb->sortList();
+
+ Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
+ if ( item->email() == email ) {
+ item->setFreeBusy( fb );
+ const int row = mFreeBusyItems.indexOf( item );
+ const QModelIndex parent = index( row, 0 );
+ emit dataChanged(parent, parent);
+ setFreeBusyPeriods( parent, fb->fullBusyPeriods() );
+ }
+ }
+}
+
+void FreeBusyItemModel::autoReload()
+{
+ mForceDownload = false;
+ reload();
+}
+
+void FreeBusyItemModel::reload()
+{
+ Q_FOREACH ( FreeBusyItem::Ptr item, mFreeBusyItems ) {
+ if ( mForceDownload ) {
+ item->startDownload( mForceDownload );
+ } else {
+ updateFreeBusyData( item );
+ }
+ }
+}
+
+void FreeBusyItemModel::triggerReload()
+{
+ mReloadTimer.start( 1000 );
+}
+
+void FreeBusyItemModel::cancelReload()
+{
+ mReloadTimer.stop();
+}
+
+void FreeBusyItemModel::manualReload()
+{
+ mForceDownload = true;
+ reload();
+}
diff --git a/libkdepim/freebusymodel/freebusyitemmodel.h b/libkdepim/freebusymodel/freebusyitemmodel.h
new file mode 100644
index 0000000..31636d5
--- /dev/null
+++ b/libkdepim/freebusymodel/freebusyitemmodel.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef FBMODEL_FREEBUSYITEMMODEL_H
+#define FBMODEL_FREEBUSYITEMMODEL_H
+
+#include "libkdepim/kdepim_export.h"
+
+#include "freebusyitem.h"
+
+#include <QAbstractItemModel>
+#include <QTimer>
+
+class ItemPrivateData;
+
+/**
+ * The FreeBusyItemModel is a 2-level tree structure.
+ *
+ * The top level parent nodes represent the freebusy items, and
+ * the 2nd-level child nodes represent the FreeBusyPeriods of the parent
+ * freebusy item.
+ */
+class KDEPIM_EXPORT FreeBusyItemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ public:
+ enum Roles {
+ AttendeeRole = Qt::UserRole,
+ FreeBusyRole,
+ FreeBusyPeriodRole
+ };
+
+ explicit FreeBusyItemModel( QObject *parent = 0 );
+ virtual ~FreeBusyItemModel();
+
+ virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
+ virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
+ virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
+ virtual QModelIndex index( int row, int column = 0,
+ const QModelIndex &parent = QModelIndex() ) const;
+ virtual QModelIndex parent( const QModelIndex &child ) const;
+ virtual QVariant headerData( int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole ) const;
+
+ void addItem( const FreeBusyItem::Ptr &freebusy );
+
+ void clear();
+ void removeAttendee( const KCalCore::Attendee::Ptr &attendee );
+ void removeItem( const FreeBusyItem::Ptr &freebusy );
+ void removeRow( int row );
+
+ bool containsAttendee( const KCalCore::Attendee::Ptr &attendee );
+
+ /**
+ * Queues a reload of free/busy data.
+ * All current attendees will have their free/busy data
+ * redownloaded from Akonadi.
+ */
+ void triggerReload();
+
+ /**
+ * cancel reloading
+ */
+ void cancelReload();
+
+ /**
+ * Reload FB items
+ */
+ void reload();
+
+ public slots:
+ void slotInsertFreeBusy( const KCalCore::FreeBusy::Ptr &fb, const QString &email );
+
+ protected:
+ void timerEvent( QTimerEvent * );
+
+ private slots:
+ // Force the download of FB information
+ void manualReload();
+ // Only download FB if the auto-download option is set in config
+ void autoReload();
+
+ private:
+ void setFreeBusyPeriods( const QModelIndex &parent,
+ const KCalCore::FreeBusyPeriod::List &list );
+ void updateFreeBusyData( const FreeBusyItem::Ptr & );
+
+ QTimer mReloadTimer;
+ bool mForceDownload;
+ QList<FreeBusyItem::Ptr> mFreeBusyItems;
+ ItemPrivateData *mRootData;
+};
+
+#endif
diff --git a/libkdepim/freebusymodel/freeperiodmodel.cpp b/libkdepim/freebusymodel/freeperiodmodel.cpp
new file mode 100644
index 0000000..e928e85
--- /dev/null
+++ b/libkdepim/freebusymodel/freeperiodmodel.cpp
@@ -0,0 +1,206 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "freeperiodmodel.h"
+
+#include <KCalCore/Period>
+
+#include <KCalendarSystem>
+#include <KGlobal>
+#include <KSystemTimeZones>
+
+#include <QSet>
+
+FreePeriodModel::FreePeriodModel( QObject *parent ): QAbstractTableModel( parent )
+{
+}
+
+FreePeriodModel::~FreePeriodModel()
+{
+}
+
+QVariant FreePeriodModel::data( const QModelIndex &index, int role ) const
+{
+ if ( !index.isValid() || !hasIndex( index.row(), index.column() ) ) {
+ return QVariant();
+ }
+
+ if( index.column() == 0 ) { //day
+ switch( role ) {
+ case Qt::DisplayRole:
+ return day( index.row() );
+ case Qt::ToolTipRole:
+ return tooltipify( index.row() );
+ case FreePeriodModel::PeriodRole:
+ return QVariant::fromValue( mPeriodList.at( index.row() ) );
+ case Qt::TextAlignmentRole:
+ return static_cast<int>( Qt::AlignRight | Qt::AlignVCenter );
+ default:
+ return QVariant();
+ }
+ } else { // everything else
+ switch( role ) {
+ case Qt::DisplayRole:
+ return date( index.row() );
+ case Qt::ToolTipRole:
+ return tooltipify( index.row() );
+ case FreePeriodModel::PeriodRole:
+ return QVariant::fromValue( mPeriodList.at( index.row() ) );
+ case Qt::TextAlignmentRole:
+ return static_cast<int>( Qt::AlignLeft | Qt::AlignVCenter );
+ default:
+ return QVariant();
+ }
+ }
+}
+
+int FreePeriodModel::rowCount( const QModelIndex &parent ) const
+{
+ if ( !parent.isValid() ) {
+ return mPeriodList.size();
+ }
+ return 0;
+}
+
+int FreePeriodModel::columnCount( const QModelIndex &parent ) const
+{
+ Q_UNUSED( parent );
+ return 2;
+}
+
+QVariant FreePeriodModel::headerData( int section, Qt::Orientation orientation, int role ) const
+{
+ return QAbstractItemModel::headerData( section, orientation, role );
+}
+
+void FreePeriodModel::slotNewFreePeriods( const KCalCore::Period::List &freePeriods )
+{
+ beginResetModel();
+ mPeriodList.clear();
+ mPeriodList = splitPeriodsByDay( freePeriods );
+ qSort( mPeriodList );
+ endResetModel();
+}
+
+KCalCore::Period::List FreePeriodModel::splitPeriodsByDay(
+ const KCalCore::Period::List &freePeriods )
+{
+ KCalCore::Period::List splitList;
+ foreach ( const KCalCore::Period &period, freePeriods ) {
+ if ( period.start().date() == period.end().date() ) {
+ splitList << period; // period occurs on the same day
+ continue;
+ }
+
+ const int validPeriodSecs = 5 * 60; // 5 minutes
+ KCalCore::Period tmpPeriod = period;
+ while ( tmpPeriod.start().date() != tmpPeriod.end().date() ) {
+ const KDateTime midnight( tmpPeriod.start().date(), QTime( 23, 59, 59, 999 ),
+ tmpPeriod.start().timeSpec() );
+ KCalCore::Period firstPeriod( tmpPeriod.start(), midnight );
+ KCalCore::Period secondPeriod( midnight.addMSecs( 1 ), tmpPeriod.end() );
+ if ( firstPeriod.duration().asSeconds() >= validPeriodSecs ) {
+ splitList << firstPeriod;
+ }
+ tmpPeriod = secondPeriod;
+ }
+ if ( tmpPeriod.duration().asSeconds() >= validPeriodSecs ) {
+ splitList << tmpPeriod;
+ }
+ }
+
+ // Perform some jiggery pokery to remove duplicates
+ QList<KCalCore::Period> tmpList = splitList.toList();
+ QSet<KCalCore::Period>set = tmpList.toSet();
+ tmpList = QList<KCalCore::Period>::fromSet( set );
+ return KCalCore::Period::List::fromList( tmpList );
+}
+
+QString FreePeriodModel::day( int index ) const
+{
+ KCalCore::Period period = mPeriodList.at( index );
+ const KCalendarSystem *calSys = KGlobal::locale()->calendar();
+ const QDate startDate = period.start().date();
+ return ki18nc( "@label Day of the week name, example: Monday,", "%1," ).
+ subs( calSys->weekDayName( startDate.dayOfWeek(), KCalendarSystem::LongDayName ) ).toString();
+}
+
+QString FreePeriodModel::date( int index ) const
+{
+ KCalCore::Period period = mPeriodList.at( index );
+ const KCalendarSystem *calSys = KGlobal::locale()->calendar();
+
+ const QDate startDate = period.start().date();
+ const QString startTime = KGlobal::locale()->formatTime( period.start().time() );
+ const QString endTime = KGlobal::locale()->formatTime( period.end().time() );
+ const QString longMonthName = calSys->monthName( startDate );
+ return ki18nc( "@label A time period duration. It is preceded/followed (based on the "
+ "orientation) by the name of the week, see the message above. "
+ "example: 12 June, 8:00am to 9:30am",
+ "%1 %2, %3 to %4" ).
+ subs( startDate.day() ).
+ subs( longMonthName ).
+ subs( startTime ).
+ subs( endTime ).toString();
+}
+
+QString FreePeriodModel::stringify( int index ) const
+{
+ KCalCore::Period period = mPeriodList.at( index );
+ const KCalendarSystem *calSys = KGlobal::locale()->calendar();
+
+ const QDate startDate = period.start().date();
+ const QString startTime = KGlobal::locale()->formatTime( period.start().time(), false, true );
+ const QString endTime = KGlobal::locale()->formatTime( period.end().time(), false, true );
+ const QString longMonthName = calSys->monthName( startDate );
+ const QString dayofWeek = calSys->weekDayName( startDate.dayOfWeek(),
+ KCalendarSystem::LongDayName );
+
+ // TODO i18n, ping chusslove
+ return ki18nc( "@label A time period duration. KLocale is used to format the components. "
+ "example: Monday, 12 June, 8:00am to 9:30am",
+ "%1, %2 %3, %4 to %5" ).
+ subs( dayofWeek ).
+ subs( startDate.day() ).
+ subs( longMonthName ).
+ subs( startTime ).
+ subs( endTime ).toString();
+}
+
+QString FreePeriodModel::tooltipify( int index ) const
+{
+ KDateTime::Spec timeSpec = KSystemTimeZones::local();
+ KCalCore::Period period = mPeriodList.at( index );
+ unsigned long duration = period.duration().asSeconds() * 1000; // we want milliseconds
+ QString toolTip = QLatin1String("<qt>");
+ toolTip += QLatin1String("<b>") + i18nc( "@info:tooltip", "Free Period" ) + QLatin1String("</b>");
+ toolTip += QLatin1String("<hr>");
+ toolTip += QLatin1String("<i>") + i18nc( "@info:tooltip period start time", "Start:" ) + QLatin1String("</i> ");
+ toolTip += KGlobal::locale()->formatDateTime( period.start().toTimeSpec( timeSpec ).dateTime() );
+ toolTip += QLatin1String("<br>");
+ toolTip += QLatin1String("<i>") + i18nc( "@info:tooltip period end time", "End:" ) + QLatin1String("</i> ");
+ toolTip += KGlobal::locale()->formatDateTime( period.end().toTimeSpec( timeSpec ).dateTime() );
+ toolTip += QLatin1String("<br>");
+ toolTip += QLatin1String("<i>") + i18nc( "@info:tooltip period duration", "Duration:" ) + QLatin1String("</i> ");
+ toolTip += KGlobal::locale()->prettyFormatDuration( duration );
+ toolTip += QLatin1String("</qt>");
+ return toolTip;
+}
+
diff --git a/libkdepim/freebusymodel/freeperiodmodel.h b/libkdepim/freebusymodel/freeperiodmodel.h
new file mode 100644
index 0000000..95dbf3f
--- /dev/null
+++ b/libkdepim/freebusymodel/freeperiodmodel.h
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef INCIDENCEEDITOR_FREEPERIODMODEL_H
+#define INCIDENCEEDITOR_FREEPERIODMODEL_H
+
+#include "libkdepim/kdepim_export.h"
+
+#include <KCalCore/Period>
+
+#include <QAbstractTableModel>
+
+class KDEPIM_EXPORT FreePeriodModel : public QAbstractTableModel
+{
+ Q_OBJECT
+ public:
+ enum Roles {
+ PeriodRole = Qt::UserRole
+ };
+ explicit FreePeriodModel( QObject *parent = 0 );
+ virtual ~FreePeriodModel();
+
+ virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const;
+ virtual int rowCount( const QModelIndex &parent = QModelIndex() ) const;
+ virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
+ virtual QVariant headerData( int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole ) const;
+
+ public slots:
+ void slotNewFreePeriods( const KCalCore::Period::List &freePeriods );
+
+ private:
+ /** Splits period blocks in the provided list, so that each period occurs on one day */
+ KCalCore::Period::List splitPeriodsByDay( const KCalCore::Period::List &freePeriods );
+
+ QString day( int index ) const;
+ QString date( int index ) const;
+ QString stringify( int index ) const;
+ QString tooltipify( int index ) const;
+
+ KCalCore::Period::List mPeriodList;
+ friend class FreePeriodModelTest;
+};
+
+#endif
diff --git a/libkdepim/freebusymodel/tests/CMakeLists.txt b/libkdepim/freebusymodel/tests/CMakeLists.txt
new file mode 100644
index 0000000..9bfbfce
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/CMakeLists.txt
@@ -0,0 +1,22 @@
+set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
+
+include_directories(
+ ../
+)
+
+MACRO(IE_UNIT_TESTS)
+ FOREACH(_testname ${ARGN})
+ kde4_add_unit_test(${_testname} NOGUI ${_testname}.cpp modeltest.cpp)
+ target_link_libraries(${_testname}
+ ${QT_QTTEST_LIBRARY}
+ ${KDEPIMLIBS_AKONADI_LIBS}
+ ${KDEPIMLIBS_KCALUTILS_LIBS}
+ ${KDEPIMLIBS_KCALCORE_LIBS}
+ kdepim)
+ ENDFOREACH(_testname)
+ENDMACRO(IE_UNIT_TESTS)
+
+IE_UNIT_TESTS(
+ testfreeperiodmodel
+ testfreebusyitemmodel
+)
\ No newline at end of file
diff --git a/libkdepim/freebusymodel/tests/modeltest.cpp b/libkdepim/freebusymodel/tests/modeltest.cpp
new file mode 100644
index 0000000..1227d20
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/modeltest.cpp
@@ -0,0 +1,643 @@
+/****************************************************************************
+**
+** Copyright (C) 2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Qt Concurrent project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales at trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+//krazy:excludeall=style
+
+#include "modeltest.h"
+
+#include <QtGui>
+
+Q_DECLARE_METATYPE ( QModelIndex )
+
+/*!
+ Connect to all of the models signals. Whenever anything happens recheck everything.
+*/
+ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false )
+{
+ Q_ASSERT ( model );
+
+ connect ( model, SIGNAL (columnsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (columnsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (columnsInserted(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (columnsRemoved(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (headerDataChanged(Qt::Orientation,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (layoutAboutToBeChanged()), this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (layoutChanged()), this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (modelReset()), this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (modelAboutToBeReset()), this, SLOT (modelAboutToBeReset()) );
+ connect ( model, SIGNAL (modelReset()), this, SLOT (modelReset()) );
+ connect ( model, SIGNAL (rowsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (rowsInserted(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+ connect ( model, SIGNAL (rowsRemoved(QModelIndex,int,int)),
+ this, SLOT (runAllTests()) );
+
+ // Special checks for inserting/removing
+ connect ( model, SIGNAL (layoutAboutToBeChanged()),
+ this, SLOT (layoutAboutToBeChanged()) );
+ connect ( model, SIGNAL (layoutChanged()),
+ this, SLOT (layoutChanged()) );
+
+ connect ( model, SIGNAL (rowsAboutToBeInserted(QModelIndex,int,int)),
+ this, SLOT (rowsAboutToBeInserted(QModelIndex,int,int)) );
+ connect ( model, SIGNAL (rowsAboutToBeRemoved(QModelIndex,int,int)),
+ this, SLOT (rowsAboutToBeRemoved(QModelIndex,int,int)) );
+ connect ( model, SIGNAL (rowsInserted(QModelIndex,int,int)),
+ this, SLOT (rowsInserted(QModelIndex,int,int)) );
+ connect ( model, SIGNAL (rowsRemoved(QModelIndex,int,int)),
+ this, SLOT (rowsRemoved(QModelIndex,int,int)) );
+
+ connect ( model, SIGNAL (rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
+ this, SLOT (rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) );
+ connect ( model, SIGNAL (rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+ this, SLOT (rowsMoved(QModelIndex,int,int,QModelIndex,int)) );
+
+ runAllTests();
+}
+
+void ModelTest::runAllTests()
+{
+
+// qDebug() << "rats";
+ if ( fetchingMore )
+ return;
+ nonDestructiveBasicTest();
+ rowCount();
+ columnCount();
+ hasIndex();
+ index();
+ parent();
+ data();
+}
+
+/*!
+ nonDestructiveBasicTest tries to call a number of the basic functions (not all)
+ to make sure the model doesn't outright segfault, testing the functions that makes sense.
+*/
+void ModelTest::nonDestructiveBasicTest()
+{
+ Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() );
+// model->canFetchMore ( QModelIndex() );
+ Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 );
+ Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() );
+// fetchingMore = true;
+// model->fetchMore ( QModelIndex() );
+// fetchingMore = false;
+ Qt::ItemFlags flags = model->flags ( QModelIndex() );
+ Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 );
+ Q_UNUSED( flags );
+ model->hasChildren ( QModelIndex() );
+ model->hasIndex ( 0, 0 );
+ model->headerData ( 0, Qt::Horizontal );
+ model->index ( 0, 0 );
+ model->itemData ( QModelIndex() );
+ QVariant cache;
+ model->match ( QModelIndex(), -1, cache );
+ model->mimeTypes();
+ Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
+ Q_ASSERT ( model->rowCount() >= 0 );
+ QVariant variant;
+ model->setData ( QModelIndex(), variant, -1 );
+ model->setHeaderData ( -1, Qt::Horizontal, QVariant() );
+ model->setHeaderData ( 999999, Qt::Horizontal, QVariant() );
+ QMap<int, QVariant> roles;
+ model->sibling ( 0, 0, QModelIndex() );
+ model->span ( QModelIndex() );
+ model->supportedDropActions();
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::rowCount() and hasChildren()
+
+ Models that are dynamically populated are not as fully tested here.
+ */
+void ModelTest::rowCount()
+{
+// qDebug() << "rc";
+ // check top row
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ int rows = model->rowCount ( topIndex );
+ Q_ASSERT ( rows >= 0 );
+ if ( rows > 0 )
+ Q_ASSERT ( model->hasChildren ( topIndex ) == true );
+
+ QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex );
+ if ( secondLevelIndex.isValid() ) { // not the top level
+ // check a row count where parent is valid
+ rows = model->rowCount ( secondLevelIndex );
+ Q_ASSERT ( rows >= 0 );
+ if ( rows > 0 )
+ Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true );
+ }
+
+ // The models rowCount() is tested more extensively in checkChildren(),
+ // but this catches the big mistakes
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::columnCount() and hasChildren()
+ */
+void ModelTest::columnCount()
+{
+ // check top row
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ Q_ASSERT ( model->columnCount ( topIndex ) >= 0 );
+
+ // check a column count where parent is valid
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ if ( childIndex.isValid() )
+ Q_ASSERT ( model->columnCount ( childIndex ) >= 0 );
+
+ // columnCount() is tested more extensively in checkChildren(),
+ // but this catches the big mistakes
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::hasIndex()
+ */
+void ModelTest::hasIndex()
+{
+// qDebug() << "hi";
+ // Make sure that invalid values returns an invalid index
+ Q_ASSERT ( model->hasIndex ( -2, -2 ) == false );
+ Q_ASSERT ( model->hasIndex ( -2, 0 ) == false );
+ Q_ASSERT ( model->hasIndex ( 0, -2 ) == false );
+
+ int rows = model->rowCount();
+ int columns = model->columnCount();
+
+ // check out of bounds
+ Q_ASSERT ( model->hasIndex ( rows, columns ) == false );
+ Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false );
+
+ Q_UNUSED( columns );
+
+ if ( rows > 0 )
+ Q_ASSERT ( model->hasIndex ( 0, 0 ) == true );
+
+ // hasIndex() is tested more extensively in checkChildren(),
+ // but this catches the big mistakes
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::index()
+ */
+void ModelTest::index()
+{
+// qDebug() << "i";
+ // Make sure that invalid values returns an invalid index
+ Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() );
+ Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() );
+ Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() );
+
+ int rows = model->rowCount();
+ int columns = model->columnCount();
+
+ if ( rows == 0 )
+ return;
+
+ // Catch off by one errors
+ Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() );
+ Q_ASSERT ( model->index ( 0, 0 ).isValid() == true );
+
+ Q_UNUSED( columns );
+
+ // Make sure that the same index is *always* returned
+ QModelIndex a = model->index ( 0, 0 );
+ QModelIndex b = model->index ( 0, 0 );
+ Q_ASSERT ( a == b );
+
+ // index() is tested more extensively in checkChildren(),
+ // but this catches the big mistakes
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::parent()
+ */
+void ModelTest::parent()
+{
+// qDebug() << "p";
+ // Make sure the model wont crash and will return an invalid QModelIndex
+ // when asked for the parent of an invalid index.
+ Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() );
+
+ if ( model->rowCount() == 0 )
+ return;
+
+ // Column 0 | Column 1 |
+ // QModelIndex() | |
+ // \- topIndex | topIndex1 |
+ // \- childIndex | childIndex1 |
+
+ // Common error test #1, make sure that a top level index has a parent
+ // that is a invalid QModelIndex.
+ QModelIndex topIndex = model->index ( 0, 0, QModelIndex() );
+ Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() );
+
+ // Common error test #2, make sure that a second level index has a parent
+ // that is the first level index.
+ if ( model->rowCount ( topIndex ) > 0 ) {
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ Q_ASSERT ( model->parent ( childIndex ) == topIndex );
+ }
+
+ // Common error test #3, the second column should NOT have the same children
+ // as the first column in a row.
+ // Usually the second column shouldn't have children.
+ QModelIndex topIndex1 = model->index ( 0, 1, QModelIndex() );
+ if ( model->rowCount ( topIndex1 ) > 0 ) {
+ QModelIndex childIndex = model->index ( 0, 0, topIndex );
+ QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 );
+ Q_ASSERT ( childIndex != childIndex1 );
+ }
+
+ // Full test, walk n levels deep through the model making sure that all
+ // parent's children correctly specify their parent.
+ checkChildren ( QModelIndex() );
+}
+
+/*!
+ Called from the parent() test.
+
+ A model that returns an index of parent X should also return X when asking
+ for the parent of the index.
+
+ This recursive function does pretty extensive testing on the whole model in an
+ effort to catch edge cases.
+
+ This function assumes that rowCount(), columnCount() and index() already work.
+ If they have a bug it will point it out, but the above tests should have already
+ found the basic bugs because it is easier to figure out the problem in
+ those tests then this one.
+ */
+void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth )
+{
+ // First just try walking back up the tree.
+ QModelIndex p = parent;
+ while ( p.isValid() )
+ p = p.parent();
+
+ // For models that are dynamically populated
+// if ( model->canFetchMore ( parent ) ) {
+// fetchingMore = true;
+// model->fetchMore ( parent );
+// fetchingMore = false;
+// }
+
+ int rows = model->rowCount ( parent );
+ int columns = model->columnCount ( parent );
+
+ qDebug() << "checkChildren" << "parent=" << model->data ( parent ).value<QString>()
+ << "current count of parent=" << rows << "columns=" << columns;
+
+ if ( rows > 0 )
+ {
+
+ Q_ASSERT(parent.column() <= 0);
+ Q_ASSERT ( model->hasChildren ( parent ) );
+ }
+
+ // Some further testing against rows(), columns(), and hasChildren()
+ Q_ASSERT ( rows >= 0 );
+ Q_ASSERT ( columns >= 0 );
+ if ( rows > 0 )
+ Q_ASSERT ( model->hasChildren ( parent ) == true );
+
+ //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows
+ // << "columns:" << columns << "parent column:" << parent.column();
+
+ Q_ASSERT ( model->hasIndex ( rows, 0, parent ) == false );
+ Q_ASSERT ( model->index(rows, 0, parent).isValid() == false );
+ for ( int r = 0; r < rows; ++r ) {
+// if ( model->canFetchMore ( parent ) ) {
+// fetchingMore = true;
+// model->fetchMore ( parent );
+// fetchingMore = false;
+// }
+ Q_ASSERT ( model->hasIndex ( r, columns, parent ) == false );
+ Q_ASSERT ( model->index(r, columns, parent).isValid() == false );
+ for ( int c = 0; c < columns; ++c ) {
+ Q_ASSERT ( model->hasIndex ( r, c, parent ) == true );
+ QModelIndex index = model->index ( r, c, parent );
+ // rowCount() and columnCount() said that it existed...
+ Q_ASSERT ( index.isValid() == true );
+
+ // index() should always return the same index when called twice in a row
+ QModelIndex modifiedIndex = model->index ( r, c, parent );
+ Q_ASSERT ( index == modifiedIndex );
+
+ // Make sure we get the same index if we request it twice in a row
+ QModelIndex a = model->index ( r, c, parent );
+ QModelIndex b = model->index ( r, c, parent );
+ Q_ASSERT ( a == b );
+
+ // Some basic checking on the index that is returned
+ Q_ASSERT ( index.model() == model );
+ Q_ASSERT ( index.row() == r );
+ Q_ASSERT ( index.column() == c );
+ // While you can technically return a QVariant usually this is a sign
+ // of an bug in data() Disable if this really is ok in your model.
+ qDebug() << index << index.data() << index.parent();
+ Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true );
+
+ // If the next test fails here is some somewhat useful debug you play with.
+ /*
+ if (model->parent(index) != parent) {
+ qDebug() << r << c << currentDepth << model->data(index).toString()
+ << model->data(parent).toString();
+ qDebug() << index << parent << model->parent(index);
+ // And a view that you can even use to show the model.
+ //QTreeView view;
+ //view.setModel(model);
+ //view.show();
+ }*/
+
+ // Check that we can get back our real parent.
+ Q_ASSERT ( model->parent ( index ) == parent );
+
+ // recursively go down the children
+ if ( model->hasChildren ( index ) && currentDepth < 10 ) {
+ //qDebug() << r << c << "has children" << model->rowCount(index);
+ checkChildren ( index, ++currentDepth );
+ }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/
+
+ // make sure that after testing the children that the index doesn't change.
+ QModelIndex newerIndex = model->index ( r, c, parent );
+ Q_ASSERT ( index == newerIndex );
+ }
+ }
+}
+
+/*!
+ Tests model's implementation of QAbstractItemModel::data()
+ */
+void ModelTest::data()
+{
+ // Invalid index should return an invalid qvariant
+ Q_ASSERT ( !model->data ( QModelIndex() ).isValid() );
+
+ if ( model->rowCount() == 0 )
+ return;
+
+ // A valid index should have a valid QVariant data
+ Q_ASSERT ( model->index ( 0, 0 ).isValid() );
+
+ // shouldn't be able to set data on an invalid index
+ Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false );
+
+ // General Purpose roles that should return a QString
+ QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole );
+ if ( variant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
+ }
+ variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole );
+ if ( variant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
+ }
+ variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole );
+ if ( variant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QString> ( variant ) );
+ }
+
+ // General Purpose roles that should return a QSize
+ variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole );
+ if ( variant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QSize> ( variant ) );
+ }
+
+ // General Purpose roles that should return a QFont
+ QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole );
+ if ( fontVariant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QFont> ( fontVariant ) );
+ }
+
+ // Check that the alignment is one we know about
+ QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole );
+ if ( textAlignmentVariant.isValid() ) {
+ int alignment = textAlignmentVariant.toInt();
+ Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) );
+ Q_UNUSED( alignment );
+ }
+
+ // General Purpose roles that should return a QColor
+ QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole );
+ if ( colorVariant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
+ }
+
+ colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole );
+ if ( colorVariant.isValid() ) {
+ Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) );
+ }
+
+ // Check that the "check state" is one we know about.
+ QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole );
+ if ( checkStateVariant.isValid() ) {
+ int state = checkStateVariant.toInt();
+ Q_ASSERT ( state == Qt::Unchecked ||
+ state == Qt::PartiallyChecked ||
+ state == Qt::Checked );
+ Q_UNUSED( state );
+ }
+}
+
+/*!
+ Store what is about to be inserted to make sure it actually happens
+
+ \sa rowsInserted()
+ */
+void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end )
+{
+// Q_UNUSED(end);
+ qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).value<QString>()
+ << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
+// qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
+ Changing c;
+ c.parent = parent;
+ c.oldSize = model->rowCount ( parent );
+ c.last = model->data ( model->index ( start - 1, 0, parent ) );
+ c.next = model->data ( model->index ( start, 0, parent ) );
+ insert.push ( c );
+}
+
+/*!
+ Confirm that what was said was going to happen actually did
+
+ \sa rowsAboutToBeInserted()
+ */
+void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end )
+{
+ Changing c = insert.pop();
+ Q_ASSERT ( c.parent == parent );
+ qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize
+ << "parent=" << model->data ( parent ).value<QString>() << "current rowcount=" << model->rowCount ( parent );
+
+ for (int ii=start; ii <= end; ii++)
+ {
+ qDebug() << "itemWasInserted:" << model->data ( model->index ( ii, 0, parent ));
+ }
+
+
+ Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) );
+ Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
+ /*
+ if (c.next != model->data(model->index(end + 1, 0, c.parent))) {
+ qDebug() << start << end;
+ for (int i=0; i < model->rowCount(); ++i)
+ qDebug() << model->index(i, 0).data().toString();
+ qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent));
+ }
+ */
+ Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) );
+}
+
+
+void ModelTest::modelAboutToBeReset()
+{
+ qDebug() << "@@@@@@@@@@@" << "modelAboutToBeReset";
+}
+
+void ModelTest::modelReset()
+{
+ qDebug() << "@@@@@@@@@@@" << "modelReset";
+}
+
+void ModelTest::layoutAboutToBeChanged()
+{
+ for ( int i = 0; i < qBound ( 0, model->rowCount(), 100 ); ++i )
+ changing.append ( QPersistentModelIndex ( model->index ( i, 0 ) ) );
+}
+
+void ModelTest::layoutChanged()
+{
+ for ( int i = 0; i < changing.count(); ++i ) {
+ QPersistentModelIndex p = changing[i];
+ Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) );
+ }
+ changing.clear();
+}
+
+void ModelTest::rowsAboutToBeMoved(const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
+{
+ qDebug() << "rowsAboutToBeMoved" << srcParent << start << end << destParent << destinationRow;
+ Changing cs;
+ cs.parent = srcParent;
+ cs.oldSize = model->rowCount ( srcParent );
+ cs.last = model->data ( model->index ( start - 1, 0, srcParent ) );
+ cs.next = model->data ( model->index ( end + 1, 0, srcParent ) );
+ remove.push ( cs );
+ Changing cd;
+ cd.parent = destParent;
+ cd.oldSize = model->rowCount ( destParent );
+ cd.last = model->data ( model->index ( destinationRow - 1, 0, destParent ) );
+ cd.next = model->data ( model->index ( destinationRow, 0, destParent ) );
+ insert.push ( cd );
+}
+
+void ModelTest::rowsMoved(const QModelIndex &srcParent, int start, int end, const QModelIndex &destParent, int destinationRow )
+{
+ qDebug() << "rowsMoved" << srcParent << start << end << destParent << destinationRow;
+
+ Changing cd = insert.pop();
+ Q_ASSERT ( cd.parent == destParent );
+ if (srcParent == destParent)
+ {
+ Q_ASSERT ( cd.oldSize == model->rowCount ( destParent ) );
+
+ // TODO: Find out what I can assert here about last and next.
+// Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
+// Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
+
+
+ }
+ else
+ {
+ Q_ASSERT ( cd.oldSize + ( end - start + 1 ) == model->rowCount ( destParent ) );
+
+ Q_ASSERT ( cd.last == model->data ( model->index ( destinationRow - 1, 0, cd.parent ) ) );
+ Q_ASSERT ( cd.next == model->data ( model->index ( destinationRow + (end - start + 1), 0, cd.parent ) ) );
+ }
+ Changing cs = remove.pop();
+
+ Q_ASSERT ( cs.parent == srcParent );
+ if (srcParent == destParent)
+ {
+ Q_ASSERT ( cs.oldSize == model->rowCount ( srcParent ) );
+ }
+ else
+ {
+ Q_ASSERT ( cs.oldSize - ( end - start + 1 ) == model->rowCount ( srcParent ) );
+
+ Q_ASSERT ( cs.last == model->data ( model->index ( start - 1, 0, srcParent ) ) );
+ qDebug() << cs.next << model->data ( model->index ( start, 0, srcParent ) );
+ Q_ASSERT ( cs.next == model->data ( model->index ( start, 0, srcParent ) ) );
+ }
+
+}
+
+/*!
+ Store what is about to be inserted to make sure it actually happens
+
+ \sa rowsRemoved()
+ */
+void ModelTest::rowsAboutToBeRemoved ( const QModelIndex &parent, int start, int end )
+{
+qDebug() << "ratbr" << parent << start << end;
+ for (int ii=start; ii <= end; ii++)
+ {
+ qDebug() << "itemwillbe removed:" << model->data ( model->index ( ii, 0, parent ));
+ }
+
+
+ Changing c;
+ c.parent = parent;
+ c.oldSize = model->rowCount ( parent );
+ c.last = model->data ( model->index ( start - 1, 0, parent ) );
+ c.next = model->data ( model->index ( end + 1, 0, parent ) );
+ remove.push ( c );
+}
+
+/*!
+ Confirm that what was said was going to happen actually did
+
+ \sa rowsAboutToBeRemoved()
+ */
+void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end )
+{
+ qDebug() << "rr" << parent << start << end;
+ Changing c = remove.pop();
+ Q_ASSERT ( c.parent == parent );
+ Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) );
+ Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) );
+ Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) );
+}
+
diff --git a/libkdepim/freebusymodel/tests/modeltest.h b/libkdepim/freebusymodel/tests/modeltest.h
new file mode 100644
index 0000000..0ed70be
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/modeltest.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2007 Trolltech ASA. All rights reserved.
+**
+** This file is part of the Qt Concurrent project on Trolltech Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.trolltech.com/products/qt/opensource.html
+**
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://www.trolltech.com/products/qt/licensing.html or contact the
+** sales department at sales at trolltech.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+//krazy:excludeall=style
+
+#ifndef MODELTEST_H
+#define MODELTEST_H
+
+#include <QtCore/QObject>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QStack>
+
+class ModelTest : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ModelTest( QAbstractItemModel *model, QObject *parent = 0 );
+
+private Q_SLOTS:
+ void nonDestructiveBasicTest();
+ void rowCount();
+ void columnCount();
+ void hasIndex();
+ void index();
+ void parent();
+ void data();
+
+protected Q_SLOTS:
+ void runAllTests();
+ void layoutAboutToBeChanged();
+ void layoutChanged();
+ void modelAboutToBeReset();
+ void modelReset();
+ void rowsAboutToBeInserted( const QModelIndex &parent, int start, int end );
+ void rowsInserted( const QModelIndex & parent, int start, int end );
+ void rowsAboutToBeRemoved( const QModelIndex &parent, int start, int end );
+ void rowsRemoved( const QModelIndex & parent, int start, int end );
+ void rowsAboutToBeMoved ( const QModelIndex &, int, int, const QModelIndex &, int);
+ void rowsMoved ( const QModelIndex &, int, int, const QModelIndex &, int );
+
+private:
+ void checkChildren( const QModelIndex &parent, int currentDepth = 0 );
+
+ QAbstractItemModel *model;
+
+ struct Changing {
+ QModelIndex parent;
+ int oldSize;
+ QVariant last;
+ QVariant next;
+ };
+ QStack<Changing> insert;
+ QStack<Changing> remove;
+
+ bool fetchingMore;
+
+ QList<QPersistentModelIndex> changing;
+};
+
+#endif
diff --git a/libkdepim/freebusymodel/tests/testfreebusyitemmodel.cpp b/libkdepim/freebusymodel/tests/testfreebusyitemmodel.cpp
new file mode 100644
index 0000000..c34b5d2
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/testfreebusyitemmodel.cpp
@@ -0,0 +1,240 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "testfreebusyitemmodel.h"
+#include "modeltest.h"
+#include "freebusyitemmodel.h"
+#include "freebusyitem.h"
+
+#include <KCalCore/Attendee>
+
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( FreeBusyItemModelTest, NoGUI )
+
+void FreeBusyItemModelTest::testModelValidity()
+{
+ FreeBusyItemModel * model = new FreeBusyItemModel( this );
+ new ModelTest( model, this );
+
+ QVERIFY( model->rowCount() == 0 );
+
+ const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
+ KCalCore::Attendee::Ptr a1( new KCalCore::Attendee( QLatin1String("fred"), QLatin1String("fred at example.com") ) );
+ KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
+
+ fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+
+ FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
+ item1->setFreeBusy( fb1 );
+
+ model->addItem( item1 );
+ QVERIFY( model->rowCount() == 1 );
+ QVERIFY( model->containsAttendee( a1 ) );
+
+ QModelIndex i = model->index( 0, 0 );
+ QCOMPARE( a1->fullName(), model->data( i, Qt::DisplayRole ).toString() );
+ QCOMPARE( a1,
+ model->data( i, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
+ QCOMPARE( item1->freeBusy(),
+ model->data( i, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
+
+ QCOMPARE( model->rowCount( i ), 2 );
+
+ model->removeRow( 0 );
+ QVERIFY( model->rowCount() == 0 );
+
+ model->addItem( item1 );
+ QVERIFY( model->rowCount() == 1 );
+
+ model->removeAttendee( a1 );
+ QVERIFY( model->rowCount() == 0 );
+
+ model->addItem( item1 );
+ QVERIFY( model->rowCount() == 1 );
+
+ model->removeItem( item1 );
+ QVERIFY( model->rowCount() == 0 );
+
+ model->addItem( item1 );
+ QVERIFY( model->rowCount() == 1 );
+
+ model->clear();
+ QVERIFY( model->rowCount() == 0 );
+}
+
+void FreeBusyItemModelTest::testModelValidity2()
+{
+ FreeBusyItemModel * model = new FreeBusyItemModel( this );
+ new ModelTest( model, this );
+
+ const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt3( QDate( 2010, 7, 24 ), QTime( 12, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt4( QDate( 2010, 7, 24 ), QTime( 14, 0, 0 ), KDateTime::UTC );
+
+ KCalCore::Attendee::Ptr a1( new KCalCore::Attendee(QLatin1String("fred"), QLatin1String("fred at example.com")));
+ KCalCore::Attendee::Ptr a2( new KCalCore::Attendee(QLatin1String("joe"), QLatin1String("joe at example.com")));
+ KCalCore::Attendee::Ptr a3( new KCalCore::Attendee(QLatin1String("max"), QLatin1String("max at example.com")));
+ KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
+ KCalCore::FreeBusy::Ptr fb2( new KCalCore::FreeBusy() );
+ KCalCore::FreeBusy::Ptr fb3( new KCalCore::FreeBusy() );
+
+ fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+
+ fb2->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb2->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+ fb2->addPeriod( dt3, KCalCore::Duration( 60 * 60 ) );
+
+ fb3->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb3->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+ fb3->addPeriod( dt4, KCalCore::Duration( 60 * 60 * 2 ) );
+
+ FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
+ item1->setFreeBusy( fb1 );
+ FreeBusyItem::Ptr item2( new FreeBusyItem( a2, 0 ) );
+ FreeBusyItem::Ptr item3( new FreeBusyItem( a3, 0 ) );
+
+ model->addItem( item1 );
+ model->addItem( item2 );
+ model->addItem( item3 );
+
+ QCOMPARE( model->rowCount(), 3 );
+
+ QVERIFY( model->containsAttendee( a1 ) );
+ QVERIFY( model->containsAttendee( a2 ) );
+ QVERIFY( model->containsAttendee( a3 ) );
+
+ QModelIndex i1 = model->index( 0, 0 );
+ QCOMPARE( a1->fullName(), model->data( i1, Qt::DisplayRole ).toString() );
+ QCOMPARE( a1,
+ model->data( i1, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
+ QCOMPARE( item1->freeBusy(),
+ model->data( i1, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
+
+ QModelIndex i2 = model->index( 1, 0 );
+ QCOMPARE( a2->fullName(), model->data( i2, Qt::DisplayRole ).toString() );
+ QCOMPARE( a2,
+ model->data( i2, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
+ QVERIFY( model->rowCount( i2 ) == 0 );
+ QVERIFY( model->data( i2, FreeBusyItemModel::FreeBusyRole ).isValid() == false );
+
+ QModelIndex i3 = model->index( 2, 0 );
+ QCOMPARE( a3->fullName(),
+ model->data( i3, Qt::DisplayRole ).toString() );
+ QCOMPARE( a3,
+ model->data( i3, FreeBusyItemModel::AttendeeRole ).value<KCalCore::Attendee::Ptr>() );
+ QVERIFY( model->rowCount( i3 ) == 0 );
+ QVERIFY( model->data( i3, FreeBusyItemModel::FreeBusyRole ).isValid() == false );
+
+ model->slotInsertFreeBusy( fb2, QLatin1String("joe at example.com"));
+ QCOMPARE( item2->freeBusy(),
+ model->data( i2, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
+ QVERIFY( model->rowCount( i2 ) == fb2->fullBusyPeriods().size() );
+
+ QModelIndex i2_0 = model->index( 0, 0, i2 );
+ QCOMPARE( fb2->fullBusyPeriods().first(),
+ model->data(
+ i2_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ QModelIndex i2_1 = model->index( 1, 0, i2 );
+ QCOMPARE( fb2->fullBusyPeriods().at( 1 ),
+ model->data(
+ i2_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ QModelIndex i2_2 = model->index( 2, 0, i2 );
+ QCOMPARE( fb2->fullBusyPeriods().last(),
+ model->data(
+ i2_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+
+ model->slotInsertFreeBusy( fb3, QLatin1String("max at example.com"));
+ QCOMPARE( item3->freeBusy(),
+ model->data( i3, FreeBusyItemModel::FreeBusyRole ).value<KCalCore::FreeBusy::Ptr>() );
+ QVERIFY( model->rowCount( i3 ) == fb3->fullBusyPeriods().size() );
+
+ QModelIndex i3_0 = model->index( 0, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().first(),
+ model->data(
+ i3_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ QModelIndex i3_1 = model->index( 1, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().at( 1 ),
+ model->data(
+ i3_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ QModelIndex i3_2 = model->index( 2, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().last(),
+ model->data(
+ i3_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+
+ model->removeAttendee( a2 );
+
+ QCOMPARE( 2, model->rowCount() );
+
+ QVERIFY( model->containsAttendee( a1 ) == true );
+ QVERIFY( model->containsAttendee( a2 ) == false );
+ QVERIFY( model->containsAttendee( a3 ) == true );
+
+ i3_0 = model->index( 0, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().first(),
+ model->data(
+ i3_0, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ i3_1 = model->index( 1, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().at( 1 ),
+ model->data(
+ i3_1, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+ i3_2 = model->index( 2, 0, i3 );
+ QCOMPARE( fb3->fullBusyPeriods().last(),
+ model->data(
+ i3_2, FreeBusyItemModel::FreeBusyPeriodRole ).value<KCalCore::FreeBusyPeriod>() );
+}
+
+void FreeBusyItemModelTest::testInsertFreeBusy()
+{
+ FreeBusyItemModel * model = new FreeBusyItemModel( this );
+ new ModelTest( model, this );
+
+ const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
+ KCalCore::Attendee::Ptr a1( new KCalCore::Attendee( QLatin1String("fred"), QLatin1String("fred at example.com")) );
+ KCalCore::FreeBusy::Ptr fb1( new KCalCore::FreeBusy() );
+ fb1->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb1->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+
+ const KDateTime dt3( QDate( 2010, 7, 24 ), QTime( 12, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt4( QDate( 2010, 7, 24 ), QTime( 14, 0, 0 ), KDateTime::UTC );
+ KCalCore::FreeBusy::Ptr fb2( new KCalCore::FreeBusy() );
+ fb2->addPeriod( dt1, KCalCore::Duration( 60 * 60 ) );
+ fb2->addPeriod( dt2, KCalCore::Duration( 60 * 60 ) );
+ fb2->addPeriod( dt3, KCalCore::Duration( 60 * 60 ) );
+ fb2->addPeriod( dt4, KCalCore::Duration( 60 * 60 * 2 ) );
+
+ FreeBusyItem::Ptr item1( new FreeBusyItem( a1, 0 ) );
+ item1->setFreeBusy( fb1 );
+
+ model->addItem( item1 );
+
+ QModelIndex i = model->index( 0, 0 );
+ QCOMPARE( model->rowCount( i ), 2 );
+
+ model->slotInsertFreeBusy( fb2, QLatin1String("fred at example.com"));
+
+ QCOMPARE( model->rowCount( i ), 4 );
+}
+
diff --git a/libkdepim/freebusymodel/tests/testfreebusyitemmodel.h b/libkdepim/freebusymodel/tests/testfreebusyitemmodel.h
new file mode 100644
index 0000000..2a16694
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/testfreebusyitemmodel.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+#ifndef TESTFREEBUSYITEMMODEL_H
+#define TESTFREEBUSYITEMMODEL_H
+
+#include <QObject>
+
+class FreeBusyItemModelTest: public QObject
+{
+ Q_OBJECT
+ private Q_SLOTS:
+ void testModelValidity();
+ void testModelValidity2();
+ void testInsertFreeBusy();
+};
+#endif
diff --git a/libkdepim/freebusymodel/tests/testfreeperiodmodel.cpp b/libkdepim/freebusymodel/tests/testfreeperiodmodel.cpp
new file mode 100644
index 0000000..dd1b524
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/testfreeperiodmodel.cpp
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "testfreeperiodmodel.h"
+#include "modeltest.h"
+#include "freeperiodmodel.h"
+
+#include <KCalCore/Period>
+#include <KCalCore/Duration>
+
+#include <KDebug>
+
+#include <qtest_kde.h>
+
+QTEST_KDEMAIN( FreePeriodModelTest, NoGUI )
+
+void FreePeriodModelTest::testModelValidity()
+{
+ FreePeriodModel * model = new FreePeriodModel( this );
+ new ModelTest( model, this );
+
+ const KDateTime dt1( QDate( 2010, 7, 24 ), QTime( 7, 0, 0 ), KDateTime::UTC );
+ const KDateTime dt2( QDate( 2010, 7, 24 ), QTime( 10, 0, 0 ), KDateTime::UTC );
+
+ KCalCore::Period::List list;
+
+ list << KCalCore::Period( dt1, KCalCore::Duration( 60 * 60 ) );
+ list << KCalCore::Period( dt2, KCalCore::Duration( 60 * 60 ) );
+
+ QVERIFY( model->rowCount() == 0 );
+ model->slotNewFreePeriods( list );
+ QCOMPARE( model->rowCount(), 2 );
+}
+
+void FreePeriodModelTest::testSplitByDay()
+{
+ FreePeriodModel * model = new FreePeriodModel( this );
+ new ModelTest( model, this );
+
+ const KDateTime startDt( QDate( 2010, 7, 24 ), QTime( 8, 0, 0 ), KDateTime::UTC );
+ const KDateTime endDt( QDate( 2010, 7, 25 ), QTime( 8, 0, 0 ), KDateTime::UTC );
+
+ KCalCore::Period::List list;
+
+ // This period goes from 8am on the 24th to 8am on the 25th
+ list << KCalCore::Period( startDt, endDt );
+
+ QVERIFY( model->rowCount() == 0 );
+
+ // as part of adding the new periods
+ // the model should split the above period into two
+ // one from 8am-12 on the 24th, and the second from 00-08 on the 25th
+ model->slotNewFreePeriods( list );
+
+ const KDateTime endPeriod1( QDate( 2010, 7, 24 ), QTime( 23, 59, 59, 999 ), KDateTime::UTC );
+ const KDateTime startPeriod2( QDate( 2010, 7, 25 ), QTime( 0, 0, 0, 0 ), KDateTime::UTC );
+
+ QModelIndex index = model->index( 0, 0 );
+ KCalCore::Period period1 =
+ model->data( index, FreePeriodModel::PeriodRole ).value<KCalCore::Period>();
+ index = model->index( 1, 0 );
+ KCalCore::Period period2 =
+ model->data( index, FreePeriodModel::PeriodRole ).value<KCalCore::Period>();
+
+ QCOMPARE( period1.start(), startDt );
+ QCOMPARE( period1.end(), endPeriod1 );
+ QCOMPARE( period2.start(), startPeriod2 );
+ QCOMPARE( period2.end(), endDt );
+}
+
diff --git a/libkdepim/freebusymodel/tests/testfreeperiodmodel.h b/libkdepim/freebusymodel/tests/testfreeperiodmodel.h
new file mode 100644
index 0000000..7d60b62
--- /dev/null
+++ b/libkdepim/freebusymodel/tests/testfreeperiodmodel.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2010 Casey Link <unnamedrambler at gmail.com>
+ Copyright (C) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info at kdab.net>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library 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 Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+#ifndef TESTFREEPERIODMODEL_H
+#define TESTFREEPERIODMODEL_H
+
+#include <QObject>
+
+class FreePeriodModelTest: public QObject
+{
+ Q_OBJECT
+ private Q_SLOTS:
+ void testModelValidity();
+ void testSplitByDay();
+};
+#endif
More information about the commits
mailing list