diff options
author | Pierre Choffet | 2016-01-09 10:58:17 -0500 |
---|---|---|
committer | Pierre Choffet | 2016-01-09 10:58:17 -0500 |
commit | 58e345f703ef5335a24b6365bec313fed58a6eac (patch) | |
tree | 718aab51c4ce64726eb7e8c5e8afbfdd86bf4614 | |
parent | 9ae630727a3e3a53798d21fe5ee762a0175deab8 (diff) | |
download | aur-58e345f703ef5335a24b6365bec313fed58a6eac.tar.gz |
Remove custom made patches
The incompatibility has been fixed upstream, so the patches are now useless and removed.
-rw-r--r-- | .SRCINFO | 18 | ||||
-rw-r--r-- | 0001-textmessages-Vastly-revamp-and-fix-the-text-messages.patch | 886 | ||||
-rw-r--r-- | 0002-contact-Enable-Akonadi-support-again.patch | 1565 | ||||
-rw-r--r-- | 0003-history-De-duplicate-identical-calls.patch | 685 | ||||
-rw-r--r-- | 0004-akonadi-Make-it-optional.patch | 234 | ||||
-rw-r--r-- | 0005-Fix-CMakeLists.txt.patch | 25 | ||||
-rw-r--r-- | 0006-contact-Add-new-basic-contact-selection-dialog.patch | 461 | ||||
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | PKGBUILD | 27 |
9 files changed, 12 insertions, 3894 deletions
@@ -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 @@ -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() { |