summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Choffet2016-01-09 10:58:17 -0500
committerPierre Choffet2016-01-09 10:58:17 -0500
commit58e345f703ef5335a24b6365bec313fed58a6eac (patch)
tree718aab51c4ce64726eb7e8c5e8afbfdd86bf4614
parent9ae630727a3e3a53798d21fe5ee762a0175deab8 (diff)
downloadaur-58e345f703ef5335a24b6365bec313fed58a6eac.tar.gz
Remove custom made patches
The incompatibility has been fixed upstream, so the patches are now useless and removed.
-rw-r--r--.SRCINFO18
-rw-r--r--0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch886
-rw-r--r--0002-contact-Enable-Akonadi-support-again.patch1565
-rw-r--r--0003-history-De-duplicate-identical-calls.patch685
-rw-r--r--0004-akonadi-Make-it-optional.patch234
-rw-r--r--0005-Fix-CMakeLists.txt.patch25
-rw-r--r--0006-contact-Add-new-basic-contact-selection-dialog.patch461
-rw-r--r--ChangeLog5
-rw-r--r--PKGBUILD27
9 files changed, 12 insertions, 3894 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 49cc8b6b0723..9814450d7c42 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,9 +1,9 @@
# Generated by mksrcinfo v8
-# Thu Jan 7 21:39:10 UTC 2016
+# Sat Jan 9 15:57:47 UTC 2016
pkgbase = ring-kde-git
pkgdesc = KDE client for Ring
- pkgver = 2.0.0.r138.g18ff797
- pkgrel = 2
+ pkgver = 2.0.0.r177.g49fb1c3
+ pkgrel = 1
url = http://ring.cx/
changelog = ChangeLog
arch = i686
@@ -33,19 +33,7 @@ pkgbase = ring-kde-git
depends = knotifications
provides = ring-kde
source = git://anongit.kde.org/ring-kde
- source = 0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch
- source = 0002-contact-Enable-Akonadi-support-again.patch
- source = 0003-history-De-duplicate-identical-calls.patch
- source = 0004-akonadi-Make-it-optional.patch
- source = 0005-Fix-CMakeLists.txt.patch
- source = 0006-contact-Add-new-basic-contact-selection-dialog.patch
sha256sums = SKIP
- sha256sums = fe1a4a7ba6df920117adf5d57a8fcfaa784986369a50c91bd3ae5b0f69ea2c59
- sha256sums = 2fce01531bcdf001b1f8cc34522c5951dcbb853ea597ffa4421cdd78661148d2
- sha256sums = 1c1ff7d6244982cbf56720eeda731b5fb09933178e02d0b3d24614a906d91e29
- sha256sums = b50755d6653b417046734a29d25cdb4ff2cadcc900e119b309e4fbb0d8614894
- sha256sums = d1215e1ba920f7b359a4319caa6ea286784b32079fc647c2fe7b66a9dde4e44c
- sha256sums = c22e0d8518575d00dc6b660e5c8979659678e403947526465ceaf17cdca7c517
pkgname = ring-kde-git
diff --git a/0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch b/0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch
deleted file mode 100644
index 57ff096f7d8b..000000000000
--- a/0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch
+++ /dev/null
@@ -1,886 +0,0 @@
-From 8f430e63c139efbd6df69f846963db925ecf1699 Mon Sep 17 00:00:00 2001
-From: Emmanuel Lepage Vallee <elv1313@gmail.com>
-Date: Sun, 13 Dec 2015 06:49:01 -0500
-Subject: [PATCH 1/6] textmessages: Vastly revamp and fix the text messages
-
-They are always neglected because nobody (I know of) use them, but
-many of the issues and regressions have been fixed. A short sumary:
-
- * New notification for text messages
- * Show only "readable" text messages
- * Show the history when selecting the entry widget
- * Show the entry box when relevant
- * Set a red color for missed messages tabs
- * Scroll down to the end automatically
----
- src/CMakeLists.txt | 1 +
- src/delegates/imdelegate.cpp | 23 +++-
- src/delegates/imdelegate.h | 5 +-
- src/eventmanager.cpp | 23 ++--
- src/eventmanager.h | 11 +-
- src/mainwindow.cpp | 3 -
- src/notification.cpp | 261 +++++++++++++++++++++++++++++++++++++++++++
- src/notification.h | 56 ++++++++++
- src/view.cpp | 64 ++++++++++-
- src/view.h | 2 +
- src/widgets/immanager.cpp | 129 +++++++++++++++++++--
- src/widgets/immanager.h | 15 ++-
- 12 files changed, 562 insertions(+), 31 deletions(-)
- create mode 100644 src/notification.cpp
- create mode 100644 src/notification.h
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 1b461f9..201f107 100755
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -173,6 +173,7 @@ SET(
- delegates/toolbardelegate.cpp
- delegates/kdepixmapmanipulation.cpp
- proxies/simplerotateproxy.cpp
-+ #proxies/valuefilterproxy.cpp
- )
-
- # Configuration pages
-diff --git a/src/delegates/imdelegate.cpp b/src/delegates/imdelegate.cpp
-index 6467676..bb4a40b 100644
---- a/src/delegates/imdelegate.cpp
-+++ b/src/delegates/imdelegate.cpp
-@@ -20,8 +20,10 @@
- #include "call.h"
- #include <media/textrecording.h>
- #include <QtGui/QPainter>
--#include <QIcon>
-+#include <QtGui/QIcon>
-+#include <QtCore/QTimer>
- #include <QtGui/QFont>
-+#include <QtWidgets/QScrollBar>
-
- ///Delegate contructor
- ImDelegates::ImDelegates(IMTab* parent) : QStyledItemDelegate(parent),m_pParent(parent)
-@@ -70,7 +72,7 @@ void ImDelegates::paint(QPainter* painter, const QStyleOptionViewItem& option, c
- }
-
- ///Constructor
--IMTab::IMTab(QAbstractListModel* model,QWidget* parent) : QListView(parent)
-+IMTab::IMTab(QAbstractItemModel* model,QWidget* parent) : QListView(parent)
- {
- setModel(model);
- setAlternatingRowColors(true);
-@@ -78,7 +80,14 @@ IMTab::IMTab(QAbstractListModel* model,QWidget* parent) : QListView(parent)
- setUniformItemSizes(false);
- setItemDelegate(new ImDelegates(this));
- setVerticalScrollMode(ScrollPerPixel);
-+
-+ scrollTo(model->index(model->rowCount()-1,0));
-+
-+ if (verticalScrollBar())
-+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
-+
- connect(model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),this,SLOT(scrollBottom()));
-+ connect(model, &QAbstractItemModel::rowsInserted, this, &IMTab::updateScrollBar);
- }
-
- ///Scroll to last message
-@@ -86,3 +95,13 @@ void IMTab::scrollBottom()
- {
- scrollTo(model()->index(model()->rowCount()-1,0));
- }
-+
-+void IMTab::updateScrollBar()
-+{
-+ if (verticalScrollBar() && verticalScrollBar()->value()
-+ == verticalScrollBar()->maximum()) {
-+ QTimer::singleShot(0,[this]() {
-+ verticalScrollBar()->setValue(verticalScrollBar()->maximum());
-+ });
-+ }
-+}
-diff --git a/src/delegates/imdelegate.h b/src/delegates/imdelegate.h
-index d809e67..4692de8 100644
---- a/src/delegates/imdelegate.h
-+++ b/src/delegates/imdelegate.h
-@@ -22,7 +22,7 @@
- #include <QtWidgets/QListView>
- #include <QtWidgets/QStyledItemDelegate>
-
--class QAbstractListModel;
-+class QAbstractItemModel;
- class IMTab;
-
- class ImDelegates : public QStyledItemDelegate
-@@ -41,9 +41,10 @@ class IMTab : public QListView
- {
- Q_OBJECT
- public:
-- explicit IMTab(QAbstractListModel* model,QWidget* parent = nullptr);
-+ explicit IMTab(QAbstractItemModel* model,QWidget* parent = nullptr);
- private Q_SLOTS:
- void scrollBottom();
-+ void updateScrollBar();
- };
-
- #endif // IM_MANAGER
-diff --git a/src/eventmanager.cpp b/src/eventmanager.cpp
-index 39bb3be..7e22c4d 100644
---- a/src/eventmanager.cpp
-+++ b/src/eventmanager.cpp
-@@ -47,6 +47,8 @@
- #include "widgets/callviewoverlay.h"
- #include "widgets/autocompletion.h"
-
-+bool EventManager::m_HasFocus = false;
-+
- //This code detect if the window is active, innactive or minimzed
- class MainWindowEvent : public QObject {
- Q_OBJECT
-@@ -57,13 +59,7 @@ public:
- protected:
- virtual bool eventFilter(QObject *obj, QEvent *event) override {
- Q_UNUSED(obj)
-- if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {
-- QFocusEvent* e = static_cast<QFocusEvent*>(event);
-- if (e->reason() == Qt::ActiveWindowFocusReason) {
-- qDebug() << "ACTIVE WINDOW EVENT";
-- }
-- }
-- else if (event->type() == QEvent::WindowStateChange) {
-+ if (event->type() == QEvent::WindowStateChange) {
- QWindowStateChangeEvent* e = static_cast<QWindowStateChangeEvent*>(event);
- switch (MainWindow::app()->windowState()) {
- case Qt::WindowMinimized:
-@@ -81,6 +77,12 @@ protected:
- else if (event->type() == QEvent::KeyPress) {
- m_pParent->viewKeyEvent(static_cast<QKeyEvent*>(event));
- }
-+ else if (event->type() == QEvent::WindowDeactivate) {
-+ m_pParent->m_HasFocus = false;
-+ }
-+ else if (event->type() == QEvent::WindowActivate) {
-+ m_pParent->m_HasFocus = true;
-+ }
- return false;
- }
-
-@@ -495,7 +497,7 @@ void EventManager::enter()
- ///Macros needs to be executed at high level so the animations kicks in
- void EventManager::addDTMF(const QString& sequence)
- {
-- if (sequence == "\n")
-+ if (sequence == QLatin1String("\n"))
- enter();
- else
- typeString(sequence);
-@@ -613,4 +615,9 @@ void EventManager::slotNetworkDown()
- m_pParent->m_pCanvasManager->newEvent(CanvasObjectManager::CanvasEvent::NETWORK_ERROR);
- }
-
-+bool EventManager::mayHaveFocus()
-+{
-+ return m_HasFocus;
-+}
-+
- #include "eventmanager.moc"
-diff --git a/src/eventmanager.h b/src/eventmanager.h
-index 3d8febd..22e9202 100644
---- a/src/eventmanager.h
-+++ b/src/eventmanager.h
-@@ -56,14 +56,21 @@ public:
- //Implement macro key listener
- virtual void addDTMF(const QString& sequence) override;
-
-+ /**
-+ * An unreliable way to track the application focus
-+ *
-+ * It is better than nothing
-+ */
-+ static bool mayHaveFocus();
-
- protected:
- virtual bool eventFilter(QObject *obj, QEvent *event) override;
-
- private:
- //Attributes
-- View* m_pParent ;
-- MainWindowEvent* m_pMainWindowEv ;
-+ View* m_pParent ;
-+ MainWindowEvent* m_pMainWindowEv ;
-+ static bool m_HasFocus ;
-
- //Methods
- bool viewKeyEvent ( QKeyEvent* e);
-diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
-index 0f430fb..d8f3993 100755
---- a/src/mainwindow.cpp
-+++ b/src/mainwindow.cpp
-@@ -94,9 +94,6 @@ MainWindow* MainWindow::m_sApp = nullptr;
-
- static void loadNumberCategories()
- {
--// QList<int> list = ConfigurationSkeleton::phoneTypeList();
--// const bool isEmpty = !list.size();
--// #define IS_ENABLED(name) (list.indexOf(name) != -1) || isEmpty
- auto& model = NumberCategoryModel::instance();
- #define ICN(name) QPixmap(QString(":/mini/icons/miniicons/%1.png").arg(name))
- model.addCategory(i18n("Home") ,ICN("home") , 1 /*KABC::PhoneNumber::Home */);
-diff --git a/src/notification.cpp b/src/notification.cpp
-new file mode 100644
-index 0000000..5e4e2f4
---- /dev/null
-+++ b/src/notification.cpp
-@@ -0,0 +1,261 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#include "notification.h"
-+
-+
-+// Qt
-+#include <QtWidgets/QApplication>
-+
-+// KDE
-+#include <KNotification>
-+#include <KLocalizedString>
-+
-+// LRC
-+#include <callmodel.h>
-+#include <accountmodel.h>
-+#include <call.h>
-+#include <person.h>
-+#include <contactmethod.h>
-+#include <numbercategory.h>
-+#include <useractionmodel.h>
-+#include <media/textrecording.h>
-+#include <media/recordingmodel.h>
-+
-+// Ring-KDE
-+#include <mainwindow.h>
-+#include <view.h>
-+#include <eventmanager.h>
-+
-+#define REGISTER_ACTION(list, var, name) list << name;var = list.size();
-+
-+
-+/*
-+ * IncomingCallNotification
-+ */
-+
-+class IncomingCallNotification : public KNotification
-+{
-+ Q_OBJECT
-+
-+public:
-+ explicit IncomingCallNotification(Call* c);
-+
-+private:
-+ uint m_Answer {99};
-+ uint m_AnswerVideo {99};
-+ uint m_HangUp {99};
-+
-+ Call* m_pCall;
-+
-+private Q_SLOTS:
-+ void stateChanged(Call::LifeCycleState newState, Call::LifeCycleState previousState);
-+ void actionPerformed(uint actionId);
-+};
-+
-+IncomingCallNotification::IncomingCallNotification(Call* call) : KNotification(
-+ QStringLiteral("incomingCall"), MainWindow::view(), NotificationFlag::Persistent ),
-+ m_pCall(call)
-+{
-+
-+ const Person* contact = call->peerContactMethod()->contact();
-+ if (contact) {
-+
-+ const QPixmap px = (contact->photo()).type() == QVariant::Pixmap ? (contact->photo()).value<QPixmap>():QPixmap();
-+ setPixmap(px);
-+ }
-+
-+ setTitle(i18n("New incoming call"));
-+
-+ setText(i18n("New call from <b>%1</b>\n<i>(%2)</i>"
-+ ,call->formattedName()
-+ ,call->peerContactMethod()->uri()
-+ ));
-+
-+ QStringList actions;
-+
-+ REGISTER_ACTION(actions, m_Answer, i18n( "Answer" ))
-+ REGISTER_ACTION(actions, m_HangUp, i18n( "Hang up" ))
-+
-+ //TODO support answer without video
-+
-+ setActions(actions);
-+
-+ addContext(QStringLiteral("contact"), call->peerContactMethod()->category()->name());
-+
-+ connect(call, &Call::lifeCycleStateChanged, this, &IncomingCallNotification::stateChanged);
-+
-+ connect(this, SIGNAL(activated(uint)), this , SLOT(actionPerformed(uint)));
-+}
-+
-+void IncomingCallNotification::stateChanged(Call::LifeCycleState newState, Call::LifeCycleState previousState)
-+{
-+ Q_UNUSED(previousState)
-+
-+ if (newState != Call::LifeCycleState::INITIALIZATION) {
-+
-+ close();
-+
-+ deleteLater();
-+ }
-+}
-+
-+void IncomingCallNotification::actionPerformed(uint actionId)
-+{
-+ if (actionId == m_Answer) {
-+ m_pCall << Call::Action::ACCEPT;
-+ }
-+ else if (actionId == m_HangUp) {
-+ m_pCall << Call::Action::REFUSE;
-+ }
-+}
-+
-+
-+/*
-+ * Text message notification
-+ */
-+class IncomingTextNotification : public KNotification
-+{
-+ Q_OBJECT
-+public:
-+ explicit IncomingTextNotification(ContactMethod* cm, Media::TextRecording* t);
-+ void actionPerformed(uint actionId);
-+};
-+
-+IncomingTextNotification::IncomingTextNotification(ContactMethod* cm, Media::TextRecording* t) : KNotification(
-+ QStringLiteral("incomingText"), MainWindow::view())
-+{
-+ setTitle(i18n("Message from %1", cm->primaryName()));
-+
-+ if (auto contact = cm->contact()) {
-+
-+ const QPixmap px = (contact->photo()).type() == QVariant::Pixmap ? (contact->photo()).value<QPixmap>():QPixmap();
-+ setPixmap(px);
-+ }
-+
-+ setText(t->instantTextMessagingModel()->index(
-+ t->instantTextMessagingModel()->rowCount()-1, 0
-+ ).data().toString());
-+}
-+
-+void IncomingTextNotification::actionPerformed(uint actionId)
-+{
-+ Q_UNUSED(actionId)
-+}
-+
-+/*
-+ * CreateContactNotification
-+ */
-+
-+class CreateContactNotification : public KNotification
-+{
-+ Q_OBJECT
-+
-+public:
-+ explicit CreateContactNotification(ContactMethod* cm);
-+
-+private:
-+ uint m_Yes {99};
-+ uint m_No {99};
-+ uint m_Never {99};
-+
-+private Q_SLOTS:
-+ void actionPerformed(uint actionId);
-+};
-+
-+CreateContactNotification::CreateContactNotification(ContactMethod* cm) :KNotification(
-+ QStringLiteral("incomingCall"), MainWindow::view())
-+{
-+ setTitle(i18n("Add %1 to contacts?", cm->uri()));
-+
-+ setText(i18n("Do you wish to add %1 to your addressbook?", cm->primaryName()));
-+
-+ QStringList actions;
-+
-+ REGISTER_ACTION(actions, m_Yes , i18n( "Yes" ))
-+ REGISTER_ACTION(actions, m_No , i18n( "No" ))
-+ REGISTER_ACTION(actions, m_Never, i18n( "Do not ask again" ))
-+
-+ setActions(actions);
-+
-+ connect(this, SIGNAL(activated(uint)), this , SLOT(actionPerformed(uint)));
-+}
-+
-+void CreateContactNotification::actionPerformed(uint actionId)
-+{
-+ if (actionId == m_Yes) {
-+ //TODO do something
-+ }
-+ else if (actionId == m_No) {
-+ //Nothing to do
-+ }
-+ else if (actionId == m_Never) {
-+ //TODO edit the config to disable this notification
-+ }
-+
-+ deleteLater();
-+}
-+
-+
-+
-+
-+Notification::Notification(QObject* parent) : QObject(parent)
-+{
-+ connect(&CallModel::instance(), &CallModel::incomingCall, this, &Notification::incomingCall);
-+ connect(&AccountModel::instance(), &AccountModel::accountStateChanged, this, &Notification::accountStatus);
-+ connect(&Media::RecordingModel::instance(), &Media::RecordingModel::newTextMessage, this, &Notification::incomingText);
-+}
-+
-+Notification* Notification::instance()
-+{
-+ static auto i = new Notification(QApplication::instance());
-+
-+ return i;
-+}
-+
-+void Notification::contactOnline()
-+{
-+ //TODO fix the presence model
-+}
-+
-+void Notification::accountStatus(Account* a, const Account::RegistrationState state)
-+{
-+ Q_UNUSED(a)
-+ Q_UNUSED(state)
-+ //TODO
-+}
-+
-+void Notification::incomingCall(Call* call)
-+{
-+ if (call)
-+ (new IncomingCallNotification(call))->sendEvent();
-+}
-+
-+void Notification::incomingText(Media::TextRecording* t, ContactMethod* cm)
-+{
-+ if (t && !EventManager::mayHaveFocus())
-+ (new IncomingTextNotification(cm, t))->sendEvent();
-+}
-+
-+void Notification::createContact()
-+{
-+ //TODO
-+}
-+
-+#undef REGISTER_ACTION
-+
-+#include <notification.moc>
-diff --git a/src/notification.h b/src/notification.h
-new file mode 100644
-index 0000000..73d2d34
---- /dev/null
-+++ b/src/notification.h
-@@ -0,0 +1,56 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#ifndef NOTIFICATION_H
-+#define NOTIFICATION_H
-+
-+#include <QtCore/QObject>
-+
-+#include <account.h>
-+class Call;
-+class ContactMethod;
-+namespace Media {
-+ class TextRecording;
-+}
-+
-+/**
-+ * This singleton class watch and reatch on events to provide system
-+ * notifications.
-+ */
-+class Notification : public QObject
-+{
-+ Q_OBJECT
-+
-+public:
-+ explicit Notification(QObject* parent = nullptr);
-+
-+ void contactOnline();
-+
-+ void accountStatus(Account* a, const Account::RegistrationState state);
-+
-+
-+ void incomingText(Media::TextRecording* t, ContactMethod* cm);
-+
-+ void createContact();
-+
-+ static Notification* instance();
-+
-+private Q_SLOTS:
-+ void incomingCall(Call* c);
-+};
-+
-+#endif
-\ No newline at end of file
-diff --git a/src/view.cpp b/src/view.cpp
-index 1188887..31ab04d 100644
---- a/src/view.cpp
-+++ b/src/view.cpp
-@@ -58,6 +58,30 @@
- #include <tip/tipmanager.h>
- #include "implementation.h"
-
-+class FocusWatcher : public QObject
-+{
-+ Q_OBJECT
-+public:
-+ explicit FocusWatcher(QObject* parent = nullptr) : QObject(parent)
-+ {
-+ if (parent)
-+ parent->installEventFilter(this);
-+ }
-+ virtual bool eventFilter(QObject *obj, QEvent *event) override
-+ {
-+ Q_UNUSED(obj)
-+ if (event->type() == QEvent::FocusIn)
-+ emit focusChanged(true);
-+ else if (event->type() == QEvent::FocusOut)
-+ emit focusChanged(false);
-+
-+ return false;
-+ }
-+
-+Q_SIGNALS:
-+ void focusChanged(bool in);
-+};
-+
- ///Constructor
- View::View(QWidget *parent)
- : QWidget(parent),m_pTransferOverlay(nullptr),m_pAutoCompletion(nullptr)
-@@ -80,7 +104,9 @@ View::View(QWidget *parent)
-
- //Create a call already, the app is useless without one anyway
- m_pView->selectionModel()->setCurrentIndex(
-- CallModel::instance().getIndex(CallModel::instance().dialingCall()),
-+ CallModel::instance().rowCount() ?
-+ CallModel::instance().index(0, 0)
-+ : CallModel::instance().getIndex(CallModel::instance().dialingCall()),
- QItemSelectionModel::SelectCurrent
- );
-
-@@ -107,7 +133,13 @@ View::View(QWidget *parent)
-
- GlobalInstances::setInterface<ColorDelegate>(pal);
-
-- m_pMessageBoxW->setVisible(false);
-+ const QModelIndex currentIndex = CallModel::instance().selectionModel()->currentIndex();
-+
-+ m_pMessageBoxW->setVisible(
-+ qvariant_cast<Call::LifeCycleState>(currentIndex.data((int)Call::Role::LifeCycleState))
-+ == Call::LifeCycleState::PROGRESS
-+ );
-+ connect(new FocusWatcher(m_pSendMessageLE), &FocusWatcher::focusChanged, this, &View::displayHistory);
-
- //Setup volume
- toolButton_recVol->setDefaultAction(ActionCollection::instance()->muteCaptureAction ());
-@@ -125,6 +157,8 @@ View::View(QWidget *parent)
- /**/connect(widget_dialpad , &Dialpad::typed , m_pEventManager, &EventManager::typeString );
- /* */
-
-+ connect(m_pView->selectionModel(), &QItemSelectionModel::currentChanged, this, &View::updateTextBoxStatus);
-+
- //Auto completion
- loadAutoCompletion();
-
-@@ -137,7 +171,6 @@ View::View(QWidget *parent)
-
- setFocus(Qt::OtherFocusReason);
-
-- loadAutoCompletion ();
- widget_dialpad->setVisible(ConfigurationSkeleton::displayDialpad());
- Audio::Settings::instance().setEnableRoomTone(ConfigurationSkeleton::enableRoomTone());
- }
-@@ -278,4 +311,29 @@ void View::slotAutoCompleteClicked(ContactMethod* n) //TODO use the new LRC API
- }
- }
-
-+void View::updateTextBoxStatus()
-+{
-+ static bool display = ConfigurationSkeleton::displayMessageBox();
-+ if (display) {
-+ Call* call = CallModel::instance().selectedCall();
-+ m_pMessageBoxW->setVisible(call
-+ && (call->lifeCycleState() == Call::LifeCycleState::PROGRESS)
-+ );
-+ }
-+}
-+
-+void View::displayHistory(bool in)
-+{
-+ if (!in)
-+ return;
-+
-+ Call* call = CallModel::instance().selectedCall();
-+
-+ if (call->lifeCycleState() == Call::LifeCycleState::PROGRESS) {
-+ m_pMessageTabBox->showConversation(call->peerContactMethod());
-+ }
-+
-+ m_pMessageTabBox->clearColor();
-+
-+}
- #include "view.moc"
-diff --git a/src/view.h b/src/view.h
-index d67f63b..f61c3fa 100644
---- a/src/view.h
-+++ b/src/view.h
-@@ -77,6 +77,8 @@ private Q_SLOTS:
- void sendMessage ();
- void slotAutoCompleteClicked(ContactMethod* n);
- void loadAutoCompletion ();
-+ void updateTextBoxStatus ();
-+ void displayHistory (bool);
-
- public Q_SLOTS:
- void updateVolumeControls ();
-diff --git a/src/widgets/immanager.cpp b/src/widgets/immanager.cpp
-index 4afd45a..d486fbd 100644
---- a/src/widgets/immanager.cpp
-+++ b/src/widgets/immanager.cpp
-@@ -19,37 +19,139 @@
- #include "call.h"
- #include "callmodel.h"
- #include "contactmethod.h"
-+#include "person.h"
- #include <media/text.h>
- #include <media/textrecording.h>
-+#include <media/recordingmodel.h>
- #include "../delegates/imdelegate.h"
-+#include <eventmanager.h>
-+
-+//KDE
-+#include <KColorScheme>
- #include <klocalizedstring.h>
-
-+// Qt
-+#include <QtWidgets/QScrollBar>
-+#include <QtGui/QPixmap>
-+#include <QtCore/QTimer>
-+
- ///Constructor
- IMManager::IMManager(QWidget* parent) : QTabWidget(parent)
- {
- setVisible(false);
- setTabsClosable(true);
-
-- connect(&CallModel::instance(), &CallModel::mediaAdded,[this](Call* c, Media::Media* m) {
-- if (m->type() == Media::Media::Type::TEXT) {
-+ connect(&CallModel::instance(), &CallModel::mediaAdded, this, &IMManager::addMedia);
-
-- Media::Text* media = static_cast<Media::Text*>(m);
-+ connect(this,SIGNAL(tabCloseRequested(int)),this,SLOT(closeRequest(int)));
-
-- newConversation(c->peerContactMethod(),media->recording()->instantMessagingModel());
-- }
-- });
-+ connect(&Media::RecordingModel::instance(), &Media::RecordingModel::newTextMessage, this, &IMManager::newMessageInserted);
-+
-+ foreach(Call* c, CallModel::instance().getActiveCalls()) {
-+ if (c->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::IN))
-+ addMedia(c, c->firstMedia<Media::Text>(Media::Media::Direction::IN));
-+ else if (c->hasMedia(Media::Media::Type::TEXT, Media::Media::Direction::OUT))
-+ addMedia(c, c->firstMedia<Media::Text>(Media::Media::Direction::OUT));
-+ }
-+
-+ connect(this, &IMManager::currentChanged, this, &IMManager::clearColor);
-+}
-+
-+void IMManager::newMessageInserted(Media::TextRecording* r, ContactMethod* cm)
-+{
-+ if (!r->instantMessagingModel()->index(
-+ r->instantMessagingModel()->rowCount()-1, 0
-+ ).data((int)Media::TextRecording::Role::HasText).toBool()
-+ )
-+ return;
-+
-+ IMTab* tab = nullptr;
-+
-+ if (!(tab = m_lTabs[cm]))
-+ tab = newConversation(cm, r->instantTextMessagingModel());
-+
-+ if (currentWidget() != tab
-+ || (!EventManager::mayHaveFocus())
-+ || tab->verticalScrollBar()->value() != tab->verticalScrollBar()->maximum()) {
-+ static QColor awayBrush = KStatefulBrush( KColorScheme::Window, KColorScheme::NegativeText ).brush(QPalette::Normal).color();
-+
-+ tabBar()->setTabTextColor(indexOf(tab), awayBrush);
-+ }
-
-- connect(this,SIGNAL(tabCloseRequested(int)),this,SLOT(closeRequest(int)));
-+}
-+
-+void IMManager::addMedia(Call* c, Media::Media* m)
-+{
-+ if (m->type() == Media::Media::Type::TEXT) {
-+
-+ Media::Text* media = static_cast<Media::Text*>(m);
-+
-+ bool isRelevant = media->hasMimeType(QStringLiteral("text/plain"))
-+ || media->hasMimeType(QStringLiteral("text/html"));
-+
-+ auto cm = c->peerContactMethod();
-+
-+ if (!isRelevant) {
-+ connect(media, &Media::Text::mimeTypesChanged, [this, media, cm]() {
-+ bool isRelevant = media->hasMimeType(QStringLiteral("text/plain"))
-+ || media->hasMimeType(QStringLiteral("text/html"));
-+
-+ if (isRelevant)
-+ newConversation(cm, media->recording()->instantTextMessagingModel());
-+
-+ });
-+ }
-+ }
- }
-
- ///Destructor
--void IMManager::newConversation(ContactMethod* cm, QAbstractListModel* model)
-+IMTab* IMManager::newConversation(ContactMethod* cm, QAbstractItemModel* model)
- {
-+ if (auto tab = m_lTabs[cm]) {
-+ setCurrentWidget(m_lTabs[cm]);
-+ setVisible(true);
-+ return tab;
-+ }
-+
- IMTab* newTab = new IMTab(model,this);
- m_lTabs[cm] = newTab;
- setVisible(true);
- const QString name = cm->primaryName();
-- addTab(newTab,name);
-+
-+ if (cm->contact())
-+ setCurrentIndex(addTab(newTab,qvariant_cast<QPixmap>(cm->contact()->photo()), name));
-+ else
-+ setCurrentIndex(addTab(newTab,name));
-+
-+
-+ // If the IMManager widget is not in the view yet, the scrollbar will be wrong
-+ QTimer::singleShot(0,[this, model, newTab] {
-+ newTab->scrollTo(model->index(model->rowCount()-1,0));
-+
-+ if (newTab->verticalScrollBar())
-+ newTab->verticalScrollBar()->setValue(newTab->verticalScrollBar()->maximum());
-+ });
-+
-+ return newTab;
-+}
-+
-+///Display a conversation from history
-+bool IMManager::showConversation(ContactMethod* cm)
-+{
-+ if (!cm)
-+ return false;
-+
-+ auto textRec = cm->textRecording();
-+
-+ if (!textRec)
-+ return false;
-+
-+ QAbstractItemModel* model = textRec->instantTextMessagingModel();
-+
-+ if (model->rowCount())
-+ newConversation(cm, model);
-+
-+ return true;
- }
-
- ///Close a tab
-@@ -64,3 +166,12 @@ void IMManager::closeRequest(int index)
- setVisible(false);
- }
- }
-+
-+void IMManager::clearColor(int idx)
-+{
-+ if (idx == -1)
-+ for(int i =0; i < count(); i++)
-+ clearColor(i);
-+ else
-+ tabBar()->setTabTextColor(idx, QColor());
-+}
-diff --git a/src/widgets/immanager.h b/src/widgets/immanager.h
-index 37e7c7a..21476df 100644
---- a/src/widgets/immanager.h
-+++ b/src/widgets/immanager.h
-@@ -20,7 +20,7 @@
-
- //Qt
- #include <QtCore/QHash>
--class QAbstractListModel;
-+class QAbstractItemModel;
-
- //KDE
- #include <QtWidgets/QTabWidget>
-@@ -28,6 +28,11 @@ class QAbstractListModel;
- //Ring
- class IMTab;
- class ContactMethod;
-+class Call;
-+namespace Media {
-+ class Media;
-+ class TextRecording;
-+}
-
- class IMManager : public QTabWidget
- {
-@@ -40,9 +45,15 @@ private:
- //Attrubutes
- QHash<ContactMethod*,IMTab*> m_lTabs;
-
-+public Q_SLOTS:
-+ void clearColor(int idx = -1);
-+ bool showConversation(ContactMethod* cm);
-+
- private Q_SLOTS:
-- void newConversation(ContactMethod* cm, QAbstractListModel* model);
-+ IMTab* newConversation(ContactMethod* cm, QAbstractItemModel* model);
- void closeRequest(int index);
-+ void addMedia(Call* c, Media::Media* m);
-+ void newMessageInserted(Media::TextRecording* r, ContactMethod* cm);
- };
-
- #endif // IM_MANAGER
---
-2.7.0
-
diff --git a/0002-contact-Enable-Akonadi-support-again.patch b/0002-contact-Enable-Akonadi-support-again.patch
deleted file mode 100644
index 72b0f5a0949c..000000000000
--- a/0002-contact-Enable-Akonadi-support-again.patch
+++ /dev/null
@@ -1,1565 +0,0 @@
-From 21755b923acdcfaac8130c52b204cb46d49f5bb5 Mon Sep 17 00:00:00 2001
-From: Emmanuel Lepage Vallee <elv1313@gmail.com>
-Date: Wed, 16 Dec 2015 23:32:26 -0500
-Subject: [PATCH 2/6] contact: Enable Akonadi support again
-
-Most features from the previous releases seem to work again
-with the KF5 version of Akonadi.
----
- src/conf/dlgdisplay.cpp | 6 +
- src/conf/dlgdisplaybase.ui | 10 +
- src/dock.cpp | 189 ++++++++---
- src/klib/CMakeLists.txt | 14 +
- src/klib/akonadibackend.cpp | 492 ++++++++++++++++-------------
- src/klib/akonadibackend.h | 145 +++------
- src/klib/akonadicontactcollectionmodel.cpp | 141 ---------
- src/klib/akonadicontactcollectionmodel.h | 70 ----
- src/klib/itemmodelserialization.cpp | 17 +
- src/klib/itemmodelserialization.h | 6 +-
- src/klib/ring-kde.kcfg | 6 +
- src/mainwindow.cpp | 5 +-
- 12 files changed, 514 insertions(+), 587 deletions(-)
- delete mode 100644 src/klib/akonadicontactcollectionmodel.cpp
- delete mode 100644 src/klib/akonadicontactcollectionmodel.h
-
-diff --git a/src/conf/dlgdisplay.cpp b/src/conf/dlgdisplay.cpp
-index 32fac93..c83d43f 100644
---- a/src/conf/dlgdisplay.cpp
-+++ b/src/conf/dlgdisplay.cpp
-@@ -24,6 +24,9 @@
- #include <KConfigDialog>
- #include <klocalizedstring.h>
-
-+//LRC
-+#include <categorizedcontactmodel.h>
-+
- //Ring
- #include "mainwindow.h"
-
-@@ -97,6 +100,9 @@ void DlgDisplay::updateSettings()
- ConfigurationSkeleton::setAutoStartOverride(true);
- }
-
-+ if (ConfigurationSkeleton::hideUnreachable() != kcfg_hideUnreachable->isChecked())
-+ CategorizedContactModel::instance().setUnreachableHidden(kcfg_hideUnreachable->isChecked());
-+
- MainWindow::app()->setAutoStart(kcfg_autoStart->isChecked());
-
- m_HasChanged = false;
-diff --git a/src/conf/dlgdisplaybase.ui b/src/conf/dlgdisplaybase.ui
-index b7e424a..cea3098 100644
---- a/src/conf/dlgdisplaybase.ui
-+++ b/src/conf/dlgdisplaybase.ui
-@@ -102,6 +102,16 @@
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
-+ <widget class="QCheckBox" name="kcfg_hideUnreachable">
-+ <property name="toolTip">
-+ <string>Hide a contact when there is no enabled account that can reach him/her</string>
-+ </property>
-+ <property name="text">
-+ <string>Hide unreachable contacts</string>
-+ </property>
-+ </widget>
-+ </item>
-+ <item>
- <widget class="QCheckBox" name="kcfg_hidePersonWithoutPhone">
- <property name="text">
- <string>Hide contacts without phone numbers</string>
-diff --git a/src/dock.cpp b/src/dock.cpp
-index 91ba8e2..4b1f88e 100644
---- a/src/dock.cpp
-+++ b/src/dock.cpp
-@@ -21,6 +21,10 @@
- //Qt
- #include <QtWidgets/QMainWindow>
- #include <QtCore/QSortFilterProxyModel>
-+#include <QtCore/QTimer>
-+
-+//KDE
-+#include <KColorScheme>
-
- //Delegates
- #include <conf/account/delegates/categorizeddelegate.h>
-@@ -28,11 +32,6 @@
- #include "delegates/phonenumberdelegate.h"
- #include "delegates/historydelegate.h"
-
--//Menu
--#include "menu/person.h"
--#include "menu/call.h"
--#include "menu/contactmethod.h"
--
- //Widgets
- #include "widgets/dockbase.h"
-
-@@ -43,8 +42,11 @@
-
- //Ring
- #include "mainwindow.h"
-+#include "view.h"
- #include "actioncollection.h"
- #include "klib/kcfg_settings.h"
-+#include <proxies/deduplicateproxy.h>
-+#include <proxies/roletransformationproxy.h>
-
- class BookmarkSortFilterProxyModel : public QSortFilterProxyModel
- {
-@@ -76,7 +78,7 @@ protected:
- Dock::Dock(QMainWindow* w) : QObject(w)
- {
- //Contact dock
-- m_pContactCD = new DockBase ( w );
-+ m_pContactCD = new DockBase ( nullptr );
- m_pContactCD->setObjectName("contactDock");
- m_pContactCD->setWindowTitle(i18nc("Contact tab","Contact"));
- auto m_pCategoryDelegate = new CategorizedDelegate(m_pContactCD->view());
-@@ -88,65 +90,112 @@ Dock::Dock(QMainWindow* w) : QObject(w)
- m_pCategoryDelegate->setChildChildDelegate(m_pContactMethodDelegate);
- m_pContactCD->setDelegate(m_pCategoryDelegate);
-
-- CategorizedContactModel::instance().setUnreachableHidden(ConfigurationSkeleton::hidePersonWithoutPhone());
-- QSortFilterProxyModel* proxy = CategorizedContactModel::SortedProxy::instance().model();
-- m_pContactCD->setProxyModel(proxy);
-- m_pContactCD->setSortingModel(
-- CategorizedContactModel::SortedProxy::instance().categoryModel(),
-- CategorizedContactModel::SortedProxy::instance().categorySelectionModel()
-- );
--
-- CategorizedContactModel::SortedProxy::instance().categorySelectionModel()->setCurrentIndex(
-- CategorizedContactModel::SortedProxy::instance().categoryModel()->index(
-- ConfigurationSkeleton::contactSortMode() , 0
-- ), QItemSelectionModel::ClearAndSelect
-- );
--
-- connect(CategorizedContactModel::SortedProxy::instance().categorySelectionModel(), & QItemSelectionModel::currentChanged,[](const QModelIndex& idx) {
-- if (idx.isValid())
-- ConfigurationSkeleton::setContactSortMode(idx.row());
-- });
--
-- m_pContactCD->setMenuConstructor([]() {
-- return new Menu::Person();
-+ // Load later to speed up the process (avoid showing while inserting items)
-+ QTimer::singleShot(10, [this]() {
-+ CategorizedContactModel::instance().setUnreachableHidden(ConfigurationSkeleton::hideUnreachable());
-+ auto proxy = CategorizedContactModel::SortedProxy::instance().model();
-+ m_pContactCD->setProxyModel(proxy, proxy);
-+ m_pContactCD->setSortingModel(
-+ CategorizedContactModel::SortedProxy::instance().categoryModel(),
-+ CategorizedContactModel::SortedProxy::instance().categorySelectionModel()
-+ );
-+
-+ CategorizedContactModel::SortedProxy::instance().categorySelectionModel()->setCurrentIndex(
-+ CategorizedContactModel::SortedProxy::instance().categoryModel()->index(
-+ ConfigurationSkeleton::contactSortMode() , 0
-+ ), QItemSelectionModel::ClearAndSelect
-+ );
-+
-+ connect(CategorizedContactModel::SortedProxy::instance().categorySelectionModel(), & QItemSelectionModel::currentChanged,[](const QModelIndex& idx) {
-+ if (idx.isValid())
-+ ConfigurationSkeleton::setContactSortMode(idx.row());
-+ });
- });
-
- //History dock
-- m_pHistoryDW = new DockBase ( w );
-+ m_pHistoryDW = new DockBase ( nullptr );
- m_pHistoryDW->setObjectName("historyDock");
- m_pHistoryDW->setWindowTitle(i18nc("History tab","History"));
- CategorizedDelegate* delegate = new CategorizedDelegate(m_pHistoryDW->view());
- delegate->setChildDelegate(new HistoryDelegate(m_pHistoryDW->view()));
- m_pHistoryDW->setDelegate(delegate);
-- m_pHistoryDW->setMenuConstructor([]() {
-- return new Menu::Call();
-- });
-- proxy = CategorizedHistoryModel::SortedProxy::instance().model();
-- m_pHistoryDW->setProxyModel(proxy);
-- m_pHistoryDW->setSortingModel(
-- CategorizedHistoryModel::SortedProxy::instance().categoryModel (),
-- CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel()
-- );
--
-- CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel()->setCurrentIndex(
-- CategorizedHistoryModel::SortedProxy::instance().categoryModel()->index(
-- ConfigurationSkeleton::historySortMode() , 0
-- ), QItemSelectionModel::ClearAndSelect
-- );
--
-- connect(CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel(), & QItemSelectionModel::currentChanged,[](const QModelIndex& idx) {
-- if (idx.isValid())
-- ConfigurationSkeleton::setHistorySortMode(idx.row());
-+
-+
-+ QTimer::singleShot(1000, [this]() {
-+ // De-duplicate by name and date
-+ auto proxy = CategorizedHistoryModel::SortedProxy::instance().model();
-+ RoleTransformationProxy* highlight = nullptr;
-+ auto dedup = ConfigurationSkeleton::mergeSameDayPeer() ? new DeduplicateProxy(proxy) : nullptr;
-+
-+ if (dedup)
-+ dedup->addFilterRole(static_cast<int>(Call::Role::DateOnly));
-+
-+ // Highlight missed calls
-+ static const bool highlightMissedIn = ConfigurationSkeleton::highlightMissedIncomingCalls();
-+ static const bool highlightMissedOut = ConfigurationSkeleton::highlightMissedOutgoingCalls();
-+
-+ if (highlightMissedOut || highlightMissedIn) {
-+ static QColor awayBrush = KStatefulBrush( KColorScheme::Window, KColorScheme::NegativeText ).brush(QPalette::Normal).color();
-+ awayBrush.setAlpha(30);
-+ static QVariant missedBg(awayBrush);
-+
-+ highlight = new RoleTransformationProxy(dedup ? dedup : proxy);
-+
-+ highlight->setRole(Qt::BackgroundRole, [](const QModelIndex& idx) {
-+ if (idx.data((int)Call::Role::Missed).toBool()) {
-+ const Call::Direction d = qvariant_cast<Call::Direction>(
-+ idx.data((int)Call::Role::Direction)
-+ );
-+
-+ if ((highlightMissedIn && d == Call::Direction::INCOMING)
-+ || (highlightMissedOut && d == Call::Direction::OUTGOING))
-+ return missedBg;
-+ }
-+
-+ return QVariant();
-+ });
-+
-+ highlight->setSourceModel(proxy);
-+
-+ if (dedup)
-+ dedup->setSourceModel(highlight);
-+ }
-+ else if (dedup)
-+ dedup->setSourceModel(proxy);
-+
-+ if (dedup)
-+ m_pHistoryDW->setProxyModel(dedup , proxy );
-+ else if (highlight)
-+ m_pHistoryDW->setProxyModel(highlight, proxy );
-+ else
-+ m_pHistoryDW->setProxyModel(proxy , proxy );
-+
-+ m_pHistoryDW->setSortingModel(
-+ CategorizedHistoryModel::SortedProxy::instance().categoryModel (),
-+ CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel()
-+ );
-+
-+ CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel()->setCurrentIndex(
-+ CategorizedHistoryModel::SortedProxy::instance().categoryModel()->index(
-+ ConfigurationSkeleton::historySortMode() , 0
-+ ), QItemSelectionModel::ClearAndSelect
-+ );
-+
-+ connect(CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel(), & QItemSelectionModel::currentChanged,[](const QModelIndex& idx) {
-+ if (idx.isValid())
-+ ConfigurationSkeleton::setHistorySortMode(idx.row());
-+ });
- });
-
- //Bookmark dock
-- m_pBookmarkDW = new DockBase ( w );
-+ m_pBookmarkDW = new DockBase ( nullptr );
- m_pBookmarkDW->setObjectName("bookmarkDock");
- m_pBookmarkDW->setWindowTitle(i18nc("Bookmark tab","Bookmark"));
- CategorizedDelegate* delegate2 = new CategorizedDelegate(m_pBookmarkDW->view());
- delegate2->setChildDelegate(new HistoryDelegate(m_pHistoryDW->view()));
- m_pBookmarkDW->setDelegate(delegate2);
-- m_pBookmarkDW->setProxyModel(new BookmarkSortFilterProxyModel(this));
-+ auto m = new BookmarkSortFilterProxyModel(this);
-+ m_pBookmarkDW->setProxyModel(m, m);
-
-
- //GUI
-@@ -178,6 +227,10 @@ Dock::Dock(QMainWindow* w) : QObject(w)
- connect(ActionCollection::instance()->showHistoryDockAction(), SIGNAL(toggled(bool)),m_pHistoryDW, SLOT(setVisible(bool)));
- connect(ActionCollection::instance()->showBookmarkDockAction(),SIGNAL(toggled(bool)),m_pBookmarkDW,SLOT(setVisible(bool)));
-
-+ connect( ActionCollection::instance()->focusHistory (), &QAction::triggered, this, &Dock::focusHistory );
-+ connect( ActionCollection::instance()->focusContact (), &QAction::triggered, this, &Dock::focusContact );
-+ connect( ActionCollection::instance()->focusCall (), &QAction::triggered, this, &Dock::focusCall );
-+ connect( ActionCollection::instance()->focusBookmark(), &QAction::triggered, this, &Dock::focusBookmark );
- }
-
- Dock::~Dock()
-@@ -185,9 +238,14 @@ Dock::~Dock()
- m_pContactCD ->setDelegate (nullptr);
- m_pHistoryDW ->setDelegate (nullptr);
- m_pBookmarkDW->setDelegate (nullptr);
-- m_pContactCD ->setProxyModel(nullptr);
-- m_pHistoryDW ->setProxyModel(nullptr);
-- m_pBookmarkDW->setProxyModel(nullptr);
-+
-+ m_pContactCD ->setProxyModel(nullptr, nullptr);
-+ m_pHistoryDW ->setProxyModel(nullptr, nullptr);
-+ m_pBookmarkDW->setProxyModel(nullptr, nullptr);
-+
-+ m_pContactCD ->deleteLater();
-+ m_pHistoryDW ->deleteLater();
-+ m_pBookmarkDW->deleteLater();
-
- if (!MainWindow::app()->isHidden()) {
- ConfigurationSkeleton::setDisplayContactDock ( m_pContactCD->isVisible() );
-@@ -240,4 +298,31 @@ void Dock::updateTabIcons()
- }
- } //updateTabIcons
-
-+void Dock::focusHistory()
-+{
-+ m_pHistoryDW->raise();
-+ ActionCollection::instance()->raiseClient(false);
-+ m_pHistoryDW->m_pFilterLE->setFocus(Qt::OtherFocusReason);
-+}
-+
-+void Dock::focusContact()
-+{
-+ m_pContactCD->raise();
-+ ActionCollection::instance()->raiseClient(false);
-+ m_pContactCD->m_pFilterLE->setFocus(Qt::OtherFocusReason);
-+}
-+
-+void Dock::focusCall()
-+{
-+ MainWindow::view()->raise();
-+ ActionCollection::instance()->raiseClient(true);
-+}
-+
-+void Dock::focusBookmark()
-+{
-+ m_pBookmarkDW->raise();
-+ ActionCollection::instance()->raiseClient(false);
-+ m_pBookmarkDW->m_pFilterLE->setFocus(Qt::OtherFocusReason);
-+}
-+
- #include <dock.moc>
-diff --git a/src/klib/CMakeLists.txt b/src/klib/CMakeLists.txt
-index a361d9d..be24937 100644
---- a/src/klib/CMakeLists.txt
-+++ b/src/klib/CMakeLists.txt
-@@ -28,6 +28,12 @@ FIND_PACKAGE(KF5 REQUIRED COMPONENTS
- XmlGui
- )
-
-+FIND_PACKAGE(KF5 COMPONENTS
-+ Akonadi
-+ AkonadiContact
-+ Contacts
-+)
-+
- INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES} ${Qt5Core_INCLUDES} ${LIB_RING_CLIENT_INCLUDE_DIR})
-
- ADD_DEFINITIONS(${Qt5Core_DEFINITIONS})
-@@ -45,6 +51,11 @@ SET( libkring_LIB_SRCS
- itemmodelserialization.cpp
- )
-
-+SET(libkring_LIB_SRCS
-+ ${libkring_LIB_SRCS}
-+ akonadibackend.cpp
-+)
-+
- KCONFIG_ADD_KCFG_FILES (libkring_LIB_SRCS kcfg_settings.kcfgc)
-
- ADD_LIBRARY( libkring STATIC ${libkring_LIB_SRCS} )
-@@ -58,6 +69,9 @@ target_link_libraries( libkring
- KF5::WidgetsAddons
- KF5::ConfigCore
- KF5::ConfigGui
-+ KF5::AkonadiCore
-+ KF5::AkonadiContact
-+ KF5::Contacts
- )
-
- SET( libkring_LIB_HDRS
-diff --git a/src/klib/akonadibackend.cpp b/src/klib/akonadibackend.cpp
-index 8afc1c4..be05b06 100644
---- a/src/klib/akonadibackend.cpp
-+++ b/src/klib/akonadibackend.cpp
-@@ -20,29 +20,33 @@
- #include "akonadibackend.h"
-
- //Qt
--#include <QPointer>
-+#include <QtCore/QPointer>
-+#include <QtWidgets/QVBoxLayout>
-+#include <QtWidgets/QDialog>
-+#include <QtWidgets/QDialogButtonBox>
-+#include <QtWidgets/QPushButton>
-
- //KDE
--#include <QDebug>
- #include <KJob>
--#include <QDialog>
--#include <akonadi/control.h>
--#include <akonadi/collectionfilterproxymodel.h>
--#include <akonadi/kmime/messagemodel.h>
--#include <akonadi/recursiveitemfetchjob.h>
--#include <akonadi/itemfetchjob.h>
--#include <akonadi/itemfetchscope.h>
--#include <akonadi/collectionfetchjob.h>
--#include <akonadi/collectionfetchscope.h>
--#include <akonadi/contact/contacteditor.h>
--#include <akonadi/contact/contacteditordialog.h>
--#include <akonadi/session.h>
--#include <akonadi/monitor.h>
--#include <akonadi/itemdeletejob.h>
--#include <akonadi/entitydisplayattribute.h>
--#include <kabc/addressee.h>
--#include <kabc/addresseelist.h>
--#include <kabc/contactgroup.h>
-+#include <AkonadiCore/Control>
-+#include <AkonadiCore/CollectionFilterProxyModel>
-+// #include <AkonadiCore/Kmime/MessageModel>
-+#include <AkonadiCore/RecursiveItemFetchJob>
-+#include <AkonadiCore/ItemFetchJob>
-+#include <AkonadiCore/ItemFetchScope>
-+#include <AkonadiCore/CollectionFetchJob>
-+#include <AkonadiCore/CollectionFetchScope>
-+#include <Akonadi/Contact/ContactEditor>
-+#include <Akonadi/Contact/ContactEditorDialog>
-+#include <AkonadiCore/Session>
-+#include <AkonadiCore/Monitor>
-+#include <AkonadiCore/ChangeRecorder>
-+#include <AkonadiCore/ItemDeleteJob>
-+#include <AkonadiCore/EntityDisplayAttribute>
-+#include <AkonadiCore/EntityTreeModel>
-+#include <kcontacts/addressee.h>
-+#include <kcontacts/addresseelist.h>
-+#include <kcontacts/contactgroup.h>
-
- //Ring library
- #include "person.h"
-@@ -56,12 +60,97 @@
- #include "collectioninterface.h"
- #include "numbercategory.h"
- #include "personmodel.h"
-+#include "interfaces/itemmodelstateserializeri.h"
-+#include "globalinstances.h"
-+
-+// Ring-KDE
- #include "kcfg_settings.h"
-
--Akonadi::Session* AkonadiBackend::m_pSession = nullptr;
-+Akonadi::Session* AkonadiBackend::m_spSession = nullptr;
-+Akonadi::EntityTreeModel* AkonadiBackend::m_spModel = nullptr;
- QHash<Akonadi::Collection::Id, AkonadiBackend*> AkonadiBackend::m_hParentLookup;
-
-+class AkonadiEditor : public CollectionEditor<Person>
-+{
-+public:
-+ AkonadiEditor(CollectionMediator<Person>* m) : CollectionEditor<Person>(m) {}
-+ ~AkonadiEditor() {
-+ m_lBackendPersons.clear();
-+ m_ItemHash.clear();
-+ m_AddrHash.clear();
-+ }
-+ virtual bool save ( const Person* item ) override;
-+ virtual bool addExisting( const Person* item ) override;
-+ virtual bool remove ( const Person* item ) override;
-+ virtual bool edit ( Person* item ) override;
-+ virtual bool addNew ( Person* item ) override;
-+
-+ QHash<QString,KContacts::Addressee> m_AddrHash ;
-+ QHash<QString,Akonadi::Item> m_ItemHash ;
-+ QVector<Person*> m_lBackendPersons;
-+private:
-+ virtual QVector<Person*> items() const override;
-+};
-+
-+void AkonadiBackend::digg(QAbstractItemModel* model, const QModelIndex& idx)
-+{
-+ if (!model)
-+ return;
-+
-+ if (idx.isValid()) {
-+ auto col = idx.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
-+
-+ if (col.isValid()) {
-+ auto col2 = PersonModel::instance().addCollection<AkonadiBackend,Akonadi::Collection*>(&col);
-+ if (col2 && col2->isEnabled())
-+ col2->load();
-+ }
-+ }
-+
-+ for (int i = 0;i < model->rowCount(idx);i++) {
-+ QModelIndex current = model->index(i,0,idx);
-+ digg(model, current);
-+ }
-+}
-+
-+void AkonadiBackend::slotRowsInserted(const QModelIndex& parent, int start, int end)
-+{
-+ for (int i = start; i <= end; i++) {
-+ digg(m_spModel, m_spModel->index(i,0, parent));
-+ }
-+}
-+
-+// Watch and digg the EntityTreeModel to get the collection list
-+void AkonadiBackend::initCollections()
-+{
-+ if (!m_spSession)
-+ m_spSession = new Akonadi::Session("ring-kde");
-+
-+ auto changeRecorder = new Akonadi::ChangeRecorder();
-
-+ changeRecorder->setCollectionMonitored( Akonadi::Collection::root() );
-+ changeRecorder->setMimeTypeMonitored( "text/directory" );
-+ changeRecorder->setSession( m_spSession );
-+
-+ m_spModel = new Akonadi::EntityTreeModel( changeRecorder, changeRecorder );
-+ m_spModel->setItemPopulationStrategy( Akonadi::EntityTreeModel::NoItemPopulation );
-+
-+ QObject::connect(m_spModel, &QAbstractItemModel::rowsInserted, &slotRowsInserted);
-+
-+ digg(m_spModel, QModelIndex());
-+}
-+
-+///Constructor
-+AkonadiBackend::AkonadiBackend(CollectionMediator<Person>* mediator, Akonadi::Collection* parentCol) : QObject(mediator->model()),
-+ CollectionInterface(new AkonadiEditor(mediator),m_hParentLookup[parentCol->parentCollection().id()]),m_pJob{},m_pMediator(mediator),
-+ m_pMonitor(nullptr),m_isEnabled(false),m_wasEnabled(false)
-+{
-+ if (!m_spSession)
-+ m_spSession = new Akonadi::Session( "Ring::instance" );
-+ setObjectName(parentCol->name());
-+ m_Coll = *parentCol;
-+ m_hParentLookup[m_Coll.id()] = this;
-+} //AkonadiBackend
-
-
-
-@@ -80,38 +169,91 @@ bool AkonadiEditor::save(const Person* item)
- return false;
- }
-
--bool AkonadiEditor::append(const Person* item)
-+bool AkonadiEditor::addExisting(const Person* item)
- {
- Q_UNUSED(item)
- return false;
- }
-
--bool AkonadiEditor::remove(Person* c)
-+bool AkonadiEditor::remove(const Person* c)
- {
- if (!c)
- return false;
- Akonadi::Item item = m_ItemHash[c->uid()];
- Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob( item );
- job->exec();
-- c->setActive(false);
- return true;
- }
-
--bool AkonadiEditor::edit( Person* item)
-+void applyNativeEdit()
- {
-- Q_UNUSED(item)
-- return false;
-+
- }
-
--bool AkonadiEditor::addNew( Person* item)
-+bool AkonadiEditor::edit( Person* contact)
- {
-- Q_UNUSED(item)
-+ Akonadi::Item item = m_ItemHash[contact->uid()];
-+ if (!(item.hasPayload<KContacts::Addressee>() && item.payload<KContacts::Addressee>().uid() == contact->uid())) {
-+ qDebug() << "Person not found";
-+ return false ;
-+ }
-+
-+ if ( item.isValid() ) {
-+ QPointer<Akonadi::ContactEditorDialog> editor = new Akonadi::ContactEditorDialog( Akonadi::ContactEditorDialog::EditMode );
-+ editor->editor()->loadContact(item);
-+
-+ if ( editor->exec() == QDialog::Accepted ) {
-+ if ( !contact->save() ) {
-+ delete editor;
-+ qDebug() << "Unable to save new contact to storage";
-+ return false;
-+ }
-+ }
-+ delete editor;
-+ return true;
-+ }
- return false;
- }
-
-+bool AkonadiEditor::addNew( Person* contact)
-+{
-+ KContacts::Addressee newPerson;
-+ newPerson.setNickName ( contact->nickName () );
-+ newPerson.setFormattedName ( contact->formattedName() );
-+ newPerson.setGivenName ( contact->firstName () );
-+ newPerson.setFamilyName ( contact->secondName () );
-+ newPerson.setOrganization ( contact->organization () );
-+ newPerson.setDepartment ( contact->department () );
-+// newPerson.setPreferredEmail ( contact->preferredEmail() );//TODO
-+
-+ foreach (ContactMethod* nb, contact->phoneNumbers()) {
-+ KContacts::PhoneNumber pn;
-+ pn.setType(AkonadiBackend::nameToType(nb->category()->name()));
-+
-+ pn.setNumber(nb->uri());
-+ newPerson.insertPhoneNumber(pn);
-+ }
-+
-+ //aPerson->setContactMethods (newNumbers );//TODO
-+
-+ QPointer<Akonadi::ContactEditorDialog> editor = new Akonadi::ContactEditorDialog( Akonadi::ContactEditorDialog::CreateMode );
-+
-+ editor->editor()->setContactTemplate(newPerson);
-+
-+ if ( editor->exec() == QDialog::Accepted ) {
-+ if ( !contact->save() ) {
-+ delete editor;
-+ qDebug() << "Unable to save new contact to storage";
-+ return false;
-+ }
-+ }
-+ delete editor;
-+ return true;
-+}
-+
- QVector<Person*> AkonadiEditor::items() const
- {
-- return QVector<Person*>();
-+ return m_lBackendPersons;
- }
-
- QString AkonadiBackend::name () const
-@@ -138,7 +280,11 @@ QVariant AkonadiBackend::icon() const
-
- bool AkonadiBackend::isEnabled() const
- {
-- return m_isEnabled;
-+ try {
-+ return GlobalInstances::itemModelStateSerializer().isChecked(this);
-+ } catch (...) {
-+ return true;
-+ }
- }
-
- bool AkonadiBackend::load()
-@@ -160,9 +306,9 @@ bool AkonadiBackend::load()
- connect(m_pMonitor,SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),this,SLOT(slotItemChanged(Akonadi::Item,QSet<QByteArray>)));
- connect(m_pMonitor,SIGNAL(itemRemoved(Akonadi::Item)),this,SLOT(slotItemRemoved(Akonadi::Item)));
-
--
- m_pMonitor->setCollectionMonitored(m_Coll,true);
- m_isEnabled = true; //FIXME does it make sense to merge loaded and enabled?
-+ m_wasEnabled = false;
- return true;
- }
-
-@@ -172,15 +318,17 @@ bool AkonadiBackend::enable (bool enable)
- return load();
- }
- else if (m_wasEnabled && enable) {
-- foreach(Person* contact, static_cast<AkonadiEditor*>(editor<Person>())->m_lBackendPersons) {
-- contact->setActive(true);
-+ foreach(Person* contact, items<Person>()) {
-+ activate(contact);
-+ emit contact->changed();
- }
- m_wasEnabled = false;
- m_isEnabled = true;
- }
-- else if (isEnabled()) {
-- foreach(Person* contact, static_cast<AkonadiEditor*>(editor<Person>())->m_lBackendPersons) {
-- contact->setActive(false);
-+ else if (m_isEnabled && !enable) {
-+ foreach(Person* contact, items<Person>()) {
-+ deactivate(contact);
-+ emit contact->changed();
- }
- m_isEnabled = false;
- m_wasEnabled = true;
-@@ -199,9 +347,9 @@ QByteArray AkonadiBackend::id() const
- return QString::number(m_Coll.id()).toLatin1();
- }
-
--CollectionInterface::SupportedFeatures AkonadiBackend::supportedFeatures() const
-+FlagPack<CollectionInterface::SupportedFeatures> AkonadiBackend::supportedFeatures() const
- {
-- return (CollectionInterface::SupportedFeatures) (
-+ return (
- CollectionInterface::SupportedFeatures::NONE |
- CollectionInterface::SupportedFeatures::LOAD |
- CollectionInterface::SupportedFeatures::SAVE |
-@@ -220,59 +368,63 @@ CollectionInterface::SupportedFeatures AkonadiBackend::supportedFeatures() const
- * *
- ****************************************************************************/
-
--///Convert string to akonadi KABC::PhoneNumber
--KABC::PhoneNumber::Type AkonadiBackend::nameToType(const QString& name)
--{
-- if (name == "Home" ) return KABC::PhoneNumber::Home ;
-- else if (name == "Work" ) return KABC::PhoneNumber::Work ;
-- else if (name == "Msg" ) return KABC::PhoneNumber::Msg ;
-- else if (name == "Pref" ) return KABC::PhoneNumber::Pref ;
-- else if (name == "Voice" ) return KABC::PhoneNumber::Voice;
-- else if (name == "Fax" ) return KABC::PhoneNumber::Fax ;
-- else if (name == "Cell" ) return KABC::PhoneNumber::Cell ;
-- else if (name == "Video" ) return KABC::PhoneNumber::Video;
-- else if (name == "Bbs" ) return KABC::PhoneNumber::Bbs ;
-- else if (name == "Modem" ) return KABC::PhoneNumber::Modem;
-- else if (name == "Car" ) return KABC::PhoneNumber::Car ;
-- else if (name == "Isdn" ) return KABC::PhoneNumber::Isdn ;
-- else if (name == "Pcs" ) return KABC::PhoneNumber::Pcs ;
-- else if (name == "Pager" ) return KABC::PhoneNumber::Pager;
-- return KABC::PhoneNumber::Home;
-+///Convert string to akonadi KContacts::PhoneNumber
-+KContacts::PhoneNumber::Type AkonadiBackend::nameToType(const QString& name)
-+{
-+ if (name == "Home" ) return KContacts::PhoneNumber::Home ;
-+ else if (name == "Work" ) return KContacts::PhoneNumber::Work ;
-+ else if (name == "Msg" ) return KContacts::PhoneNumber::Msg ;
-+ else if (name == "Pref" ) return KContacts::PhoneNumber::Pref ;
-+ else if (name == "Voice" ) return KContacts::PhoneNumber::Voice;
-+ else if (name == "Fax" ) return KContacts::PhoneNumber::Fax ;
-+ else if (name == "Cell" ) return KContacts::PhoneNumber::Cell ;
-+ else if (name == "Video" ) return KContacts::PhoneNumber::Video;
-+ else if (name == "Bbs" ) return KContacts::PhoneNumber::Bbs ;
-+ else if (name == "Modem" ) return KContacts::PhoneNumber::Modem;
-+ else if (name == "Car" ) return KContacts::PhoneNumber::Car ;
-+ else if (name == "Isdn" ) return KContacts::PhoneNumber::Isdn ;
-+ else if (name == "Pcs" ) return KContacts::PhoneNumber::Pcs ;
-+ else if (name == "Pager" ) return KContacts::PhoneNumber::Pager;
-+ return KContacts::PhoneNumber::Home;
- }
-
--void AkonadiBackend::fillPerson(Person* c, const KABC::Addressee& addr) const
--{
-- c->setNickName (addr.nickName() );
-- c->setFormattedName (addr.formattedName() );
-- c->setFirstName (addr.givenName() );
-- c->setFamilyName (addr.familyName() );
-- c->setOrganization (addr.organization() );
-- c->setPreferredEmail (addr.preferredEmail() );
-- c->setDepartment (addr.department() );
-- c->setUid (addr.uid().toUtf8() );
--
-- const KABC::PhoneNumber::List numbers = addr.phoneNumbers();
-- Person::ContactMethods newNumbers(c);
-- foreach (const KABC::PhoneNumber& number, numbers) {
-- newNumbers << PhoneDirectoryModel::instance()->getNumber(number.number(),c,nullptr,number.typeLabel());
-- QString number2 = number.number();
-- if (number2.left (5) == "<sip:")
-- number2 = number2.remove(0,5);
-- if (number2.right(1) == ">" )
-- number2 = number2.remove(number2.size()-2,1);
-+void AkonadiBackend::fillPerson(Person* c, const KContacts::Addressee& addr)
-+{
-+ if (!c) {
-+ qDebug() << "Contact not found";
-+ return;
- }
-- c->setContactMethods (newNumbers );
-+
-+ c->setNickName ( addr.nickName () );
-+ c->setFormattedName ( addr.formattedName () );
-+ c->setFirstName ( addr.givenName () );
-+ c->setFamilyName ( addr.familyName () );
-+ c->setOrganization ( addr.organization () );
-+ c->setPreferredEmail ( addr.preferredEmail() );
-+ c->setDepartment ( addr.department () );
-+ c->setUid ( addr.uid().toUtf8 () );
-+
-+ const KContacts::PhoneNumber::List numbers = addr.phoneNumbers();
-+ QVector<ContactMethod*> newNumbers;
-+ foreach (const KContacts::PhoneNumber& number, numbers) {
-+ ContactMethod* cm = PhoneDirectoryModel::instance().getNumber(number.number(),c,nullptr,number.typeLabel());
-+
-+ newNumbers << cm;
-+ }
-+
-+ c->setContactMethods ( newNumbers );
- }
-
- Person* AkonadiBackend::addItem(Akonadi::Item item, bool ignoreEmpty)
- {
-+ Q_UNUSED(ignoreEmpty)
- Person* aPerson = nullptr;
-- if ( item.hasPayload<KABC::Addressee>() ) {
-+ if ( item.hasPayload<KContacts::Addressee>() ) {
- m_pMonitor->setItemMonitored(item,true);
-- KABC::Addressee tmp = item.payload<KABC::Addressee>();
-- const KABC::PhoneNumber::List numbers = tmp.phoneNumbers();
-+ KContacts::Addressee tmp = item.payload<KContacts::Addressee>();
-+ const KContacts::PhoneNumber::List numbers = tmp.phoneNumbers();
- const QString uid = tmp.uid();
-- if (numbers.size() || !ignoreEmpty) {
-+ if (numbers.size() ) {
- aPerson = new Person(this);
-
- //This need to be done first because of the phone numbers indexes
-@@ -308,7 +460,7 @@ void AkonadiBackend::slotJobCompleted(KJob* job)
- const Akonadi::Item::List items = akojob->items();
- foreach ( const Akonadi::Item &item, items ) {
- Person* c = addItem(item,onlyWithNumber);
-- PersonModel::instance()->addPerson(c);
-+ PersonModel::instance().addPerson(c);
- }
- }
- }
-@@ -321,66 +473,34 @@ void AkonadiBackend::update(const Akonadi::Collection& collection)
- return;
- }
-
-- Akonadi::RecursiveItemFetchJob *job = new Akonadi::RecursiveItemFetchJob( collection, QStringList() << KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType());
-+ Akonadi::RecursiveItemFetchJob *job = new Akonadi::RecursiveItemFetchJob( collection, QStringList() << KContacts::Addressee::mimeType() << KContacts::ContactGroup::mimeType());
- job->fetchScope().fetchFullPayload();
- connect(job, SIGNAL(result(KJob*)), this, SLOT(slotJobCompleted(KJob*)));
- job->start();
--// return m_PersonByUid.values();
--} //update
--
--// bool AkonadiBackend::remove(Person* c)
--// {
--//
--// }
-
--///Edit backend value using an updated frontend contact
--bool AkonadiBackend::edit(Person* contact,QWidget* parent)
--{
-- Akonadi::Item item = static_cast<AkonadiEditor*>(editor<Person>())->m_ItemHash[contact->uid()];
-- if (!(item.hasPayload<KABC::Addressee>() && item.payload<KABC::Addressee>().uid() == contact->uid())) {
-- qDebug() << "Person not found";
-- return false ;
-- }
--
-- if ( item.isValid() ) {
-- QPointer<Akonadi::ContactEditor> editor = new Akonadi::ContactEditor( Akonadi::ContactEditor::EditMode, parent );
-- editor->loadContact(item);
-- QPointer<QDialog> dlg = new QDialog(parent);
-- QVBoxLayout *mainLayout = new QVBoxLayout;
-- dlg->setLayout(mainLayout);
-- mainLayout->addWidget(editor);
-- if ( dlg->exec() == QDialog::Accepted ) {
-- if ( !editor->saveContact() ) {
-- delete dlg;
-- qDebug() << "Unable to save new contact to storage";
-- return false;
-- }
-- }
-- delete editor;
-- delete dlg ;
-- return true;
-- }
-- return false;
--} //editPerson
-+} //update
-
- ///Save a contact
- bool AkonadiBackend::save(const Person* contact)
- {
- Akonadi::Item item = static_cast<AkonadiEditor*>(editor<Person>())->m_ItemHash[contact->uid()];
-- if (!(item.hasPayload<KABC::Addressee>() && item.payload<KABC::Addressee>().uid() == contact->uid())) {
-+
-+ if (!(item.hasPayload<KContacts::Addressee>() && item.payload<KContacts::Addressee>().uid() == contact->uid())) {
- qDebug() << "Person not found";
- return false;
- }
-- KABC::Addressee payload = item.payload<KABC::Addressee>();
-- payload.setNickName ( contact->nickName() );
-- payload.setFormattedName ( contact->formattedName() );
-- payload.setGivenName ( contact->firstName() );
-- payload.setFamilyName ( contact->secondName() );
-- payload.setOrganization ( contact->organization() );
-- payload.setDepartment ( contact->department() );
-+
-+ auto payload = item.payload<KContacts::Addressee> ();
-+
-+ payload.setNickName ( contact->nickName () );
-+ payload.setFormattedName ( contact->formattedName() );
-+ payload.setGivenName ( contact->firstName () );
-+ payload.setFamilyName ( contact->secondName () );
-+ payload.setOrganization ( contact->organization () );
-+ payload.setDepartment ( contact->department () );
-
- foreach (ContactMethod* nb, contact->phoneNumbers()) {
-- KABC::PhoneNumber pn;
-+ KContacts::PhoneNumber pn;
- pn.setType(nameToType(nb->category()->name()));
-
- pn.setNumber(nb->uri());
-@@ -390,93 +510,29 @@ bool AkonadiBackend::save(const Person* contact)
- return false;
- }
-
--
--// bool AkonadiBackend::append(const Person* item)
--// {
--// Q_UNUSED(item)
--// return false;
--// }
--
--///Add a new contact
--bool AkonadiBackend::addNewPerson(Person* contact,QWidget* parent)
--{
-- KABC::Addressee newPerson;
-- newPerson.setNickName ( contact->nickName() );
-- newPerson.setFormattedName ( contact->formattedName() );
-- newPerson.setGivenName ( contact->firstName() );
-- newPerson.setFamilyName ( contact->secondName() );
-- newPerson.setOrganization ( contact->organization() );
-- newPerson.setDepartment ( contact->department() );
-- //newPerson.setPreferredEmail ( contact->getPreferredEmail() );//TODO
--
-- foreach (ContactMethod* nb, contact->phoneNumbers()) {
-- KABC::PhoneNumber pn;
-- pn.setType(nameToType(nb->category()->name()));
--
-- pn.setNumber(nb->uri());
-- newPerson.insertPhoneNumber(pn);
-- }
--
-- //aPerson->setContactMethods (newNumbers );//TODO
--
-- QPointer<Akonadi::ContactEditor> editor = new Akonadi::ContactEditor( Akonadi::ContactEditor::CreateMode, parent );
--
-- editor->setContactTemplate(newPerson);
--
-- QPointer<QDialog> dlg = new QDialog(parent);
-- QVBoxLayout *mainLayout = new QVBoxLayout;
-- dlg->setLayout(mainLayout);
-- mainLayout->addWidget(editor);
-- if ( dlg->exec() == QDialog::Accepted ) {
-- if ( !editor->saveContact() ) {
-- delete dlg;
-- qDebug() << "Unable to save new contact to storage";
-- return false;
-- }
-- }
-- delete dlg;
-- return true;
--} //addNewPerson
--
--///Implement virtual pure method
--// bool AkonadiBackend::edit(Person* contact)
--// {
--// return edit(contact,nullptr);
--// }
--
--///Implement virtual pure method
--// bool AkonadiBackend::addNew(Person* contact)
--// {
--// return addNewPerson(contact,nullptr);
--// }
--
- ///Add a new phone number to an existing contact
- bool AkonadiBackend::addContactMethod(Person* contact, ContactMethod* number)
- {
- Akonadi::Item item = static_cast<AkonadiEditor*>(editor<Person>())->m_ItemHash[contact->uid()];
-- if (!(item.hasPayload<KABC::Addressee>() && item.payload<KABC::Addressee>().uid() == contact->uid())) {
-+ if (!(item.hasPayload<KContacts::Addressee>() && item.payload<KContacts::Addressee>().uid() == contact->uid())) {
- qDebug() << "Person not found";
- return false;
- }
- if ( item.isValid() ) {
-- KABC::Addressee payload = item.payload<KABC::Addressee>();
-- payload.insertPhoneNumber(KABC::PhoneNumber(number->uri(),nameToType(number->category()->name())));
-- item.setPayload<KABC::Addressee>(payload);
-- QPointer<Akonadi::ContactEditor> editor = new Akonadi::ContactEditor( Akonadi::ContactEditor::EditMode, (QWidget*)nullptr );
-- editor->loadContact(item);
--
-- QPointer<QDialog> dlg = new QDialog(nullptr);
-- QVBoxLayout *mainLayout = new QVBoxLayout;
-- dlg->setLayout(mainLayout);
-- mainLayout->addWidget(editor);
-- if ( dlg->exec() == QDialog::Accepted ) {
-- if ( !editor->saveContact() ) {
-- delete dlg;
-+ KContacts::Addressee payload = item.payload<KContacts::Addressee>();
-+ payload.insertPhoneNumber(KContacts::PhoneNumber(number->uri(),nameToType(number->category()->name())));
-+ item.setPayload<KContacts::Addressee>(payload);
-+ QPointer<Akonadi::ContactEditorDialog> editor = new Akonadi::ContactEditorDialog( Akonadi::ContactEditorDialog::EditMode, (QWidget*)nullptr );
-+ editor->editor()->loadContact(item);
-+
-+ if ( editor->exec() == QDialog::Accepted ) {
-+ if ( !contact->save() ) {
-+ delete editor;
- qDebug() << "Unable to save new contact to storage";
- return false;
- }
- }
-- delete dlg ;
-+
- delete editor;
- return true;
- }
-@@ -496,12 +552,7 @@ bool AkonadiBackend::addContactMethod(Person* contact, ContactMethod* number)
- ///Called when a new collection is added
- void AkonadiBackend::itemsReceived( const Akonadi::Item::List& list)
- {
--// QList<int> disabledColl = ConfigurationSkeleton::disabledCollectionList();
- foreach (const Akonadi::Item& item, list) {
--// if (disabledColl.indexOf(coll.id()) == -1) {
--// update(coll);
--// emit reloaded();
--// }
- slotItemAdded(item,m_Coll);
- }
- }
-@@ -520,9 +571,9 @@ void AkonadiBackend::slotItemAdded(const Akonadi::Item& item,const Akonadi::Coll
- void AkonadiBackend::slotItemChanged(const Akonadi::Item &item, const QSet< QByteArray > &part)
- {
- Q_UNUSED(part)
-- if (item.hasPayload<KABC::Addressee>()) {
-- KABC::Addressee tmp = item.payload<KABC::Addressee>();
-- Person* c = PersonModel::instance()->getPersonByUid(tmp.uid().toUtf8());
-+ if (item.hasPayload<KContacts::Addressee>()) {
-+ KContacts::Addressee tmp = item.payload<KContacts::Addressee>();
-+ Person* c = PersonModel::instance().getPersonByUid(tmp.uid().toUtf8());
- if (c)
- fillPerson(c,tmp);
- }
-@@ -531,16 +582,11 @@ void AkonadiBackend::slotItemChanged(const Akonadi::Item &item, const QSet< QByt
- ///Callback when a contact is removed
- void AkonadiBackend::slotItemRemoved(const Akonadi::Item &item)
- {
-- Person* c = PersonModel::instance()->getPersonByUid(item.remoteId().toUtf8());
-- PersonModel::instance()->disablePerson(c);
--}
-+ Person* c = PersonModel::instance().getPersonByUid(item.remoteId().toUtf8());
-
--Akonadi::Collection AkonadiBackend::collection() const
--{
-- return m_Coll;
-+ if (c)
-+ deactivate(c);
-+ else
-+ qDebug() << "A contact was deleted, but Ring-KDE can't find it";
-+ //PersonModel::instance().disablePerson(c);
- }
--
--// QList<Person*> AkonadiBackend::items() const
--// {
--// return m_lBackendPersons;
--// }
-diff --git a/src/klib/akonadibackend.h b/src/klib/akonadibackend.h
-index b7ba169..58adb51 100644
---- a/src/klib/akonadibackend.h
-+++ b/src/klib/akonadibackend.h
-@@ -20,30 +20,30 @@
- #ifndef AKONADI_BACKEND_H
- #define AKONADI_BACKEND_H
-
--#include <QPointer>
-+#include <QtCore/QPointer>
-
- #include <collectioninterface.h>
- #include <collectioneditor.h>
- #include <collectionmediator.h>
- #include "typedefs.h"
--#include <akonadi/collectionmodel.h>
--#include <kabc/phonenumber.h>
--#include <akonadi/item.h>
-+#include <kcontacts/phonenumber.h>
-+#include <AkonadiCore/Item>
-
- //Qt
- class QObject;
-
- //KDE
--namespace KABC {
-+namespace KContacts {
- class Addressee ;
- class ContactMethod ;
- }
-
- namespace Akonadi {
-- class Session ;
-- class Collection ;
-- class ItemFetchJob;
-- class Monitor ;
-+ class Session ;
-+ class Collection ;
-+ class ItemFetchJob ;
-+ class Monitor ;
-+ class EntityTreeModel;
- }
- class KJob;
-
-@@ -58,50 +58,47 @@ class LIB_EXPORT AkonadiBackend : public QObject, public CollectionInterface
- {
- Q_OBJECT
- public:
-- template<typename T>
-- explicit AkonadiBackend(CollectionMediator<T>* mediator, const Akonadi::Collection& parentCol);
--// Person* getPersonByPhone ( const QString& phoneNumber ,bool resolveDNS = false, Account* a=nullptr);
-- bool edit ( Person* contact , QWidget* parent = 0 );
-- bool addNewPerson ( Person* contact , QWidget* parent = 0 );
-- virtual bool addContactMethod( Person* contact , ContactMethod* number );
--
-- virtual QString name () const override;
-- virtual QString category () const override;
-- virtual QVariant icon() const override;
-- virtual bool isEnabled() const override;
-- virtual bool enable (bool enable) override;
-- virtual QByteArray id() const;
--
--// virtual bool edit ( Person* contact ) override;
--// virtual bool addNew ( Person* contact ) override;
--// virtual bool remove ( Person* c ) override;
--// virtual bool append(const Person* item);
-- virtual ~AkonadiBackend ( );
--
-- virtual bool load();
-- virtual bool reload();
-- virtual bool save(const Person* contact);
--
-- SupportedFeatures supportedFeatures() const;
--
--// virtual QList<Person*> items() const override;
--
-- Akonadi::Collection collection() const;
-+ // Constructor
-+ explicit AkonadiBackend(CollectionMediator<Person>* mediator, Akonadi::Collection* parentCol);
-+ virtual ~AkonadiBackend( );
-+
-+ // Mutator
-+ bool addContactMethod( Person* contact , ContactMethod* number );
-+
-+ // CollectionInterface override
-+ virtual QString name ( ) const override;
-+ virtual QString category ( ) const override;
-+ virtual QVariant icon ( ) const override;
-+ virtual bool isEnabled ( ) const override;
-+ virtual bool enable ( bool enable ) override;
-+ virtual QByteArray id ( ) const override;
-+ virtual bool load ( ) override;
-+ virtual bool reload ( ) override;
-+ virtual bool save ( const Person* contact );
-+ virtual FlagPack<SupportedFeatures> supportedFeatures() const override;
-+
-+ //Helper
-+ static KContacts::PhoneNumber::Type nameToType(const QString& name);
-+ static void initCollections();
-+
- private:
-
- //Attributes
-- static Akonadi::Session* m_pSession ;
-- Akonadi::Monitor* m_pMonitor ;
-- Akonadi::Collection m_Coll ;
-- QPointer<Akonadi::ItemFetchJob> m_pJob;
-- bool m_isEnabled;
-- bool m_wasEnabled;
-- CollectionMediator<Person>* m_pMediator;
-+ static Akonadi::Session* m_spSession ;
-+ static Akonadi::EntityTreeModel* m_spModel ;
-+
-+ Akonadi::Monitor* m_pMonitor ;
-+ Akonadi::Collection m_Coll ;
-+ QPointer<Akonadi::ItemFetchJob> m_pJob ;
-+ bool m_isEnabled ;
-+ bool m_wasEnabled ;
-+ CollectionMediator<Person>* m_pMediator ;
-
- //Helper
-- KABC::PhoneNumber::Type nameToType(const QString& name);
-- Person* addItem(Akonadi::Item item, bool ignoreEmpty = false);
-- void fillPerson(Person* c, const KABC::Addressee& addr) const;
-+ Person* addItem (Akonadi::Item item , bool ignoreEmpty = false );
-+ static void fillPerson (Person* c , const KContacts::Addressee& addr);
-+ static void digg (QAbstractItemModel* model, const QModelIndex& idx );
-+ static void slotRowsInserted(const QModelIndex& parent, int start , int end);
-
- //Parent locator
- static QHash<Akonadi::Collection::Id, AkonadiBackend*> m_hParentLookup;
-@@ -109,6 +106,7 @@ private:
- public Q_SLOTS:
- void update(const Akonadi::Collection& collection);
- void itemsReceived( const Akonadi::Item::List& );
-+
- private Q_SLOTS:
- void slotItemAdded(const Akonadi::Item& item, const Akonadi::Collection& coll);
- void slotItemChanged (const Akonadi::Item &item, const QSet< QByteArray > &partIdentifiers);
-@@ -116,55 +114,4 @@ private Q_SLOTS:
- void slotJobCompleted(KJob* job);
- };
-
--class AkonadiEditor : public CollectionEditor<Person>
--{
--public:
-- AkonadiEditor(CollectionMediator<Person>* m) : CollectionEditor<Person>(m) {}
-- ~AkonadiEditor() {
-- m_lBackendPersons.clear();
-- m_ItemHash.clear();
-- m_AddrHash.clear();
-- }
-- virtual bool save ( const Person* item ) override;
-- virtual bool append ( const Person* item ) override;
-- virtual bool remove ( Person* item ) override;
-- virtual bool edit ( Person* item ) override;
-- virtual bool addNew ( Person* item ) override;
--
-- QHash<QString,KABC::Addressee> m_AddrHash ;
-- QHash<QString,Akonadi::Item> m_ItemHash ;
-- QList<Person*> m_lBackendPersons;
--private:
-- virtual QVector<Person*> items() const override;
--};
--#include <akonadi/control.h>
--#include <akonadi/collectionfilterproxymodel.h>
--#include <akonadi/kmime/messagemodel.h>
--#include <akonadi/recursiveitemfetchjob.h>
--#include <akonadi/itemfetchjob.h>
--#include <akonadi/itemfetchscope.h>
--#include <akonadi/collectionfetchjob.h>
--#include <akonadi/collectionfetchscope.h>
--#include <akonadi/contact/contacteditor.h>
--#include <akonadi/contact/contacteditordialog.h>
--#include <akonadi/session.h>
--#include <akonadi/monitor.h>
--#include <akonadi/itemdeletejob.h>
--#include <akonadi/entitydisplayattribute.h>
--#include <kabc/addressee.h>
--#include <kabc/addresseelist.h>
--#include <kabc/contactgroup.h>
--///Constructor
--template<typename T>
--AkonadiBackend::AkonadiBackend(CollectionMediator<T>* mediator, const Akonadi::Collection& parentCol) : QObject(mediator->model()),
-- CollectionInterface(new AkonadiEditor(mediator),m_hParentLookup[parentCol.parent()]),m_pJob(nullptr),m_pMediator(mediator),
-- m_pMonitor(nullptr),m_isEnabled(false),m_wasEnabled(false)
--{
-- if (!m_pSession)
-- m_pSession = new Akonadi::Session( "Ring::instance" );
-- setObjectName(parentCol.name());
-- m_Coll = parentCol;
-- m_hParentLookup[m_Coll.id()] = this;
--} //AkonadiBackend
--
- #endif
-diff --git a/src/klib/akonadicontactcollectionmodel.cpp b/src/klib/akonadicontactcollectionmodel.cpp
-deleted file mode 100644
-index 6d4cc9c..0000000
---- a/src/klib/akonadicontactcollectionmodel.cpp
-+++ /dev/null
-@@ -1,141 +0,0 @@
--/****************************************************************************
-- * Copyright (C) 2014-2015 by Savoir-Faire Linux *
-- * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
-- * *
-- * This library is free software; you can redistribute it and/or *
-- * modify it under the terms of the GNU Lesser General Public *
-- * License as published by the Free Software Foundation; either *
-- * version 2.1 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 *
-- * Lesser 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 "akonadicontactcollectionmodel.h"
--
--//Qt
--#include <QCoreApplication>
--
--// KDE
--#include <akonadi/collectionmodel.h>
--
--// Ring
--#include "personmodel.h"
--#include "akonadibackend.h"
--#include "kcfg_settings.h"
--
--AkonadiPersonCollectionModel* AkonadiPersonCollectionModel::m_spInstance = nullptr;
--
--
--AkonadiPersonCollectionModel* AkonadiPersonCollectionModel::instance()
--{
-- if (!m_spInstance)
-- m_spInstance = new AkonadiPersonCollectionModel(QCoreApplication::instance());
-- return m_spInstance;
--}
--
--AkonadiPersonCollectionModel::AkonadiPersonCollectionModel(QObject* parent) : QSortFilterProxyModel(parent) {
-- m_pParentModel = new Akonadi::CollectionModel(this);
-- setSourceModel(m_pParentModel);
-- setDynamicSortFilter(true);
-- reload();
-- connect(this,SIGNAL(rowsInserted(QModelIndex,int,int)),this,SLOT(slotInsertCollection(QModelIndex,int,int)));
-- connect(this,SIGNAL(rowsRemoved(QModelIndex,int,int)),this,SLOT(slotRemoveCollection(QModelIndex,int,int)));
--}
--
--AkonadiPersonCollectionModel::~AkonadiPersonCollectionModel()
--{
-- setSourceModel(nullptr);
-- delete m_pParentModel;
--}
--
--bool AkonadiPersonCollectionModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const
--{
-- const QModelIndex idx = sourceModel()->index(source_row,0,source_parent);
-- Akonadi::Collection col = qvariant_cast<Akonadi::Collection>(idx.data(Akonadi::CollectionModel::Roles::CollectionRole));
-- return col.contentMimeTypes().indexOf("text/directory") != -1;
--}
--
--Qt::ItemFlags AkonadiPersonCollectionModel::flags ( const QModelIndex& index ) const
--{
-- return QSortFilterProxyModel::flags(index) | Qt::ItemIsUserCheckable;
--}
--
--QVariant AkonadiPersonCollectionModel::data( const QModelIndex& index, int role ) const
--{
-- if (role == Qt::CheckStateRole) {
-- const int id = index.data(Akonadi::CollectionModel::Roles::CollectionIdRole).toInt();
-- return m_hChecked[id]?Qt::Unchecked:Qt::Checked;
-- }
-- return QSortFilterProxyModel::data(index,role);
--}
--
--bool AkonadiPersonCollectionModel::setData( const QModelIndex& index, const QVariant &value, int role)
--{
-- if (role == Qt::CheckStateRole) {
-- const int id = index.data(Akonadi::CollectionModel::Roles::CollectionIdRole).toInt();
-- m_hChecked[id] = !value.toBool();
-- emit dataChanged(index,index);
-- emit changed();
-- return false;
-- }
-- else
-- return QSortFilterProxyModel::setData(index,value,role);
--}
--
--
--void AkonadiPersonCollectionModel::reload()
--{
--// m_hChecked.clear();
--// const QList<int> disabled = ConfigurationSkeleton::disabledCollectionList();
--// foreach(const int str, disabled) {
--// m_hChecked[str] = true; //Disabled == true, enabled == false
--// }
--}
--
--void AkonadiPersonCollectionModel::digg(const QModelIndex& idx)
--{
-- for (int i = 0;i < rowCount(idx);i++) {
-- QModelIndex current = index(i,0,idx);
-- if (!m_hLoaded[current.data(Akonadi::CollectionModel::Roles::CollectionIdRole).toInt()]) {
-- PersonModel::instance()->addBackend<AkonadiBackend,Akonadi::Collection>(qvariant_cast<Akonadi::Collection>(index(i,0,idx).data(Akonadi::CollectionModel::Roles::CollectionRole)));
-- }
-- digg(current);
-- }
--}
--
--void AkonadiPersonCollectionModel::save()
--{
--// QList<int> ret;
--// for (QHash<int,bool>::iterator i = m_hChecked.begin(); i != m_hChecked.end(); ++i) {
--// if (i.value())
--// ret << i.key();
--// }
-- digg(QModelIndex());
--// ConfigurationSkeleton::setDisabledCollectionList(ret);
--}
--
--
--void AkonadiPersonCollectionModel::slotInsertCollection(const QModelIndex& parentIdx, int start, int end)
--{
-- for (int i =start; i <= end;i++) {
-- Akonadi::Collection col = qvariant_cast<Akonadi::Collection>(index(i,0,parentIdx).data(Akonadi::CollectionModel::Roles::CollectionRole));
--
-- PersonModel::instance()->addBackend<AkonadiBackend,Akonadi::Collection&>(col);
-- m_hLoaded[col.id()] = !m_hChecked[col.id()];
-- }
--}
--
--void AkonadiPersonCollectionModel::slotRemoveCollection(const QModelIndex& index , int start, int end)
--{
-- Q_UNUSED(index)
-- Q_UNUSED(start)
-- Q_UNUSED(end)
-- for (int i =start; i <= end;i++) {
-- //TODO
-- }
--}
-diff --git a/src/klib/akonadicontactcollectionmodel.h b/src/klib/akonadicontactcollectionmodel.h
-deleted file mode 100644
-index 8bdb50c..0000000
---- a/src/klib/akonadicontactcollectionmodel.h
-+++ /dev/null
-@@ -1,70 +0,0 @@
--/****************************************************************************
-- * Copyright (C) 2014-2015 by Savoir-Faire Linux *
-- * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
-- * *
-- * This library is free software; you can redistribute it and/or *
-- * modify it under the terms of the GNU Lesser General Public *
-- * License as published by the Free Software Foundation; either *
-- * version 2.1 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 *
-- * Lesser 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 AKONADI_CONTACT_COLLECTION_MODEL_H
--#define AKONADI_CONTACT_COLLECTION_MODEL_H
--
--#include <QtCore/QSortFilterProxyModel>
--#include "typedefs.h"
--
--namespace Akonadi {
-- class CollectionModel;
--}
--
--///Filter out notes and emails collections
--class LIB_EXPORT AkonadiPersonCollectionModel : public QSortFilterProxyModel
--{
-- Q_OBJECT
--public:
-- virtual ~AkonadiPersonCollectionModel();
--
--public:
-- virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
-- virtual Qt::ItemFlags flags ( const QModelIndex& index ) const;
-- virtual bool setData ( const QModelIndex& index, const QVariant &value, int role );
--
-- //Mutator
-- void reload();
-- void save();
--
-- //Singleton
-- static AkonadiPersonCollectionModel* instance();
--
--protected:
-- virtual bool filterAcceptsRow( int source_row, const QModelIndex & source_parent ) const;
--
--private:
-- explicit AkonadiPersonCollectionModel(QObject* parent);
-- QHash<int,bool> m_hChecked;
-- QHash<int,bool> m_hLoaded ;
-- Akonadi::CollectionModel* m_pParentModel;
--
-- //Singleton
-- static AkonadiPersonCollectionModel* m_spInstance;
--
-- //Helper
-- void digg(const QModelIndex& idx);
--
--private Q_SLOTS:
-- void slotInsertCollection(const QModelIndex&,int,int);
-- void slotRemoveCollection(const QModelIndex&,int,int);
--
--Q_SIGNALS:
-- void changed();
--};
--
--#endif
-diff --git a/src/klib/itemmodelserialization.cpp b/src/klib/itemmodelserialization.cpp
-index 1a0d4cd..6da8cc1 100644
---- a/src/klib/itemmodelserialization.cpp
-+++ b/src/klib/itemmodelserialization.cpp
-@@ -17,6 +17,10 @@
- ***************************************************************************/
- #include "itemmodelserialization.h"
-
-+#include <personmodel.h>
-+
-+#include "akonadibackend.h"
-+
- #include "collectioninterface.h"
- #include "kcfg_settings.h"
-
-@@ -59,3 +63,16 @@ bool ItemModelStateSerialization::setChecked(const CollectionInterface* backend,
- m_hChecked[backend->id()] = ! enabled;
- return true;
- }
-+
-+CollectionInterface* ItemModelStateSerialization::preferredCollection(CollectionManagerInterfaceBase* manager, FlagPack<CollectionInterface::SupportedFeatures> features, FlagPack<Interfaces::ItemModelStateSerializerI::Hints> hints )
-+{
-+ Q_UNUSED(hints)
-+ if (manager == &PersonModel::instance()) {
-+ foreach(CollectionInterface* i, PersonModel::instance().collections(features)) {
-+ if (dynamic_cast<AkonadiBackend*>(i)) //TODO use something better
-+ return i;
-+ }
-+ }
-+
-+ return nullptr;
-+}
-diff --git a/src/klib/itemmodelserialization.h b/src/klib/itemmodelserialization.h
-index 3242e09..53e164d 100644
---- a/src/klib/itemmodelserialization.h
-+++ b/src/klib/itemmodelserialization.h
-@@ -25,7 +25,6 @@
- class Account;
- class CollectionInterface;
-
--///Ringlib Qt does not link to QtGui, and does not need to, this allow to add runtime Gui support
- class LIB_EXPORT ItemModelStateSerialization : public Interfaces::ItemModelStateSerializerI
- {
- public:
-@@ -35,6 +34,11 @@ public:
-
- //Getter
- virtual bool isChecked(const CollectionInterface* backend) const override;
-+ virtual CollectionInterface* preferredCollection(
-+ CollectionManagerInterfaceBase* manager,
-+ FlagPack<CollectionInterface::SupportedFeatures> features,
-+ FlagPack<Interfaces::ItemModelStateSerializerI::Hints> hints
-+ ) override;
-
- //Setter
- virtual bool setChecked(const CollectionInterface* backend, bool enabled) override;
-diff --git a/src/klib/ring-kde.kcfg b/src/klib/ring-kde.kcfg
-index 79def64..85b539d 100644
---- a/src/klib/ring-kde.kcfg
-+++ b/src/klib/ring-kde.kcfg
-@@ -213,6 +213,12 @@
- <default> false </default>
- </entry>
-
-+ <entry name="hideUnreachable" type="Bool">
-+ <label>Hide unreachable contacts</label>
-+ <tooltip>Hide a contact if there is no enabled accounts that can reach him/her</tooltip>
-+ <default> true </default>
-+ </entry>
-+
- <entry name="defaultAccountId" type="String">
- <label>Default account used for contact lookup if only partial (only extension) contacts info is available</label>
- <default>IP2IP</default>
-diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
-index d8f3993..1d0553d 100755
---- a/src/mainwindow.cpp
-+++ b/src/mainwindow.cpp
-@@ -86,6 +86,7 @@
- #include <video/renderer.h>
- #include "ringapplication.h"
- #include "widgets/dockbase.h"
-+#include "klib/akonadibackend.h"
- #ifdef ENABLE_VIDEO
- #include "widgets/videodock.h"
- #endif
-@@ -174,6 +175,9 @@ MainWindow::MainWindow(QWidget* parent)
- PersonModel::instance().addCollection<FallbackPersonCollection>(LoadOptions::FORCE_ENABLED);
-
- GlobalInstances::setInterface<ItemModelStateSerialization>();
-+ GlobalInstances::itemModelStateSerializer().load();
-+
-+ AkonadiBackend::initCollections();
- // PersonModel::instance().backendModel()->load();
- // AccountModel::instance().setDefaultAccount(AccountModel::instance().getAccountById(ConfigurationSkeleton::defaultAccountId()));
-
-@@ -353,7 +357,6 @@ MainWindow::MainWindow(QWidget* parent)
- if (!ConfigurationSkeleton::autoStartOverride())
- setAutoStart(true);
-
--// RecentModel::instance();
-
- } //Ring
-
---
-2.7.0
-
diff --git a/0003-history-De-duplicate-identical-calls.patch b/0003-history-De-duplicate-identical-calls.patch
deleted file mode 100644
index 8e2975c7afdd..000000000000
--- a/0003-history-De-duplicate-identical-calls.patch
+++ /dev/null
@@ -1,685 +0,0 @@
-From f2a5aaa2b668ab5d87284dec9dddeb3b805b5ec4 Mon Sep 17 00:00:00 2001
-From: Emmanuel Lepage Vallee <elv1313@gmail.com>
-Date: Wed, 9 Dec 2015 08:49:10 -0500
-Subject: [PATCH 3/6] history: De-duplicate identical calls
-
-Add a new generic proxy model that can be used to
-filter out duplicate items from a model.
----
- src/CMakeLists.txt | 41 +++----
- src/dock.cpp | 100 ++---------------
- src/proxies/deduplicateproxy.cpp | 219 ++++++++++++++++++++++++++++++++++++++
- src/proxies/deduplicateproxy.h | 97 +++++++++++++++++
- src/proxies/simplerotateproxy.cpp | 9 +-
- src/proxies/simplerotateproxy.h | 9 ++
- 6 files changed, 365 insertions(+), 110 deletions(-)
- create mode 100644 src/proxies/deduplicateproxy.cpp
- create mode 100644 src/proxies/deduplicateproxy.h
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 201f107..b49dcd0 100755
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -6,6 +6,10 @@ IF(POLICY CMP0022)
- CMAKE_POLICY(SET CMP0022 NEW)
- ENDIF(POLICY CMP0022)
-
-+IF(POLICY CMP0063)
-+ CMAKE_POLICY(SET CMP0063 NEW)
-+ENDIF(POLICY CMP0063)
-+
- # set(CMAKE_AUTOMOC ON)
-
- SET(KF5_DEP_VERSION "5.6.0")
-@@ -146,8 +150,6 @@ INCLUDE_DIRECTORIES(SYSTEM
- #Build KDE specific files
- ADD_SUBDIRECTORY( klib )
-
--MESSAGE("CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
--
- IF(${CMAKE_BUILD_TYPE} MATCHES Release)
- MESSAGE("NO DEBUG OUTPUT")
- ADD_DEFINITIONS( -DQT_NO_DEBUG_OUTPUT)
-@@ -173,7 +175,7 @@ SET(
- delegates/toolbardelegate.cpp
- delegates/kdepixmapmanipulation.cpp
- proxies/simplerotateproxy.cpp
-- #proxies/valuefilterproxy.cpp
-+ proxies/deduplicateproxy.cpp
- )
-
- # Configuration pages
-@@ -195,6 +197,8 @@ SET(
- # Widgets
- SET(
- ring_kde_WIDGETS
-+ widgets/personselector.cpp
-+ widgets/contactmethodselector.cpp
- widgets/systray.cpp
- widgets/dialpad.cpp
- widgets/dockbase.cpp
-@@ -223,14 +227,6 @@ SET(
- widgets/wizard.cpp
- )
-
--# Asset contextual menus
--SET(
-- ring_kde_MENUS
-- menu/person.cpp
-- menu/call.cpp
-- menu/contactmethod.cpp
--)
--
- # Video Widgets
- IF(NOT (${ENABLE_VIDEO} MATCHES false))
- SET(
-@@ -252,6 +248,8 @@ SET(
- mainwindow.cpp
- cmd.cpp
- dock.cpp
-+ notification.cpp
-+ notification.cpp
- ringapplication.cpp
- errormessage.cpp
- kspeechinterfacesingleton.cpp
-@@ -264,7 +262,6 @@ SET(
- ${ring_kde_CONF}
- ${ring_kde_WIDGETS}
- ${ring_kde_VIDEO}
-- ${ring_kde_MENUS}
- )
-
- # generate rules for building source files from the resources
-@@ -287,6 +284,8 @@ SET(
- conf/dlgaudiorecording.ui
- conf/dlgpresence.ui
- conf/dlgfallbackperson.ui
-+ widgets/ui/personselector.ui
-+ widgets/ui/contactmethodselector.ui
- widgets/ui/player.ui
- widgets/ui/playeroverlay.ui
- widgets/ui/contactdock.ui
-@@ -302,7 +301,6 @@ SET(
- # add_subdirectory( test ) #Enable again some day, it cause compile problems for some users
-
- IF(NOT (${ENABLE_VIDEO} MATCHES false))
-- MESSAGE("VIDEO enabled")
- SET(ENABLE_VIDEO 1 CACHE BOOLEAN "Enable video")
- ADD_DEFINITIONS( -DENABLE_VIDEO=true )
- SET (
-@@ -355,12 +353,15 @@ TARGET_LINK_LIBRARIES(ring-kde
- ${LIB_RING_CLIENT_LIBRARY}
- ${OPENGL_link}
-
-- ${Qt5Widgets_LIBRARIES}
-- ${Qt5Core_LIBRARIES}
-- ${Qt5Gui_LIBRARIES}
-- ${Qt5Svg_LIBRARIES}
-- ${Qt5OpenGL_LIBRARIES}
-- ${Qt5PrintSupport_LIBRARIES}
-+ # Qt5
-+ Qt5::Widgets
-+ Qt5::Core
-+ Qt5::Gui
-+ Qt5::Svg
-+ Qt5::OpenGL
-+ Qt5::PrintSupport
-+
-+ # KF5
- KF5::I18n
- KF5::WidgetsAddons
- KF5::ConfigCore
-@@ -372,6 +373,8 @@ TARGET_LINK_LIBRARIES(ring-kde
- KF5::KIOWidgets
- KF5::Completion
- KF5::Crash
-+ KF5::NotifyConfig
-+ KF5::GlobalAccel
- # ${KDEPIMLIBS_AKONADI_KMIME_LIBS}
- # ${KDEPIMLIBS_AKONADI_LIBS}
- # ${KDEPIMLIBS_AKONADI_CONTACT_LIBS}
-diff --git a/src/dock.cpp b/src/dock.cpp
-index 4b1f88e..1d41470 100644
---- a/src/dock.cpp
-+++ b/src/dock.cpp
-@@ -23,9 +23,6 @@
- #include <QtCore/QSortFilterProxyModel>
- #include <QtCore/QTimer>
-
--//KDE
--#include <KColorScheme>
--
- //Delegates
- #include <conf/account/delegates/categorizeddelegate.h>
- #include "delegates/contactdelegate.h"
-@@ -42,11 +39,9 @@
-
- //Ring
- #include "mainwindow.h"
--#include "view.h"
- #include "actioncollection.h"
- #include "klib/kcfg_settings.h"
- #include <proxies/deduplicateproxy.h>
--#include <proxies/roletransformationproxy.h>
-
- class BookmarkSortFilterProxyModel : public QSortFilterProxyModel
- {
-@@ -92,9 +87,9 @@ Dock::Dock(QMainWindow* w) : QObject(w)
-
- // Load later to speed up the process (avoid showing while inserting items)
- QTimer::singleShot(10, [this]() {
-- CategorizedContactModel::instance().setUnreachableHidden(ConfigurationSkeleton::hideUnreachable());
-+ CategorizedContactModel::instance().setUnreachableHidden(ConfigurationSkeleton::hidePersonWithoutPhone());
- auto proxy = CategorizedContactModel::SortedProxy::instance().model();
-- m_pContactCD->setProxyModel(proxy, proxy);
-+ m_pContactCD->setProxyModel(proxy);
- m_pContactCD->setSortingModel(
- CategorizedContactModel::SortedProxy::instance().categoryModel(),
- CategorizedContactModel::SortedProxy::instance().categorySelectionModel()
-@@ -122,54 +117,13 @@ Dock::Dock(QMainWindow* w) : QObject(w)
-
-
- QTimer::singleShot(1000, [this]() {
-- // De-duplicate by name and date
- auto proxy = CategorizedHistoryModel::SortedProxy::instance().model();
-- RoleTransformationProxy* highlight = nullptr;
-- auto dedup = ConfigurationSkeleton::mergeSameDayPeer() ? new DeduplicateProxy(proxy) : nullptr;
--
-- if (dedup)
-- dedup->addFilterRole(static_cast<int>(Call::Role::DateOnly));
--
-- // Highlight missed calls
-- static const bool highlightMissedIn = ConfigurationSkeleton::highlightMissedIncomingCalls();
-- static const bool highlightMissedOut = ConfigurationSkeleton::highlightMissedOutgoingCalls();
--
-- if (highlightMissedOut || highlightMissedIn) {
-- static QColor awayBrush = KStatefulBrush( KColorScheme::Window, KColorScheme::NegativeText ).brush(QPalette::Normal).color();
-- awayBrush.setAlpha(30);
-- static QVariant missedBg(awayBrush);
--
-- highlight = new RoleTransformationProxy(dedup ? dedup : proxy);
--
-- highlight->setRole(Qt::BackgroundRole, [](const QModelIndex& idx) {
-- if (idx.data((int)Call::Role::Missed).toBool()) {
-- const Call::Direction d = qvariant_cast<Call::Direction>(
-- idx.data((int)Call::Role::Direction)
-- );
--
-- if ((highlightMissedIn && d == Call::Direction::INCOMING)
-- || (highlightMissedOut && d == Call::Direction::OUTGOING))
-- return missedBg;
-- }
--
-- return QVariant();
-- });
--
-- highlight->setSourceModel(proxy);
--
-- if (dedup)
-- dedup->setSourceModel(highlight);
-- }
-- else if (dedup)
-- dedup->setSourceModel(proxy);
--
-- if (dedup)
-- m_pHistoryDW->setProxyModel(dedup , proxy );
-- else if (highlight)
-- m_pHistoryDW->setProxyModel(highlight, proxy );
-- else
-- m_pHistoryDW->setProxyModel(proxy , proxy );
-+ auto dedup = new DeduplicateProxy(proxy);
-+ // De-duplicate by name and date
-+ dedup->addFilterRole(static_cast<int>(Call::Role::DateOnly));
-+ dedup->setSourceModel(proxy);
-
-+ m_pHistoryDW->setProxyModel(dedup);
- m_pHistoryDW->setSortingModel(
- CategorizedHistoryModel::SortedProxy::instance().categoryModel (),
- CategorizedHistoryModel::SortedProxy::instance().categorySelectionModel()
-@@ -194,8 +148,7 @@ Dock::Dock(QMainWindow* w) : QObject(w)
- CategorizedDelegate* delegate2 = new CategorizedDelegate(m_pBookmarkDW->view());
- delegate2->setChildDelegate(new HistoryDelegate(m_pHistoryDW->view()));
- m_pBookmarkDW->setDelegate(delegate2);
-- auto m = new BookmarkSortFilterProxyModel(this);
-- m_pBookmarkDW->setProxyModel(m, m);
-+ m_pBookmarkDW->setProxyModel(new BookmarkSortFilterProxyModel(this));
-
-
- //GUI
-@@ -227,10 +180,6 @@ Dock::Dock(QMainWindow* w) : QObject(w)
- connect(ActionCollection::instance()->showHistoryDockAction(), SIGNAL(toggled(bool)),m_pHistoryDW, SLOT(setVisible(bool)));
- connect(ActionCollection::instance()->showBookmarkDockAction(),SIGNAL(toggled(bool)),m_pBookmarkDW,SLOT(setVisible(bool)));
-
-- connect( ActionCollection::instance()->focusHistory (), &QAction::triggered, this, &Dock::focusHistory );
-- connect( ActionCollection::instance()->focusContact (), &QAction::triggered, this, &Dock::focusContact );
-- connect( ActionCollection::instance()->focusCall (), &QAction::triggered, this, &Dock::focusCall );
-- connect( ActionCollection::instance()->focusBookmark(), &QAction::triggered, this, &Dock::focusBookmark );
- }
-
- Dock::~Dock()
-@@ -239,9 +188,9 @@ Dock::~Dock()
- m_pHistoryDW ->setDelegate (nullptr);
- m_pBookmarkDW->setDelegate (nullptr);
-
-- m_pContactCD ->setProxyModel(nullptr, nullptr);
-- m_pHistoryDW ->setProxyModel(nullptr, nullptr);
-- m_pBookmarkDW->setProxyModel(nullptr, nullptr);
-+ m_pContactCD ->setProxyModel(nullptr);
-+ m_pHistoryDW ->setProxyModel(nullptr);
-+ m_pBookmarkDW->setProxyModel(nullptr);
-
- m_pContactCD ->deleteLater();
- m_pHistoryDW ->deleteLater();
-@@ -298,31 +247,4 @@ void Dock::updateTabIcons()
- }
- } //updateTabIcons
-
--void Dock::focusHistory()
--{
-- m_pHistoryDW->raise();
-- ActionCollection::instance()->raiseClient(false);
-- m_pHistoryDW->m_pFilterLE->setFocus(Qt::OtherFocusReason);
--}
--
--void Dock::focusContact()
--{
-- m_pContactCD->raise();
-- ActionCollection::instance()->raiseClient(false);
-- m_pContactCD->m_pFilterLE->setFocus(Qt::OtherFocusReason);
--}
--
--void Dock::focusCall()
--{
-- MainWindow::view()->raise();
-- ActionCollection::instance()->raiseClient(true);
--}
--
--void Dock::focusBookmark()
--{
-- m_pBookmarkDW->raise();
-- ActionCollection::instance()->raiseClient(false);
-- m_pBookmarkDW->m_pFilterLE->setFocus(Qt::OtherFocusReason);
--}
--
- #include <dock.moc>
-diff --git a/src/proxies/deduplicateproxy.cpp b/src/proxies/deduplicateproxy.cpp
-new file mode 100644
-index 0000000..ccde71a
---- /dev/null
-+++ b/src/proxies/deduplicateproxy.cpp
-@@ -0,0 +1,219 @@
-+/****************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
-+ * *
-+ * This library is free software; you can redistribute it and/or *
-+ * modify it under the terms of the GNU Lesser General Public *
-+ * License as published by the Free Software Foundation; either *
-+ * version 2.1 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 *
-+ * Lesser 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 "deduplicateproxy.h"
-+
-+#include <QtCore/QDebug>
-+
-+typedef std::function<bool(const QModelIndex&, const QModelIndex&)> Comparator;
-+
-+class DeduplicateProxyPrivate final
-+{
-+public:
-+ // Attributes
-+ bool m_AddChildren { false };
-+ Comparator m_fCompare { };
-+ DeduplicateProxy::Mode m_Mode { DeduplicateProxy::Mode::ROLE };
-+ bool m_isSrcProxy { false };
-+ QVector<int> m_lOtherRoles { };
-+ int m_HiddenRoleId { -1 };
-+ bool m_isHiddenRoleSet{ false };
-+ QString m_HiddenRoleName { };
-+};
-+
-+DeduplicateProxy::DeduplicateProxy(QObject* parent) : QSortFilterProxyModel(parent),
-+d_ptr(new DeduplicateProxyPrivate())
-+{
-+}
-+
-+void DeduplicateProxy::setComparator(const Comparator& f)
-+{
-+ d_ptr->m_Mode = DeduplicateProxy::Mode::FUNCTION;
-+ d_ptr->m_fCompare = f;
-+
-+ invalidateFilter();
-+}
-+
-+/**
-+ * Useful when there is a main filter role, but some items need to be kept.
-+ *
-+ * If any role added to this list is different, the index wont be hidden
-+ *
-+ * For example using this proxy to create instant messaging thread if they
-+ * come from the same person, but also create different threads if the date
-+ * differ.
-+ */
-+void DeduplicateProxy::addFilterRole(int role)
-+{
-+ d_ptr->m_lOtherRoles << role;
-+
-+ invalidateFilter();
-+}
-+
-+QVector<int> DeduplicateProxy::filterRoles() const
-+{
-+ return d_ptr->m_lOtherRoles;// + filterRole();
-+}
-+
-+/**
-+ * Add rejected items as children of the non-rejected matching item
-+ *
-+ * @warning This is ignored for indexes that already have children
-+ */
-+void DeduplicateProxy::setAddChildren(bool add)
-+{
-+ d_ptr->m_AddChildren = add;
-+}
-+
-+bool DeduplicateProxy::areChildrenAdded()
-+{
-+ return d_ptr->m_AddChildren;
-+}
-+
-+Comparator DeduplicateProxy::comparator()
-+{
-+ return d_ptr->m_fCompare;
-+}
-+
-+/**
-+ * Check if the source_row index is identical to the previous index
-+ */
-+bool DeduplicateProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-+{
-+ // Get both source QModelIndex and compare them
-+ if (source_row > 0) {
-+ const QModelIndex idx = sourceModel()->index(source_row, filterKeyColumn(), source_parent);
-+
-+ // It is correct to assume sourceModelIndex - 1 will be part of the same group
-+ if (idx.row() > 0) {
-+ const QModelIndex sibling = sourceModel()->index(idx.row() - 1, idx.column(), idx.parent());
-+
-+ bool accept = false;
-+
-+ // Allow to filter with more than one role, apply only if they exist
-+ foreach(const int r, d_ptr->m_lOtherRoles) {
-+ const QVariant v1 = idx.data (r);
-+ const QVariant v2 = sibling.data(r);
-+
-+ // Yes, this is an "=", not "=="
-+ if ((accept = !(v1.isValid() && v2.isValid() && (v1 == v2))))
-+ break;
-+ }
-+
-+ return accept || idx.data(filterRole()) != sibling.data(filterRole());
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+//TODO support for columns too
-+
-+///Return the number of hidden siblings of idx
-+int DeduplicateProxy::hiddenSiblingCount(const QModelIndex& idx) const
-+{
-+ if ((!sourceModel()) || (!idx.isValid()) || idx.model() != this)
-+ return 0;
-+
-+ const QModelIndex nextIdx = index(idx.row()+1, idx.column(), idx.parent());
-+
-+ const QModelIndex srcIdx = mapToSource(idx);
-+
-+ if (!nextIdx.isValid())
-+ return sourceModel()->rowCount(srcIdx.parent()) - srcIdx.row();
-+
-+ const QModelIndex srcNextIdx = mapToSource(nextIdx);
-+
-+ return srcNextIdx.row() - srcIdx.row();
-+}
-+
-+/**
-+ * Return the list of source model QModelIndex that have been hidden
-+ */
-+QList<QModelIndex> DeduplicateProxy::hiddenSiblings(const QModelIndex& idx) const
-+{
-+ const int count = hiddenSiblingCount(idx);
-+
-+ if (!count)
-+ return {};
-+
-+ QList<QModelIndex> ret;
-+
-+ const int parentRow = mapToSource(idx).row();
-+ const QModelIndex srcParentIdx = mapToSource(idx).parent();
-+
-+ for (int i = 0; i < count; i++)
-+ ret << sourceModel()->index(parentRow + count, idx.column(), srcParentIdx);
-+
-+ return ret;
-+}
-+
-+/**
-+ * Add a model data role to report the number of hidden siblings
-+ */
-+void DeduplicateProxy::setHiddenCountRole(int role, const QString& name)
-+{
-+ d_ptr->m_isHiddenRoleSet = true;
-+ d_ptr->m_HiddenRoleId = role;
-+ d_ptr->m_HiddenRoleName = name;
-+}
-+
-+///This proxy doesn't sort anything
-+void DeduplicateProxy::sort ( int column, Qt::SortOrder order)
-+{
-+ sourceModel()->sort(column, order);
-+}
-+
-+void DeduplicateProxy::setSourceModel ( QAbstractItemModel * sourceModel )
-+{
-+ QSortFilterProxyModel::setSourceModel(sourceModel);
-+
-+ d_ptr->m_isSrcProxy = sourceModel && qobject_cast<QAbstractProxyModel*>(sourceModel);
-+
-+ //TODO find a way to catch setFilterString to forward it as this proxy
-+ // is likely in front of another QSortFilterProxyModel re-implement ::invalidateFilter?
-+}
-+
-+int DeduplicateProxy::rowCount(const QModelIndex& parent) const
-+{
-+ if (!d_ptr->m_AddChildren)
-+ return QSortFilterProxyModel::rowCount(parent);
-+
-+
-+ //TODO ::index, ::mapToSource and ::mapFromSource still need to be implemented
-+ /*int hidden = 0;
-+ // Handle when the rejected items need to be added as children
-+ if (d_ptr->m_AddChildren && (hidden = hiddenSiblingCount(parent))) {
-+ const QModelIndex src = mapToSource(parent);
-+
-+ // Only add the children if there is none
-+ int parentRowCount = sourceModel()->rowCount(src);
-+
-+ if (!parentRowCount)
-+ return hidden;
-+ }*/
-+
-+ return QSortFilterProxyModel::rowCount(parent); //TODO
-+}
-+
-+QVariant DeduplicateProxy::data( const QModelIndex& index, int role ) const
-+{
-+ if (d_ptr->m_isHiddenRoleSet && role == d_ptr->m_HiddenRoleId)
-+ return hiddenSiblingCount(index);
-+
-+ return QSortFilterProxyModel::data(index, role);
-+}
-diff --git a/src/proxies/deduplicateproxy.h b/src/proxies/deduplicateproxy.h
-new file mode 100644
-index 0000000..d2cee28
---- /dev/null
-+++ b/src/proxies/deduplicateproxy.h
-@@ -0,0 +1,97 @@
-+/****************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
-+ * *
-+ * This library is free software; you can redistribute it and/or *
-+ * modify it under the terms of the GNU Lesser General Public *
-+ * License as published by the Free Software Foundation; either *
-+ * version 2.1 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 *
-+ * Lesser 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 DEDUPLICATEPROXY_H
-+#define DEDUPLICATEPROXY_H
-+
-+#include <functional>
-+
-+#include <QtCore/QSortFilterProxyModel>
-+
-+class DeduplicateProxyPrivate;
-+
-+/**
-+ * This proxy take a role and remove additional rows matching the operator==
-+ * of the role. It only deduplication indexes without child.
-+ *
-+ * Further QIdentityProxyModels can be created to extract the number of
-+ *
-+ * Example:
-+ * ==Without addChildren== ==With addChildren==
-+ * Foo Foo Foo
-+ * |-> Bar |-> Bar |-> Bar
-+ * |-> Bar |-> Baz |-> Bar
-+ * |-> Bar |-> Bar |-> Bar
-+ * |-> Baz Bar |-> Baz
-+ * |-> Bar |-> Foo |-> Bar
-+ * Bar ====== > |-> Baz Bar
-+ * |-> Foo Bar |-> Foo
-+ * |-> Baz |-> Foo |-> Baz
-+ * Bar Bar
-+ * |-> Foo |-> Foo
-+ * |-> Foo |-> Foo
-+ *
-+ * @warning The default role comparaison only work for QVariant basic types \
-+ * for custom types, it is better to use the function comparaison
-+ *
-+ * @note The filter string and sort role will be forwarded down the proxy chain\
-+ * so this model can be used as a drop in replacment in existing code TODO
-+ */
-+class DeduplicateProxy : public QSortFilterProxyModel
-+{
-+ Q_OBJECT
-+
-+public:
-+ enum class Mode {
-+ ROLE,
-+ FUNCTION //TODO
-+ };
-+
-+ explicit DeduplicateProxy(QObject* parent = nullptr);
-+
-+ void addFilterRole(int role);
-+
-+ QVector<int> filterRoles() const;
-+
-+ void setComparator(const std::function<bool(const QModelIndex&, const QModelIndex&)>& f); //TODO
-+
-+ void setHiddenCountRole(int role, const QString& name = QString());
-+
-+ QList<QModelIndex> hiddenSiblings(const QModelIndex& idx) const;
-+
-+ void setAddChildren(bool add); //TODO
-+
-+ int hiddenSiblingCount(const QModelIndex& idx) const;
-+
-+ bool areChildrenAdded(); //TODO
-+ std::function<bool(const QModelIndex&, const QModelIndex&)> comparator(); //TODO
-+
-+ // Model override
-+ virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
-+ virtual void sort ( int column, Qt::SortOrder order) override;
-+ virtual void setSourceModel ( QAbstractItemModel * sourceModel ) override;
-+ virtual int rowCount(const QModelIndex& parent) const override;
-+ virtual QVariant data( const QModelIndex& index, int role ) const override;
-+
-+
-+
-+private:
-+ DeduplicateProxyPrivate* d_ptr;
-+ Q_DECLARE_PRIVATE(DeduplicateProxy)
-+};
-+
-+#endif
-\ No newline at end of file
-diff --git a/src/proxies/simplerotateproxy.cpp b/src/proxies/simplerotateproxy.cpp
-index ab3fe47..03a9fb1 100644
---- a/src/proxies/simplerotateproxy.cpp
-+++ b/src/proxies/simplerotateproxy.cpp
-@@ -19,6 +19,7 @@
-
- SimpleRotateProxy::SimpleRotateProxy(QObject * parent) : QAbstractProxyModel(parent)
- {
-+ //TODO implement it correctly, this is the lazy way
- connect(this, &SimpleRotateProxy::sourceModelChanged, [this]() {
- connect(this->sourceModel(),&QAbstractItemModel::dataChanged,[this](const QModelIndex&, const QModelIndex&) {
- emit this->layoutChanged();
-@@ -77,10 +78,14 @@ QModelIndex SimpleRotateProxy::parent(const QModelIndex& ) const
-
- int SimpleRotateProxy::rowCount(const QModelIndex& idx) const
- {
-- return sourceModel()->columnCount(idx);
-+ return idx.parent().isValid() ?
-+ sourceModel()->rowCount (idx) :
-+ sourceModel()->columnCount(idx);
- }
-
- int SimpleRotateProxy::columnCount(const QModelIndex& idx) const
- {
-- return sourceModel()->rowCount(idx);
-+ return idx.parent().isValid() ?
-+ sourceModel()->columnCount(idx) :
-+ sourceModel()->rowCount (idx);
- }
-diff --git a/src/proxies/simplerotateproxy.h b/src/proxies/simplerotateproxy.h
-index 255ba1c..ce61a03 100644
---- a/src/proxies/simplerotateproxy.h
-+++ b/src/proxies/simplerotateproxy.h
-@@ -36,6 +36,15 @@
- * displaying them horizontally create a better visual separation.
- *
- * 3) The source model is external and display data in inverted order
-+ *
-+ * Example:
-+ *
-+ * |-> Foo
-+ * |-> Bar -----------------
-+ * |-> Baz ====> | | |
-+ * |-> Foobar Foo Bar Baz
-+ * |-> Foobaz |-> Foobar
-+ * |-> Foobaz
- */
- class SimpleRotateProxy : public QAbstractProxyModel
- {
---
-2.7.0
-
diff --git a/0004-akonadi-Make-it-optional.patch b/0004-akonadi-Make-it-optional.patch
deleted file mode 100644
index 8fb5b7bd640f..000000000000
--- a/0004-akonadi-Make-it-optional.patch
+++ /dev/null
@@ -1,234 +0,0 @@
-From db0bdfdc7473d60a694a14813512acca48066613 Mon Sep 17 00:00:00 2001
-From: Emmanuel Lepage Vallee <elv1313@gmail.com>
-Date: Sat, 19 Dec 2015 23:08:50 -0500
-Subject: [PATCH 4/6] akonadi: Make it optional
-
-Not all distributions ship with a KF5 version of Akonadi yet.
----
- CMakeLists.txt | 16 ++++++++++----
- src/CMakeLists.txt | 4 ----
- src/klib/CMakeLists.txt | 44 ++++++++++++++++++++++++++++---------
- src/klib/itemmodelserialization.cpp | 11 +++++++++-
- src/mainwindow.cpp | 16 +++++++++-----
- 5 files changed, 67 insertions(+), 24 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 8372310..23eb4bd 100755
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -15,8 +15,9 @@ ENDIF(POLICY CMP0028)
- SET(PROJECT_VERSION "2.2.0")
- PROJECT(ring-kde)
-
--SET(QT_MIN_VERSION "5.2.0")
--SET(KF5_DEP_VERSION "5.6.0")
-+SET(QT_MIN_VERSION "5.2.0" )
-+SET(KF5_DEP_VERSION "5.6.0" )
-+SET(AKO_DEP_VERSION "4.89.0")
-
- SET(LOCAL_CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" )
- SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH} ${LOCAL_CMAKE_MODULE_PATH}" )
-@@ -69,8 +70,15 @@ FIND_PACKAGE(KF5 "${KF5_DEP_VERSION}" REQUIRED COMPONENTS
- Crash
- )
-
--# SET(AKONADI_MIN_VERSION 1.0)
--# FIND_PACKAGE(Akonadi QUIET NO_MODULE ${AKONADI_MIN_VERSION})
-+FIND_PACKAGE(KF5 "${AKO_DEP_VERSION}" COMPONENTS
-+ Akonadi
-+ AkonadiContact
-+ Contacts
-+)
-+
-+IF ( KF5_AKONADI_FOUND AND KF5_AKONADICONTACT_FOUND AND KF5_CONTACTS_FOUND)
-+ ADD_DEFINITIONS("-DENABLE_AKONADI=1")
-+ENDIF()
-
- # INCLUDE ( KDE4Defaults )
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index b49dcd0..67c4e2b 100755
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -375,10 +375,6 @@ TARGET_LINK_LIBRARIES(ring-kde
- KF5::Crash
- KF5::NotifyConfig
- KF5::GlobalAccel
--# ${KDEPIMLIBS_AKONADI_KMIME_LIBS}
--# ${KDEPIMLIBS_AKONADI_LIBS}
--# ${KDEPIMLIBS_AKONADI_CONTACT_LIBS}
--# ${X11_LIBRARIES}
- )
-
- IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-diff --git a/src/klib/CMakeLists.txt b/src/klib/CMakeLists.txt
-index be24937..03c07b6 100644
---- a/src/klib/CMakeLists.txt
-+++ b/src/klib/CMakeLists.txt
-@@ -4,6 +4,18 @@ ADD_DEFINITIONS("-std=c++0x")
-
- PROJECT(libkring)
-
-+IF(POLICY CMP0048)
-+ CMAKE_POLICY(SET CMP0048 NEW)
-+ENDIF(POLICY CMP0048)
-+
-+IF(POLICY CMP0017)
-+ CMAKE_POLICY(SET CMP0017 NEW)
-+ENDIF(POLICY CMP0017)
-+
-+IF(POLICY CMP0028)
-+ CMAKE_POLICY(SET CMP0028 NEW)
-+ENDIF(POLICY CMP0028)
-+
- FIND_PACKAGE(ECM 1.1.0 REQUIRED NO_MODULE)
- SET (CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
-
-@@ -34,6 +46,11 @@ FIND_PACKAGE(KF5 COMPONENTS
- Contacts
- )
-
-+IF ( KF5_AKONADI_FOUND AND KF5_AKONADICONTACT_FOUND AND KF5_CONTACTS_FOUND)
-+ SET(AKONADI_FOUND 1)
-+ENDIF()
-+
-+
- INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES} ${Qt5Core_INCLUDES} ${LIB_RING_CLIENT_INCLUDE_DIR})
-
- ADD_DEFINITIONS(${Qt5Core_DEFINITIONS})
-@@ -45,16 +62,17 @@ SET(GENERIC_LIB_VERSION "2.0.0")
- #File to compile
- SET( libkring_LIB_SRCS
- helperfunctions.cpp
--# akonadibackend.cpp
--# akonadicontactcollectionmodel.cpp
- kdeprofilepersistor.cpp
- itemmodelserialization.cpp
- )
-
--SET(libkring_LIB_SRCS
-- ${libkring_LIB_SRCS}
-- akonadibackend.cpp
--)
-+
-+IF ( ${AKONADI_FOUND} )
-+ SET(libkring_LIB_SRCS
-+ ${libkring_LIB_SRCS}
-+ akonadibackend.cpp
-+ )
-+ENDIF()
-
- KCONFIG_ADD_KCFG_FILES (libkring_LIB_SRCS kcfg_settings.kcfgc)
-
-@@ -69,13 +87,19 @@ target_link_libraries( libkring
- KF5::WidgetsAddons
- KF5::ConfigCore
- KF5::ConfigGui
-- KF5::AkonadiCore
-- KF5::AkonadiContact
-- KF5::Contacts
- )
-
-+# Akonadi support is optional
-+IF ( ${AKONADI_FOUND} )
-+ target_link_libraries( libkring
-+ KF5::AkonadiCore
-+ KF5::AkonadiContact
-+ KF5::Contacts
-+ )
-+ENDIF()
-+
- SET( libkring_LIB_HDRS
--# akonadibackend.h
-+ akonadibackend.h
- helperfunctions.h
- itemmodelserialization.h
- )
-diff --git a/src/klib/itemmodelserialization.cpp b/src/klib/itemmodelserialization.cpp
-index 6da8cc1..8152d12 100644
---- a/src/klib/itemmodelserialization.cpp
-+++ b/src/klib/itemmodelserialization.cpp
-@@ -19,7 +19,10 @@
-
- #include <personmodel.h>
-
--#include "akonadibackend.h"
-+
-+#ifdef ENABLE_AKONADI
-+ #include "akonadibackend.h"
-+#endif
-
- #include "collectioninterface.h"
- #include "kcfg_settings.h"
-@@ -67,12 +70,18 @@ bool ItemModelStateSerialization::setChecked(const CollectionInterface* backend,
- CollectionInterface* ItemModelStateSerialization::preferredCollection(CollectionManagerInterfaceBase* manager, FlagPack<CollectionInterface::SupportedFeatures> features, FlagPack<Interfaces::ItemModelStateSerializerI::Hints> hints )
- {
- Q_UNUSED(hints)
-+
-+#ifdef ENABLE_AKONADI
- if (manager == &PersonModel::instance()) {
- foreach(CollectionInterface* i, PersonModel::instance().collections(features)) {
- if (dynamic_cast<AkonadiBackend*>(i)) //TODO use something better
- return i;
- }
- }
-+#else
-+ Q_UNUSED(manager )
-+ Q_UNUSED(features)
-+#endif
-
- return nullptr;
- }
-diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
-index 1d0553d..c8cf752 100755
---- a/src/mainwindow.cpp
-+++ b/src/mainwindow.cpp
-@@ -86,9 +86,13 @@
- #include <video/renderer.h>
- #include "ringapplication.h"
- #include "widgets/dockbase.h"
--#include "klib/akonadibackend.h"
-+
-+#ifdef ENABLE_AKONADI
-+ #include "klib/akonadibackend.h"
-+#endif
-+
- #ifdef ENABLE_VIDEO
--#include "widgets/videodock.h"
-+ #include "widgets/videodock.h"
- #endif
-
- MainWindow* MainWindow::m_sApp = nullptr;
-@@ -177,9 +181,9 @@ MainWindow::MainWindow(QWidget* parent)
- GlobalInstances::setInterface<ItemModelStateSerialization>();
- GlobalInstances::itemModelStateSerializer().load();
-
-+#ifdef ENABLE_AKONADI
- AkonadiBackend::initCollections();
--// PersonModel::instance().backendModel()->load();
--// AccountModel::instance().setDefaultAccount(AccountModel::instance().getAccountById(ConfigurationSkeleton::defaultAccountId()));
-+#endif
-
- init = true;
-
-@@ -223,7 +227,6 @@ MainWindow::MainWindow(QWidget* parent)
- m_pCentralDW->setTitleBarWidget(new QWidget());
- m_pCentralDW->setContentsMargins(0,0,0,0);
- m_pView->setContentsMargins (0,0,0,0);
-- addDockWidget( Qt::BottomDockWidgetArea, m_pCentralDW );
- m_pCentralDW->setObjectName( "callDock" );
- m_pCentralDW->show();
-
-@@ -233,6 +236,9 @@ MainWindow::MainWindow(QWidget* parent)
- m_pTrayIcon = new SysTray ( this->windowIcon(), this );
-
- m_pDock = new Dock(this);
-+
-+ addDockWidget( Qt::BottomDockWidgetArea, m_pCentralDW );
-+
- connect(m_pCentralDW ,SIGNAL(visibilityChanged(bool)),m_pDock,SLOT(updateTabIcons()));
-
- selectCallTab();
---
-2.7.0
-
diff --git a/0005-Fix-CMakeLists.txt.patch b/0005-Fix-CMakeLists.txt.patch
deleted file mode 100644
index cd015aa0dc87..000000000000
--- a/0005-Fix-CMakeLists.txt.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From b6e20f613203d98e549d0d1e0924ef273513e9e2 Mon Sep 17 00:00:00 2001
-From: Pierre Choffet <peuc@wanadoo.fr>
-Date: Thu, 7 Jan 2016 15:44:22 -0500
-Subject: [PATCH 5/6] Fix CMakeLists.txt
-
----
- src/CMakeLists.txt | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 67c4e2b..01fd97c 100755
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -15,7 +15,7 @@ ENDIF(POLICY CMP0063)
- SET(KF5_DEP_VERSION "5.6.0")
- SET(QT_MIN_VERSION "5.2.0")
-
--FIND_PACKAGE ( KF5 REQUIRED )
-+FIND_PACKAGE ( KF5 REQUIRED NotifyConfig GlobalAccel)
-
- find_package (ECM 1.1.0 REQUIRED NO_MODULE)
- set (CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
---
-2.7.0
-
diff --git a/0006-contact-Add-new-basic-contact-selection-dialog.patch b/0006-contact-Add-new-basic-contact-selection-dialog.patch
deleted file mode 100644
index 9d143615133a..000000000000
--- a/0006-contact-Add-new-basic-contact-selection-dialog.patch
+++ /dev/null
@@ -1,461 +0,0 @@
-From 962788b7c0956953c688170cbe5c234e0a6c1876 Mon Sep 17 00:00:00 2001
-From: Emmanuel Lepage Vallee <elv1313@gmail.com>
-Date: Sat, 5 Dec 2015 21:20:59 -0500
-Subject: [PATCH 6/6] contact: Add new (basic) contact selection dialog
-
-This will be expanded in further commits to improve assigning contacts
-to unassigned contact methods.
----
- src/widgets/contactmethodselector.cpp | 40 ++++++++++
- src/widgets/contactmethodselector.h | 42 +++++++++++
- src/widgets/personselector.cpp | 47 ++++++++++++
- src/widgets/personselector.h | 42 +++++++++++
- src/widgets/ui/contactmethodselector.ui | 126 ++++++++++++++++++++++++++++++++
- src/widgets/ui/personselector.ui | 100 +++++++++++++++++++++++++
- 6 files changed, 397 insertions(+)
- create mode 100644 src/widgets/contactmethodselector.cpp
- create mode 100644 src/widgets/contactmethodselector.h
- create mode 100644 src/widgets/personselector.cpp
- create mode 100644 src/widgets/personselector.h
- create mode 100644 src/widgets/ui/contactmethodselector.ui
- create mode 100644 src/widgets/ui/personselector.ui
-
-diff --git a/src/widgets/contactmethodselector.cpp b/src/widgets/contactmethodselector.cpp
-new file mode 100644
-index 0000000..d2a0728
---- /dev/null
-+++ b/src/widgets/contactmethodselector.cpp
-@@ -0,0 +1,40 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#include "contactmethodselector.h"
-+
-+// Qt
-+#include <QtCore/QSortFilterProxyModel>
-+
-+#include <phonedirectorymodel.h>
-+#include <contactmethod.h>
-+
-+ContactMethodSelector::ContactMethodSelector(QWidget* parent) : QDialog(parent)
-+{
-+ setupUi(this);
-+
-+ m_pSortedContacts = new QSortFilterProxyModel(this);
-+ m_pSortedContacts->setSourceModel ( &PhoneDirectoryModel::instance() );
-+ m_pSortedContacts->setSortRole ( Qt::DisplayRole );
-+ m_pSortedContacts->setFilterCaseSensitivity( Qt::CaseInsensitive );
-+ m_pSortedContacts->setSortCaseSensitivity ( Qt::CaseInsensitive );
-+
-+
-+ connect(m_pFilterLE ,SIGNAL(filterStringChanged(QString)), m_pSortedContacts, SLOT(setFilterRegExp(QString)) );
-+
-+ listView->setModel(m_pSortedContacts);
-+}
-diff --git a/src/widgets/contactmethodselector.h b/src/widgets/contactmethodselector.h
-new file mode 100644
-index 0000000..7819856
---- /dev/null
-+++ b/src/widgets/contactmethodselector.h
-@@ -0,0 +1,42 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#ifndef CONTACTMETHODSELECTOR_H
-+#define CONTACTMETHODSELECTOR_H
-+
-+#include "ui_contactmethodselector.h"
-+
-+#include <QtWidgets/QDialog>
-+
-+class QSortFilterProxyModel;
-+
-+class ContactMethod;
-+
-+class ContactMethodSelector : public QDialog, public Ui_ContactMethodSelector
-+{
-+ Q_OBJECT
-+public:
-+ explicit ContactMethodSelector(QWidget* parent = nullptr);
-+ virtual ~ContactMethodSelector() = default;
-+
-+private:
-+ QSortFilterProxyModel* m_pSortedContacts;
-+ QSortFilterProxyModel* m_pNearMatchContact;
-+
-+};
-+
-+#endif
-\ No newline at end of file
-diff --git a/src/widgets/personselector.cpp b/src/widgets/personselector.cpp
-new file mode 100644
-index 0000000..97e8af9
---- /dev/null
-+++ b/src/widgets/personselector.cpp
-@@ -0,0 +1,47 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#include "personselector.h"
-+
-+// Qt
-+#include <QtCore/QSortFilterProxyModel>
-+
-+#include <personmodel.h>
-+#include <contactmethod.h>
-+
-+PersonSelector::PersonSelector(QWidget* parent, const ContactMethod* cm) : QDialog(parent)
-+{
-+ setupUi(this);
-+
-+ m_pSortedContacts = new QSortFilterProxyModel(this);
-+ m_pSortedContacts->setSourceModel ( &PersonModel::instance() );
-+ m_pSortedContacts->setSortRole ( Qt::DisplayRole );
-+ m_pSortedContacts->setFilterCaseSensitivity( Qt::CaseInsensitive );
-+ m_pSortedContacts->setSortCaseSensitivity ( Qt::CaseInsensitive );
-+
-+ if (cm) {
-+ m_pNearMatchContact = new QSortFilterProxyModel(this);
-+ m_pNearMatchContact->setSourceModel ( &PersonModel::instance() );
-+ m_pNearMatchContact->setFilterFixedString( cm->primaryName() );
-+ }
-+
-+ nearMatch->setVisible(cm != nullptr && m_pNearMatchContact->rowCount());
-+
-+ connect(m_pFilterLE ,SIGNAL(filterStringChanged(QString)), m_pSortedContacts, SLOT(setFilterRegExp(QString)) );
-+
-+ listView->setModel(m_pSortedContacts);
-+}
-\ No newline at end of file
-diff --git a/src/widgets/personselector.h b/src/widgets/personselector.h
-new file mode 100644
-index 0000000..09b6332
---- /dev/null
-+++ b/src/widgets/personselector.h
-@@ -0,0 +1,42 @@
-+/***************************************************************************
-+ * Copyright (C) 2015 by Emmanuel Lepage Vallee *
-+ * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.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 3 of the License, or *
-+ * (at your option) any later version. *
-+ * *
-+ * This program is distributed in the hope that it will be useful, *
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
-+ * GNU General Public License for more details. *
-+ * *
-+ * You should have received a copy of the GNU General Public License *
-+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
-+ **************************************************************************/
-+#ifndef PERSONSELECTOR_H
-+#define PERSONSELECTOR_H
-+
-+#include "ui_personselector.h"
-+
-+#include <QtWidgets/QDialog>
-+
-+class QSortFilterProxyModel;
-+
-+class ContactMethod;
-+
-+class PersonSelector : public QDialog, public Ui_PersonSelector
-+{
-+ Q_OBJECT
-+public:
-+ explicit PersonSelector(QWidget* parent = nullptr, const ContactMethod* cm = nullptr);
-+ virtual ~PersonSelector() = default;
-+
-+private:
-+ QSortFilterProxyModel* m_pSortedContacts;
-+ QSortFilterProxyModel* m_pNearMatchContact;
-+
-+};
-+
-+#endif
-\ No newline at end of file
-diff --git a/src/widgets/ui/contactmethodselector.ui b/src/widgets/ui/contactmethodselector.ui
-new file mode 100644
-index 0000000..dd69b93
---- /dev/null
-+++ b/src/widgets/ui/contactmethodselector.ui
-@@ -0,0 +1,126 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<ui version="4.0">
-+ <class>ContactMethodSelector</class>
-+ <widget class="QDialog" name="ContactMethodSelector">
-+ <property name="geometry">
-+ <rect>
-+ <x>0</x>
-+ <y>0</y>
-+ <width>400</width>
-+ <height>300</height>
-+ </rect>
-+ </property>
-+ <property name="windowTitle">
-+ <string>Dialog</string>
-+ </property>
-+ <layout class="QVBoxLayout" name="verticalLayout_2">
-+ <item>
-+ <widget class="QGroupBox" name="groupBox">
-+ <property name="title">
-+ <string>Existing</string>
-+ </property>
-+ <layout class="QVBoxLayout" name="verticalLayout">
-+ <item>
-+ <widget class="QListView" name="listView"/>
-+ </item>
-+ <item>
-+ <widget class="FilterLineEdit" name="m_pFilterLE">
-+ <property name="placeholderText">
-+ <string>Search</string>
-+ </property>
-+ </widget>
-+ </item>
-+ </layout>
-+ </widget>
-+ </item>
-+ <item>
-+ <widget class="QGroupBox" name="groupBox_2">
-+ <property name="title">
-+ <string>New</string>
-+ </property>
-+ <layout class="QFormLayout" name="formLayout_2">
-+ <item row="0" column="0">
-+ <widget class="QLabel" name="label_2">
-+ <property name="text">
-+ <string>Phone number</string>
-+ </property>
-+ </widget>
-+ </item>
-+ <item row="0" column="1">
-+ <widget class="QLineEdit" name="lineEdit"/>
-+ </item>
-+ <item row="1" column="0">
-+ <widget class="QLabel" name="label">
-+ <property name="text">
-+ <string>Account</string>
-+ </property>
-+ </widget>
-+ </item>
-+ <item row="1" column="1">
-+ <widget class="QComboBox" name="comboBox"/>
-+ </item>
-+ </layout>
-+ </widget>
-+ </item>
-+ <item>
-+ <widget class="QDialogButtonBox" name="buttonBox">
-+ <property name="orientation">
-+ <enum>Qt::Horizontal</enum>
-+ </property>
-+ <property name="standardButtons">
-+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-+ </property>
-+ </widget>
-+ </item>
-+ </layout>
-+ </widget>
-+ <customwidgets>
-+ <customwidget>
-+ <class>FilterLineEdit</class>
-+ <extends>QLineEdit</extends>
-+ <header>widgets/filterlineedit.h</header>
-+ </customwidget>
-+ </customwidgets>
-+ <tabstops>
-+ <tabstop>m_pFilterLE</tabstop>
-+ <tabstop>listView</tabstop>
-+ <tabstop>lineEdit</tabstop>
-+ <tabstop>comboBox</tabstop>
-+ <tabstop>buttonBox</tabstop>
-+ </tabstops>
-+ <resources/>
-+ <connections>
-+ <connection>
-+ <sender>buttonBox</sender>
-+ <signal>accepted()</signal>
-+ <receiver>ContactMethodSelector</receiver>
-+ <slot>accept()</slot>
-+ <hints>
-+ <hint type="sourcelabel">
-+ <x>248</x>
-+ <y>254</y>
-+ </hint>
-+ <hint type="destinationlabel">
-+ <x>157</x>
-+ <y>274</y>
-+ </hint>
-+ </hints>
-+ </connection>
-+ <connection>
-+ <sender>buttonBox</sender>
-+ <signal>rejected()</signal>
-+ <receiver>ContactMethodSelector</receiver>
-+ <slot>reject()</slot>
-+ <hints>
-+ <hint type="sourcelabel">
-+ <x>316</x>
-+ <y>260</y>
-+ </hint>
-+ <hint type="destinationlabel">
-+ <x>286</x>
-+ <y>274</y>
-+ </hint>
-+ </hints>
-+ </connection>
-+ </connections>
-+</ui>
-diff --git a/src/widgets/ui/personselector.ui b/src/widgets/ui/personselector.ui
-new file mode 100644
-index 0000000..c415c37
---- /dev/null
-+++ b/src/widgets/ui/personselector.ui
-@@ -0,0 +1,100 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<ui version="4.0">
-+ <class>PersonSelector</class>
-+ <widget class="QDialog" name="PersonSelector">
-+ <property name="geometry">
-+ <rect>
-+ <x>0</x>
-+ <y>0</y>
-+ <width>400</width>
-+ <height>300</height>
-+ </rect>
-+ </property>
-+ <property name="windowTitle">
-+ <string>Dialog</string>
-+ </property>
-+ <layout class="QVBoxLayout" name="verticalLayout">
-+ <item>
-+ <widget class="QSplitter" name="splitter">
-+ <property name="orientation">
-+ <enum>Qt::Vertical</enum>
-+ </property>
-+ <widget class="QListView" name="nearMatch">
-+ <property name="sizePolicy">
-+ <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
-+ <horstretch>0</horstretch>
-+ <verstretch>0</verstretch>
-+ </sizepolicy>
-+ </property>
-+ </widget>
-+ <widget class="QListView" name="listView"/>
-+ </widget>
-+ </item>
-+ <item>
-+ <widget class="FilterLineEdit" name="m_pFilterLE">
-+ <property name="placeholderText">
-+ <string>Search</string>
-+ </property>
-+ </widget>
-+ </item>
-+ <item>
-+ <widget class="QDialogButtonBox" name="buttonBox">
-+ <property name="orientation">
-+ <enum>Qt::Horizontal</enum>
-+ </property>
-+ <property name="standardButtons">
-+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-+ </property>
-+ </widget>
-+ </item>
-+ </layout>
-+ </widget>
-+ <customwidgets>
-+ <customwidget>
-+ <class>FilterLineEdit</class>
-+ <extends>QLineEdit</extends>
-+ <header>widgets/filterlineedit.h</header>
-+ </customwidget>
-+ </customwidgets>
-+ <tabstops>
-+ <tabstop>m_pFilterLE</tabstop>
-+ <tabstop>listView</tabstop>
-+ <tabstop>nearMatch</tabstop>
-+ <tabstop>buttonBox</tabstop>
-+ </tabstops>
-+ <resources/>
-+ <connections>
-+ <connection>
-+ <sender>buttonBox</sender>
-+ <signal>accepted()</signal>
-+ <receiver>PersonSelector</receiver>
-+ <slot>accept()</slot>
-+ <hints>
-+ <hint type="sourcelabel">
-+ <x>248</x>
-+ <y>254</y>
-+ </hint>
-+ <hint type="destinationlabel">
-+ <x>157</x>
-+ <y>274</y>
-+ </hint>
-+ </hints>
-+ </connection>
-+ <connection>
-+ <sender>buttonBox</sender>
-+ <signal>rejected()</signal>
-+ <receiver>PersonSelector</receiver>
-+ <slot>reject()</slot>
-+ <hints>
-+ <hint type="sourcelabel">
-+ <x>316</x>
-+ <y>260</y>
-+ </hint>
-+ <hint type="destinationlabel">
-+ <x>286</x>
-+ <y>274</y>
-+ </hint>
-+ </hints>
-+ </connection>
-+ </connections>
-+</ui>
---
-2.7.0
-
diff --git a/ChangeLog b/ChangeLog
index 10241a5360ce..cecc2d96531c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-09 Pierre Choffet <peuc@wanadoo.fr>
+ * 2.0.0.r177.g49fb1c3
+ The client incompatibilities have now been fixed upstream, so the package
+ specific patches have been removed.
+
2016-01-07 Pierre Choffet <peuc@wanadoo.fr>
* 2.0.0.r138.g18ff797-2 :
Fix upstream which is broken after libringclient update. Add 5 backported
diff --git a/PKGBUILD b/PKGBUILD
index b49e9bb8b70d..7bd1939fbec3 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -6,8 +6,8 @@
# #commit=<commit_id> in source url.
pkgname=ring-kde-git
-pkgver=2.0.0.r138.g18ff797
-pkgrel=2
+pkgver=2.0.0.r177.g49fb1c3
+pkgrel=1
pkgdesc="KDE client for Ring"
arch=("i686" "x86_64")
url="http://ring.cx/"
@@ -20,20 +20,8 @@ depends=("libringclient-git" "ring-daemon-git" "qt5-base" "qt5-svg"
makedepends=("git" "cmake" "extra-cmake-modules")
provides=("ring-kde")
changelog="ChangeLog"
-source=("git://anongit.kde.org/ring-kde"
- "0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch"
- "0002-contact-Enable-Akonadi-support-again.patch"
- "0003-history-De-duplicate-identical-calls.patch"
- "0004-akonadi-Make-it-optional.patch"
- "0005-Fix-CMakeLists.txt.patch"
- "0006-contact-Add-new-basic-contact-selection-dialog.patch")
-sha256sums=('SKIP'
- 'fe1a4a7ba6df920117adf5d57a8fcfaa784986369a50c91bd3ae5b0f69ea2c59'
- '2fce01531bcdf001b1f8cc34522c5951dcbb853ea597ffa4421cdd78661148d2'
- '1c1ff7d6244982cbf56720eeda731b5fb09933178e02d0b3d24614a906d91e29'
- 'b50755d6653b417046734a29d25cdb4ff2cadcc900e119b309e4fbb0d8614894'
- 'd1215e1ba920f7b359a4319caa6ea286784b32079fc647c2fe7b66a9dde4e44c'
- 'c22e0d8518575d00dc6b660e5c8979659678e403947526465ceaf17cdca7c517')
+source=("git://anongit.kde.org/ring-kde")
+sha256sums=('SKIP')
pkgver() {
cd "ring-kde"
@@ -43,13 +31,6 @@ pkgver() {
prepare() {
cd "ring-kde"
-
- git am < '../0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch'
- git am < '../0002-contact-Enable-Akonadi-support-again.patch'
- git am < '../0003-history-De-duplicate-identical-calls.patch'
- git am < '../0004-akonadi-Make-it-optional.patch'
- git am < '../0005-Fix-CMakeLists.txt.patch'
- git am < '../0006-contact-Add-new-basic-contact-selection-dialog.patch'
}
build() {