1
/****************************************************************************
2
* Copyright (C) 2014 by Savoir-Faire Linux *
3
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
5
* This library is free software; you can redistribute it and/or *
6
* modify it under the terms of the GNU Lesser General Public *
7
* License as published by the Free Software Foundation; either *
8
* version 2.1 of the License, or (at your option) any later version. *
10
* This library is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13
* Lesser General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17
***************************************************************************/
20
#include "contactmodel.h"
26
#include "phonenumber.h"
27
#include "abstractitembackend.h"
28
#include "itembackendmodel.h"
29
#include "visitors/itemmodelstateserializationvisitor.h"
32
#include <QtCore/QHash>
33
#include <QtCore/QDebug>
34
#include <QtCore/QCoreApplication>
36
ContactModel* ContactModel::m_spInstance = nullptr;
39
ContactModel::ContactModel(QObject* par) : QAbstractItemModel(par?par:QCoreApplication::instance()),
40
m_pBackendModel(nullptr)
45
ContactModel::~ContactModel()
47
m_hContactsByUid.clear();
48
while (m_lContacts.size()) {
49
Contact* c = m_lContacts[0];
50
m_lContacts.remove(0);
55
ContactModel* ContactModel::instance() {
57
m_spInstance = new ContactModel(QCoreApplication::instance());
61
/*****************************************************************************
65
****************************************************************************/
68
bool ContactModel::setData( const QModelIndex& idx, const QVariant &value, int role)
76
QVariant ContactModel::data( const QModelIndex& idx, int role) const
80
if (!idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
81
const Contact* c = m_lContacts[idx.row()];
83
return QVariant(c->formattedName());
85
else if (idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) {
86
const Contact* c = m_lContacts[idx.parent().row()];
88
return QVariant(c->phoneNumbers()[idx.row()]->uri());
93
QVariant ContactModel::headerData(int section, Qt::Orientation orientation, int role) const
96
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
97
return QVariant(tr("Contacts"));
101
int ContactModel::rowCount( const QModelIndex& par ) const
103
if (!par.isValid()) {
104
return m_lContacts.size();
106
else if (!par.parent().isValid() && par.row() < m_lContacts.size()) {
107
const Contact* c = m_lContacts[par.row()];
109
const int size = c->phoneNumbers().size();
110
return size==1?0:size;
116
Qt::ItemFlags ContactModel::flags( const QModelIndex& idx ) const
119
return Qt::NoItemFlags;
120
return Qt::ItemIsEnabled | ((idx.parent().isValid())?Qt::ItemIsSelectable:Qt::ItemIsEnabled);
123
int ContactModel::columnCount ( const QModelIndex& par) const
129
QModelIndex ContactModel::parent( const QModelIndex& idx) const
132
return QModelIndex();
133
CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer();
134
if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) {
135
int idx2 = m_lContacts.indexOf(((Contact::PhoneNumbers*)modelItem)->contact());
137
return ContactModel::index(idx2,0,QModelIndex());
140
return QModelIndex();
143
QModelIndex ContactModel::index( int row, int column, const QModelIndex& par) const
145
if (!par.isValid() && m_lContacts.size() > row) {
146
return createIndex(row,column,m_lContacts[row]);
148
else if (par.isValid() && m_lContacts[par.row()]->phoneNumbers().size() > row) {
149
return createIndex(row,column,(CategorizedCompositeNode*)(&(m_lContacts[par.row()]->phoneNumbers())));
151
return QModelIndex();
154
/*****************************************************************************
158
****************************************************************************/
161
///Find contact by UID
162
Contact* ContactModel::getContactByUid(const QByteArray& uid)
164
return m_hContactsByUid[uid];
168
* Create a temporary contact or return the existing one for an UID
169
* This temporary contact should eventually be merged into the real one
171
Contact* ContactModel::getPlaceHolder(const QByteArray& uid )
173
Contact* ct = m_hContactsByUid[uid];
175
//Do not create a placeholder if the real deal exist
180
//Do not re-create if it already exist
181
ct = m_hPlaceholders[uid];
185
ContactPlaceHolder* ct2 = new ContactPlaceHolder(uid);
187
m_hPlaceholders[ct2->uid()] = ct2;
191
///Return if there is backends
192
bool ContactModel::hasBackends() const
194
return m_lBackends.size();
198
const QVector<AbstractContactBackend*> ContactModel::enabledBackends() const
203
bool ContactModel::hasEnabledBackends() const
205
return m_lBackends.size()>0;
208
CommonItemBackendModel* ContactModel::backendModel() const
210
if (!m_pBackendModel) {
211
const_cast<ContactModel*>(this)->m_pBackendModel = new CommonItemBackendModel(const_cast<ContactModel*>(this));
213
return m_pBackendModel; //TODO
216
const QVector<AbstractContactBackend*> ContactModel::backends() const
221
bool ContactModel::enableBackend(AbstractContactBackend* backend, bool enabled)
229
bool ContactModel::addContact(Contact* c)
233
beginInsertRows(QModelIndex(),m_lContacts.size()-1,m_lContacts.size());
235
m_hContactsByUid[c->uid()] = c;
237
//Deprecate the placeholder
238
if (m_hPlaceholders.contains(c->uid())) {
239
ContactPlaceHolder* c2 = m_hPlaceholders[c->uid()];
242
m_hPlaceholders[c->uid()] = nullptr;
246
emit layoutChanged();
247
emit newContactAdded(c);
252
void ContactModel::disableContact(Contact* c)
258
const ContactList ContactModel::contacts() const
263
void ContactModel::addBackend(AbstractContactBackend* backend, LoadOptions options)
265
m_lBackends << backend;
266
connect(backend,SIGNAL(reloaded()),this,SLOT(slotReloaded()));
267
connect(backend,SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*)));
268
if (options & LoadOptions::FORCE_ENABLED || ItemModelStateSerializationVisitor::instance()->isChecked(backend))
270
emit newBackendAdded(backend);
273
bool ContactModel::addNewContact(Contact* c, AbstractContactBackend* backend)
276
return m_lBackends[0]->addNew(c);
280
/*****************************************************************************
284
****************************************************************************/
286
void ContactModel::slotReloaded()
291
void ContactModel::slotContactAdded(Contact* c)