Commit 67af9451 authored by Volker Krause's avatar Volker Krause
Browse files

Use IncidenceTreeModel from akonadi-calendar

parent b0fa3a49
Pipeline #164941 passed with stage
in 5 minutes and 4 seconds
......@@ -41,7 +41,6 @@ target_sources(KF5EventViews PRIVATE
todo/tododelegates.cpp
todo/todomodel.cpp
todo/incidencetreemodel.cpp
todo/todoviewquickaddline.cpp
todo/todoviewquicksearch.cpp
......@@ -68,11 +67,9 @@ target_sources(KF5EventViews PRIVATE
todo/todoviewview.h
todo/todomodel.h
todo/todoviewquicksearch.h
todo/incidencetreemodel_p.h
todo/tododelegates.h
todo/todomodel_p.h
todo/todoview.h
todo/incidencetreemodel.h
todo/todoviewquickaddline.h
multiagenda/multiagendaview.h
multiagenda/configdialoginterface.h
......@@ -174,7 +171,6 @@ ecm_generate_headers(eventviews_CamelCasetodo_HEADERS
HEADER_NAMES
TodoView
TodoModel
IncidenceTreeModel
REQUIRED_HEADERS eventviews_todo_HEADERS
PREFIX EventViews
RELATIVE todo
......
This diff is collapsed.
/*
SPDX-FileCopyrightText: 2012 Sérgio Martins <iamsergio@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
*/
#pragma once
#include "eventviews_export.h"
#include <Akonadi/Item>
#include <QAbstractProxyModel>
#include <memory>
class IncidenceTreeModelPrivate;
class EVENTVIEWS_EXPORT IncidenceTreeModel : public QAbstractProxyModel
{
Q_OBJECT
public:
/**
* Constructs a new IncidenceTreeModel.
*/
explicit IncidenceTreeModel(QObject *parent = nullptr);
/**
* Constructs a new IncidenceTreeModel which will only show incidences of
* type @p mimeTypes. Common use case is a to-do tree.
*
* This constructor is offered for performance reasons. The filtering has
* zero overhead, and we avoid stacking mime type filter proxy models.
*
* If you're more concerned about clean design than performance, use the default
* constructor and stack a Akonadi::EntityMimeTypeFilterModel on top of this one.
*/
explicit IncidenceTreeModel(const QStringList &mimeTypes, QObject *parent = nullptr);
~IncidenceTreeModel() override;
Q_REQUIRED_RESULT int rowCount(const QModelIndex &parent = QModelIndex()) const override;
Q_REQUIRED_RESULT int columnCount(const QModelIndex &parent = QModelIndex()) const override;
Q_REQUIRED_RESULT QVariant data(const QModelIndex &index, int role) const override;
Q_REQUIRED_RESULT QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
Q_REQUIRED_RESULT QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override;
Q_REQUIRED_RESULT QModelIndex mapToSource(const QModelIndex &proxyIndex) const override;
Q_REQUIRED_RESULT QModelIndex parent(const QModelIndex &child) const override;
void setSourceModel(QAbstractItemModel *sourceModel) override;
Q_REQUIRED_RESULT bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
/**
* Returns the akonadi item containing the incidence with @p incidenceUid.
*/
Q_REQUIRED_RESULT Akonadi::Item item(const QString &incidenceUid) const;
Q_SIGNALS:
/**
* This signal is emitted whenever an index changes parent.
* The view can then expand the parent if desired.
* This is better than the view waiting for "rows moved" signals because those
* signals are also sent when the model is initially populated.
*/
void indexChangedParent(const QModelIndex &index);
/**
* Signals that we finished doing a batch of insertions.
*
* One rowsInserted() signal from the ETM, will make IncidenceTreeModel generate
* several rowsInserted(), layoutChanged() or rowsMoved() signals.
*
* A tree view can use this signal to know when to call KConfigViewStateSaver::restore()
* to restore expansion states. Listening to rowsInserted() signals would be a
* performance problem.
*/
void batchInsertionFinished();
private:
friend class IncidenceTreeModelPrivate;
std::unique_ptr<IncidenceTreeModelPrivate> const d;
};
/*
SPDX-FileCopyrightText: 2012 Sérgio Martins <iamsergio@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
*/
#pragma once
#include "incidencetreemodel.h"
#include <Akonadi/Item>
#include <KCalendarCore/Incidence>
#include <QHash>
#include <QModelIndex>
#include <QObject>
#include <QPersistentModelIndex>
#include <QSharedPointer>
#include <QStringList>
#include <QVector>
using Uid = QString;
using ParentUid = QString;
struct Node {
using Ptr = QSharedPointer<Node>;
using Map = QMap<Akonadi::Item::Id, Ptr>;
using List = QVector<Ptr>;
QPersistentModelIndex sourceIndex; // because ETM::modelIndexesForItem is so slow
Akonadi::Item::Id id;
Node::Ptr parentNode;
QString parentUid;
QString uid;
List directChilds;
int depth;
};
/** Just a struct to contain some data before we create the node */
struct PreNode {
using Ptr = QSharedPointer<PreNode>;
using List = QVector<Ptr>;
KCalendarCore::Incidence::Ptr incidence;
QPersistentModelIndex sourceIndex;
Akonadi::Item item;
int depth;
PreNode()
: depth(-1)
{
}
};
class IncidenceTreeModelPrivate : public QObject
{
Q_OBJECT
public:
IncidenceTreeModelPrivate(IncidenceTreeModel *qq, const QStringList &mimeTypes);
void reset(bool silent = false);
void insertNode(const PreNode::Ptr &node, bool silent = false);
void insertNode(const QModelIndex &sourceIndex, bool silent = false);
void removeNode(const Node::Ptr &node);
QModelIndex indexForNode(const Node::Ptr &node) const;
int rowForNode(const Node::Ptr &node) const;
bool indexBeingRemoved(const QModelIndex &) const; // Is it being removed?
void dumpTree();
void assert_and_dump(bool condition, const QString &message);
Node::List sorted(const Node::List &nodes) const;
PreNode::Ptr prenodeFromSourceRow(int sourceRow) const;
void setSourceModel(QAbstractItemModel *model);
public:
Node::Map m_nodeMap;
Node::List m_toplevelNodeList;
QHash<Uid, Node::Ptr> m_uidMap;
QHash<Uid, Akonadi::Item> m_itemByUid;
QMultiHash<ParentUid, Node::Ptr> m_waitingForParent;
QList<Node *> m_removedNodes;
const QStringList m_mimeTypes;
private Q_SLOTS:
void onHeaderDataChanged(Qt::Orientation orientation, int first, int last);
void onDataChanged(const QModelIndex &begin, const QModelIndex &end);
void onRowsAboutToBeInserted(const QModelIndex &parent, int begin, int end);
void onRowsInserted(const QModelIndex &parent, int begin, int end);
void onRowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end);
void onRowsRemoved(const QModelIndex &parent, int begin, int end);
void onRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
void onModelAboutToBeReset();
void onModelReset();
void onLayoutAboutToBeChanged();
void onLayoutChanged();
private:
IncidenceTreeModel *const q;
};
......@@ -5,7 +5,6 @@
SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
*/
#include "incidencetreemodel.h"
#include "todomodel_p.h"
#include <CalendarSupport/KCalPrefs>
......@@ -16,6 +15,8 @@
#include <KEmailAddress>
#include <KLocalizedString>
#include <Akonadi/IncidenceTreeModel>
#include <KCalUtils/DndFactory>
#include <KCalUtils/ICalDrag>
#include <KCalUtils/VCalDrag>
......@@ -60,7 +61,7 @@ TodoModelPrivate::TodoModelPrivate(const EventViews::PrefsPtr &preferences, Todo
Akonadi::Item TodoModelPrivate::findItemByUid(const QString &uid, const QModelIndex &parent) const
{
Q_ASSERT(!uid.isEmpty());
auto treeModel = qobject_cast<IncidenceTreeModel *>(q->sourceModel());
auto treeModel = qobject_cast<Akonadi::IncidenceTreeModel *>(q->sourceModel());
if (treeModel) { // O(1) Shortcut
return treeModel->item(uid);
}
......
......@@ -13,7 +13,6 @@
#include "todoview.h"
#include "calendarview_debug.h"
#include "incidencetreemodel.h"
#include "tododelegates.h"
#include "todomodel.h"
#include "todoviewquickaddline.h"
......@@ -25,6 +24,7 @@
#include <Akonadi/TagFetchJob>
#include <Akonadi/ETMViewStateSaver>
#include <Akonadi/IncidenceTreeModel>
#include <CalendarSupport/KCalPrefs>
#include <CalendarSupport/Utils>
......@@ -105,10 +105,10 @@ public:
todoTreeModel = nullptr;
} else {
delete todoTreeModel;
todoTreeModel = new IncidenceTreeModel(QStringList() << todoMimeType, parent);
todoTreeModel = new Akonadi::IncidenceTreeModel(QStringList() << todoMimeType, parent);
for (TodoView *view : std::as_const(views)) {
QObject::connect(todoTreeModel, &IncidenceTreeModel::indexChangedParent, view, &TodoView::expandIndex);
QObject::connect(todoTreeModel, &IncidenceTreeModel::batchInsertionFinished, view, &TodoView::restoreViewState);
QObject::connect(todoTreeModel, &Akonadi::IncidenceTreeModel::indexChangedParent, view, &TodoView::expandIndex);
QObject::connect(todoTreeModel, &Akonadi::IncidenceTreeModel::batchInsertionFinished, view, &TodoView::restoreViewState);
view->mView->setDragDropMode(QAbstractItemView::DragDrop);
view->setFlatView(flat, /**propagate=*/false); // So other views update their toggle icon
}
......@@ -150,7 +150,7 @@ public:
QObject *parent = nullptr;
Akonadi::ETMCalendar::Ptr calendar;
IncidenceTreeModel *todoTreeModel = nullptr;
Akonadi::IncidenceTreeModel *todoTreeModel = nullptr;
Akonadi::EntityMimeTypeFilterModel *todoFlatModel = nullptr;
EventViews::PrefsPtr prefs;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment