1 /** \file TocContactListWidget.cpp
2 * \brief Implementation of TocContactListWidget class
4 * Tieto Open Communicator - Client for the Telepathy communications framework.
5 * Copyright (c) 2010, Tieto Corporation
8 * Redistribution and use in source and binary forms, with or without modification,
9 * are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * Neither the name of the Tieto Corporation nor the names of its contributors
17 * may be used to endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <QMouseEvent>
34 #include <QMessageBox>
37 #include <QCommonStyle>
39 #include "TocContactListWidget"
40 #include "IconProvider"
44 Q_DECLARE_METATYPE(TocContact*);
46 TocContactListWidget::TocContactListWidget(QWidget * parent)
47 : QListWidget(parent),
48 _editAction(tr("Edit"), 0),
49 _removeAction(tr("Remove"), 0)
51 setStyle(new QCommonStyle());
52 setFlow( QListView::LeftToRight );
53 setViewMode( QListView::IconMode );
54 setGridSize( QSize(109, 113) );
55 setIconSize(QSize(68,68));
56 setDragEnabled( false );
57 setVerticalScrollMode( QAbstractItemView::ScrollPerItem );
60 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
61 setResizeMode( QListView::Adjust );
62 QFont currentFont(font());
63 currentFont.setPixelSize(14);
67 (new QListWidgetItem(QIcon(":/addcontact.png"), tr("Add Contact"), this))->setFlags( Qt::ItemIsEnabled );
69 TocSettings *pSettings = TocSettings::getInstance();
71 QList<TocContact*> *pContactsList = pSettings->contactList();
73 IconProvider *pIconProvider = IconProvider::getInstance();
75 foreach(TocContact* pContact, *pContactsList)
77 if(!pContact->customIconPath.isEmpty())
78 pIconProvider->setCustomIcon(pContact);
80 QString displayedText;
81 if(pContact->name.isEmpty())
82 displayedText = pContact->uid;
84 displayedText = pContact->name;
86 QListWidgetItem* pItem = new QListWidgetItem(displayedText, this);
88 pItem->setData( Qt::DecorationRole, *(pIconProvider->matchIcon(pContact)) );
89 pItem->setData( ContactRole, QVariant::fromValue(pContact));
91 pItem->setFlags( Qt::ItemIsEnabled );
97 _logo = new QImage(":/tieto-logo.png");
99 sortItems(Alphabetical); // Sort items alphabetically
102 CONNECT(&_editAction, SIGNAL(triggered(bool)), this, SLOT(onEditRequested()));
103 CONNECT(&_removeAction, SIGNAL(triggered(bool)), this, SLOT(onRemoveRequested()));
104 CONNECT(this, SIGNAL(logoColorChanged(QColor)), this, SLOT(changeLogoColor(QColor)));
107 TocContactListWidget::~TocContactListWidget() {
111 void TocContactListWidget::onNewContactList(const TocContactList& contactList) {
113 QListWidgetItem* pAddContactItem = takeItem( 0 );
116 IconProvider *pIconProvider = IconProvider::getInstance();
118 foreach(TocContact* pContact, contactList)
120 QString displayedText;
121 if(pContact->name.isEmpty())
122 displayedText = pContact->uid;
124 displayedText = pContact->name;
126 QListWidgetItem* pNewItem = new QListWidgetItem(displayedText, this);
128 pNewItem->setData(DecorationRole, *(pIconProvider->matchIcon(pContact)));
129 pNewItem->setData(ContactRole, QVariant::fromValue(pContact));
131 //make it not selectable
132 pNewItem->setFlags( Qt::ItemIsEnabled );
135 insertItem(0, pAddContactItem);
137 sortItems(Alphabetical);
140 void TocContactListWidget::onContactPresenceUpdate(const QString& uid, Presence presence, const QString& description) {
142 IconProvider *pIconProvider = IconProvider::getInstance();
144 QListWidgetItem* pItem = findItem(uid);
149 TocContact *pContact = pItem->data(ContactRole).value<TocContact*>();
151 pContact->presence = presence;
152 pContact->description = description;
154 pItem->setData(Qt::DecorationRole, *(pIconProvider->matchIcon(pContact)));
157 QString TocContactListWidget::getDisplayedName(const QString& uid) {
159 QListWidgetItem* pItem = findItem(uid);
162 return pItem->data(DisplayRole).toString();
167 void TocContactListWidget::clearStatuses() {
169 IconProvider *pIconProvider = IconProvider::getInstance();
171 for(int i = 1; i < count(); ++i) {
173 QListWidgetItem* pItem = this->item(i);
175 TocContact *pContact = pItem->data(ContactRole).value<TocContact*>();
176 pContact->presence = Offline;
177 // pContact->description = ""; // TODO: Clear description also? Some clients remember last descr
179 pItem->setData(Qt::DecorationRole, *(pIconProvider->matchIcon(pContact)));
183 Q_DECLARE_METATYPE(QListWidgetItem*);
186 void TocContactListWidget::mouseDoubleClickEvent(QMouseEvent *event)
188 QPoint itemPos = event->pos();
190 QListWidgetItem* pClickedItem = itemAt(itemPos);
194 QListWidgetItem* pAddContactItem = item(0);
196 if(pAddContactItem == pClickedItem)
197 emit contactInfoRequest(0);
200 TocContact *pContact = pClickedItem->data(ContactRole).value<TocContact*>();
201 QString uid = pContact->uid;
202 QString name = pClickedItem->text(); // Using Text instead of pContact->name because the latter can be empty
204 emit triggered(uid, name, pContact->presence);
208 void TocContactListWidget::contextMenuEvent(QContextMenuEvent *event)
210 QPoint itemPos = event->pos();
212 QListWidgetItem* pClickedItem = itemAt(itemPos);
214 //if it applies to Add Contact then skip it
215 QListWidgetItem* pAddContactItem = item(0);
216 if(pClickedItem == pAddContactItem || pClickedItem == 0) return;
219 QMenu contextMenu(this);
221 contextMenu.setStyleSheet(
226 "margin-bottom: 0px;"
233 "margin-bottom: 0px;"
234 "padding: 0px 10px 0px 30px;"
238 "border-radius: 5px;"
241 _editAction.setData(QVariant::fromValue(pClickedItem));
242 _removeAction.setData(QVariant::fromValue(pClickedItem));
244 contextMenu.addAction(&_editAction);
245 contextMenu.addAction(&_removeAction);
247 contextMenu.exec(mapToGlobal(itemPos));
251 void TocContactListWidget::onEditRequested() {
253 //extract data from sender
254 QObject* pObject = QObject::sender();
255 _pCurrentEditedItem = (static_cast<QAction*>(pObject))->data().value<QListWidgetItem*>();
257 _currentEditedContact = *(_pCurrentEditedItem->data(ContactRole).value<TocContact*>());
259 if(_pCurrentEditedItem)
260 emit contactInfoRequest(_pCurrentEditedItem);
263 void TocContactListWidget::onRemoveRequested() {
265 //extract data from sender
266 QObject* pObject = QObject::sender();
267 QListWidgetItem* pItem = (static_cast<QAction*>(pObject))->data().value<QListWidgetItem*>();
271 TocContact* pContact = pItem->data(ContactRole).value<TocContact*>();
272 QMessageBox::StandardButton clickedButton = QMessageBox::question(this, "TEC", tr("Are you sure you want to remove\ncontact: %1").arg(pContact->name), QMessageBox::Yes | QMessageBox::No);
273 if(clickedButton == QMessageBox::No) return;
276 if(takeItem(row(pItem)))
278 //Removing went successfuly
279 //Lets notify the engine
280 QString uid = pItem->data(ContactRole).value<TocContact*>()->uid;
282 emit removedContact(uid);
287 void TocContactListWidget::commitAdd(QListWidgetItem* pNewItem) {
289 TocContact *pNewContact = pNewItem->data(ContactRole).value<TocContact*>();
290 QString uid = pNewContact->uid;
292 //ensure that item is not already present
300 sortItems(Alphabetical);
303 emit addContact(pNewContact);
306 void TocContactListWidget::commitEdit(QListWidgetItem* pEditedItem) {
308 TocContact* pEditedContact = pEditedItem->data(ContactRole).value<TocContact*>();
310 QString newUid = pEditedContact->uid;
311 QString newName = pEditedContact->name;
313 QString oldUid = _currentEditedContact.uid;
314 QString oldName = _currentEditedContact.name;
316 if( newUid != oldUid )//If Uid has changed ensure that item with such uid is not already present
317 if( findItem(newUid, pEditedItem) ) {
318 pEditedContact->uid = oldUid;
322 if( newName != oldName )
323 if(newName.isEmpty())
324 emit displayedNameChanged( newUid, newUid );
326 emit displayedNameChanged( newUid, newName );
329 sortItems(Alphabetical);
331 IconProvider *pIconProvider = IconProvider::getInstance();
332 pEditedItem->setData(Qt::DecorationRole, *(pIconProvider->matchIcon(pEditedContact)));
334 emit editContact(pEditedContact, oldUid);
337 QListWidgetItem* TocContactListWidget::findItem(const QString& requestedUid, const QListWidgetItem* pExcludedItem) {
341 for(int i=1; i < count(); i++)
343 QListWidgetItem* pRequestedItem = item(i);
344 if( pExcludedItem == pRequestedItem )
347 uid = pRequestedItem->data(ContactRole).value<TocContact*>()->uid;
349 if(uid == requestedUid)
350 return pRequestedItem;
356 void TocContactListWidget::sortItems(SortOrder order) {
358 QListWidgetItem* pAddContactItem = 0;
363 pAddContactItem = takeItem( 0 );
364 QListWidget::sortItems(Qt::AscendingOrder);
365 insertItem(0, pAddContactItem);
369 // TODO: sort by status
373 // TODO: disable sorting and enable drag & drop events
378 void TocContactListWidget::paintEvent(QPaintEvent * event) {
381 QPainter painter(this->viewport());
382 painter.drawImage(this->width() - _logo->width(), this->height() - _logo->height(), *_logo);
384 QListWidget::paintEvent(event);
387 QColor TocContactListWidget::logoColor() const {
391 void TocContactListWidget::setLogoColor(QColor color) {
393 emit logoColorChanged( _logoColor );
396 void TocContactListWidget::changeLogoColor(QColor color) {
398 QString colorName = color.name();
400 if( colorName == "#0000ff" )
402 else if( colorName == "#add8e6" )
403 lColor = LOGO_LIGHT_BLUE;
404 else if( colorName == "#008000" )
406 else if( colorName == "#ffa500" )
407 lColor = LOGO_ORANGE;
408 else if( colorName == "#ff0000" )
413 for(int i = 0; i < _logo->width(); ++i)
414 for(int j = 0; j < _logo->height(); ++j)
415 if(_logo->pixel(i, j) >> 24)
416 _logo->setPixel(i,j, lColor.rgb());