Skip to content

Commit

Permalink
Merge pull request #7 from dcaliste/errors
Browse files Browse the repository at this point in the history
Report when events already exist in db on importation
  • Loading branch information
pvuorela committed Oct 19, 2021
2 parents 8dbc57b + d8d7731 commit 643120a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 83 deletions.
119 changes: 39 additions & 80 deletions src/calendarimportmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QUrl>

// mkcal
#include <extendedcalendar.h>
#include <extendedstorage.h>

// kcalendarcore
#include <KCalendarCore/MemoryCalendar>
Expand All @@ -49,6 +47,11 @@ CalendarImportModel::CalendarImportModel(QObject *parent)
: QAbstractListModel(parent),
mError(false)
{
mKCal::ExtendedCalendar::Ptr calendar(new mKCal::ExtendedCalendar(QTimeZone::systemTimeZone()));
mStorage = calendar->defaultStorage(calendar);
if (!mStorage->open()) {
qWarning() << "Unable to open calendar DB";
}
}

CalendarImportModel::~CalendarImportModel()
Expand All @@ -72,7 +75,7 @@ void CalendarImportModel::setFileName(const QString &fileName)

mFileName = fileName;
emit fileNameChanged();
reload();
setError(!importToMemory(mFileName, mIcsRawData));
}

QString CalendarImportModel::icsString() const
Expand All @@ -88,7 +91,12 @@ void CalendarImportModel::setIcsString(const QString &icsData)

mIcsRawData = data;
emit icsStringChanged();
reload();
setError(!importToMemory(mFileName, mIcsRawData));
}

bool CalendarImportModel::hasDuplicates() const
{
return !mDuplicates.isEmpty();
}

bool CalendarImportModel::error() const
Expand Down Expand Up @@ -132,50 +140,28 @@ QVariant CalendarImportModel::data(const QModelIndex &index, int role) const
return event->allDay();
case LocationRole:
return event->location();
case DuplicateRole:
return mDuplicates.contains(event->instanceIdentifier());
case UidRole:
return event->uid();
default:
return QVariant();
}
}

bool CalendarImportModel::importToNotebook(const QString &notebookUid)
bool CalendarImportModel::importToNotebook(const QString &notebookUid) const
{
mKCal::ExtendedCalendar::Ptr calendar(new mKCal::ExtendedCalendar(QTimeZone::systemTimeZone()));
mKCal::ExtendedStorage::Ptr storage = calendar->defaultStorage(calendar);
bool success = false;

if (!storage->open()) {
qWarning() << "Unable to open calendar DB";
return false;
}

if (!notebookUid.isEmpty()) {
if (! (storage->defaultNotebook() && storage->defaultNotebook()->uid() == notebookUid)) {
mKCal::Notebook::Ptr notebook = storage->notebook(notebookUid);
if (notebook) {
// TODO: should we change default notebook back if we change it?
storage->setDefaultNotebook(notebook);
} else {
qWarning() << "Invalid notebook UID" << notebookUid;
return false;
}
for (const KCalendarCore::Incidence::Ptr &incidence : mEventList) {
const KCalendarCore::Incidence::Ptr old =
mStorage->calendar()->incidence(incidence->uid(), incidence->recurrenceId());
if (old) {
// Unconditionally overwrite existing incidence with the same UID/RecID.
mStorage->calendar()->deleteIncidence(old);
}
mStorage->calendar().staticCast<mKCal::ExtendedCalendar>()->addIncidence(incidence, notebookUid);
}

if (!mFileName.isEmpty()) {
success = CalendarUtils::importFromFile(mFileName, calendar);
} else {
success = CalendarUtils::importFromIcsRawData(mIcsRawData, calendar);
}

if (success) {
storage->save();
}

storage->close();

return success;
return mStorage->save();
}

QHash<int, QByteArray> CalendarImportModel::roleNames() const
Expand All @@ -187,66 +173,39 @@ QHash<int, QByteArray> CalendarImportModel::roleNames() const
roleNames[EndTimeRole] = "endTime";
roleNames[AllDayRole] = "allDay";
roleNames[LocationRole] = "location";
roleNames[DuplicateRole] = "duplicate";
roleNames[UidRole] = "uid";

return roleNames;
}

static bool incidenceLessThan(const KCalendarCore::Incidence::Ptr e1,
const KCalendarCore::Incidence::Ptr e2)
{
if (e1->dtStart() == e2->dtStart()) {
int cmp = QString::compare(e1->summary(),
e2->summary(),
Qt::CaseInsensitive);
if (cmp == 0)
return QString::compare(e1->uid(), e2->uid()) < 0;
else
return cmp < 0;
} else {
return e1->dtStart() < e2->dtStart();
}
}

void CalendarImportModel::reload()
{
if (!mFileName.isEmpty() || !mIcsRawData.isEmpty()) {
bool success = importToMemory(mFileName, mIcsRawData);
setError(!success);
} else if (!mEventList.isEmpty()) {
beginResetModel();
mEventList.clear();
endResetModel();
emit countChanged();
setError(false);
}
}

bool CalendarImportModel::importToMemory(const QString &fileName, const QByteArray &icsData)
{
if (!mEventList.isEmpty())
mEventList.clear();

bool success = false;

beginResetModel();
KCalendarCore::MemoryCalendar::Ptr cal(new KCalendarCore::MemoryCalendar(QTimeZone::systemTimeZone()));
if (!fileName.isEmpty()) {
success = CalendarUtils::importFromFile(fileName, cal);
} else {
} else if (!icsData.isEmpty()) {
success = CalendarUtils::importFromIcsRawData(icsData, cal);
}
KCalendarCore::Incidence::List incidenceList = cal->incidences();
for (int i = 0; i < incidenceList.size(); i++) {
KCalendarCore::Incidence::Ptr incidence = incidenceList.at(i);
if (incidence->type() == KCalendarCore::IncidenceBase::TypeEvent)
mEventList.append(incidence.staticCast<KCalendarCore::Event>());
}
if (!mEventList.isEmpty())
qSort(mEventList.begin(), mEventList.end(), incidenceLessThan);

beginResetModel();
mDuplicates.clear();
mEventList = cal->events(KCalendarCore::EventSortStartDate);
// To avoid detach here, use qAsConst when available.
for (const KCalendarCore::Event::Ptr &event : mEventList) {
mStorage->load(event->uid(), event->recurrenceId());
const KCalendarCore::Event::Ptr old =
mStorage->calendar()->event(event->uid(), event->recurrenceId());
if (old) {
mDuplicates.insert(old->instanceIdentifier());
}
}
endResetModel();
emit countChanged();
emit hasDuplicatesChanged();

return success;
}

Expand Down
12 changes: 9 additions & 3 deletions src/calendarimportmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@

#include <QAbstractListModel>

// kcalendarcore
#include <KCalendarCore/Calendar>
#include <extendedstorage.h>

class CalendarImportModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged)
Q_PROPERTY(QString icsString READ icsString WRITE setIcsString NOTIFY icsStringChanged)
Q_PROPERTY(bool hasDuplicates READ hasDuplicates NOTIFY hasDuplicatesChanged)
Q_PROPERTY(bool error READ error NOTIFY errorChanged)

public:
Expand All @@ -55,6 +56,7 @@ class CalendarImportModel : public QAbstractListModel
AllDayRole,
LocationRole,
UidRole,
DuplicateRole,
};

explicit CalendarImportModel(QObject *parent = 0);
Expand All @@ -68,6 +70,8 @@ class CalendarImportModel : public QAbstractListModel
QString icsString() const;
void setIcsString(const QString &icsData);

bool hasDuplicates() const;

bool error() const;

virtual int rowCount(const QModelIndex &index) const;
Expand All @@ -80,22 +84,24 @@ public slots:
void countChanged();
void fileNameChanged();
void icsStringChanged();
void hasDuplicatesChanged();
bool errorChanged();

public slots:
bool importToNotebook(const QString &notebookUid = QString());
bool importToNotebook(const QString &notebookUid = QString()) const;

protected:
virtual QHash<int, QByteArray> roleNames() const;

private:
void reload();
bool importToMemory(const QString &fileName, const QByteArray &icsData);
void setError(bool error);

QString mFileName;
QByteArray mIcsRawData;
KCalendarCore::Event::List mEventList;
mKCal::ExtendedStorage::Ptr mStorage;
QSet<QString> mDuplicates;
bool mError;
};

Expand Down

0 comments on commit 643120a

Please sign in to comment.