phonebookui/pbkcommonui/src/cntgroupselectionpopup.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 14 May 2010 15:42:23 +0300
changeset 31 2a11b5b00470
parent 27 de1630741fbe
child 37 fd64c38c277d
permissions -rw-r--r--
Revision: 201017 Kit: 201019

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/

#include "cntgroupselectionpopup.h"

#include <hbgroupbox.h>
#include <hbaction.h>
#include <hbsearchpanel.h>
#include <hblistviewitem.h>
#include <hbindexfeedback.h>
#include <hbscrollbar.h>
#include <hbtextitem.h>
#include <qtcontacts.h>
#include <QGraphicsWidget>
#include <mobcntmodel.h>
#include <hbmainwindow.h>
#include <hbparameterlengthlimiter.h>


CntGroupSelectionPopup::CntGroupSelectionPopup(QContactManager *manager, QContact *contact, QGraphicsItem *parent):
    HbDialog(parent),
    mListView(NULL),
    mEmptyListLabel(NULL),
    mContactManager(manager),
    mContact(contact)
{    
    QList<QContactSortOrder> sortOrders;
    QContactSortOrder sortOrderFirstName;
    sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst);
    sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive);
    sortOrders.append(sortOrderFirstName);

    QContactSortOrder sortOrderLastName;
    sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldLast);
    sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive);
    sortOrders.append(sortOrderLastName);

    mCntModel = new MobCntModel(mContactManager, QContactFilter(), sortOrders);

    mSearchPanel = new HbSearchPanel();
    connect(mSearchPanel, SIGNAL(exitClicked()), this, SLOT(closeFind()));
    connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString)));
    
    mContainerLayout = new QGraphicsLinearLayout(Qt::Vertical);
    mContainerLayout->setContentsMargins(0, 0, 0, 0);
    mContainerLayout->setSpacing(0);
    
    mContainerWidget = new HbWidget();
 }

CntGroupSelectionPopup::~CntGroupSelectionPopup()
{
    delete mContainerWidget;
    mContainerWidget = 0;
    
    delete mCntModel;
    mCntModel = 0;
}

void CntGroupSelectionPopup::populateListOfContact()
{
    QContactName groupContactName = mContact->detail( QContactName::DefinitionName );
    QString groupName(groupContactName.value( QContactName::FieldCustomLabel ));
    
    HbGroupBox *headingLabel = new HbGroupBox(this);
    headingLabel->setHeading(HbParameterLengthLimiter(hbTrId("txt_phob_title_members_of_1_group")).arg(groupName));
    
    setHeadingWidget(headingLabel);
    
    mListView = new HbListView(this);
    QContactRelationshipFilter rFilter;
    
    QContactDetailFilter contactsFilter;
    contactsFilter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
    contactsFilter.setValue(QString(QLatin1String(QContactType::TypeContact)));
    mCntModel->setFilterAndSortOrder(contactsFilter);
    mCntModel->showMyCard(false);
    
    rFilter.setRelationshipType(QContactRelationship::HasMember);
    rFilter.setRelatedContactRole(QContactRelationship::First);
    rFilter.setRelatedContactId(mContact->id());   
    QList<QContactLocalId> contactsLocalIdList = mContactManager->contactIds(rFilter);
    int countContacts = contactsLocalIdList.count();
    
    //Get the index of the contacts
    // Set the select option for those contacts in the selectionModel
    mListView->setModel(mCntModel);
    // set the listview to multiSelection mode, this will bring MarkAll functionality (from Orbit)
    mListView->setSelectionMode(HbAbstractItemView::MultiSelection);
    mListView->setFrictionEnabled(true);
    mListView->setScrollingStyle(HbScrollArea::PanWithFollowOn);
    mListView->verticalScrollBar()->setInteractive(true);
    HbListViewItem *prototype = mListView->listItemPrototype();
    prototype->setGraphicsSize(HbListViewItem::Thumbnail);
    HbIndexFeedback *indexFeedback = new HbIndexFeedback(this);
    indexFeedback->setIndexFeedbackPolicy(HbIndexFeedback::IndexFeedbackSingleCharacter);
    indexFeedback->setItemView(mListView);
    
    for (int i=0; i < countContacts; i++ )
    {
        // get QContact from QContactId
        QContact contactInList = mContactManager->contact(contactsLocalIdList.at(i));
        QModelIndex contactIndex = mCntModel->indexOfContact(contactInList);
        mListView->selectionModel()->select(contactIndex, QItemSelectionModel::Select);
    }
    
    setTimeout(HbPopup::NoTimeout);
    setDismissPolicy(HbPopup::NoDismiss);
    setModal(true);
    setAttribute(Qt::WA_DeleteOnClose, true);
     
    // Note that the layout takes ownership of the item(s) it contains.
    if (!mCntModel->rowCount())
    {
        mListView->setVisible(false);
        if (mEmptyListLabel == 0)
        {
            mEmptyListLabel = new HbTextItem(hbTrId("(no matching contacts)"));
            mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
            mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary));
            mEmptyListLabel->setAlignment(Qt::AlignCenter);
            mContainerLayout->insertItem(0, mEmptyListLabel);
        }
    }
    else
    {
        mContainerLayout->addItem(mListView);
    }
    mContainerLayout->addItem(mSearchPanel);
    mContainerWidget->setLayout(mContainerLayout);
    HbMainWindow* window = mainWindow();
    if ( window )
        {
        mContainerWidget->setPreferredHeight(window->size().height());
        }
    mContainerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    setContentWidget(mContainerWidget);
    
    HbAction *mPrimaryAction = new HbAction(hbTrId("Save"), this);
    addAction(mPrimaryAction);
    
    HbAction *mSecondaryAction = new HbAction(hbTrId("txt_common_button_cancel"), this);
    addAction(mSecondaryAction);
}

bool CntGroupSelectionPopup::saveNewGroup()
{
    // Save the relationship from the selection model of the member selection list
    QModelIndexList indexes = mListView->selectionModel()->selection().indexes();
    
    for (int i = 0; i < indexes.count(); i++)
    {
        QModelIndex index = indexes[i];
        QContact contact = mCntModel->contact(indexes[i]);
        int id = contact.localId();
        int gpid = mContact->localId();
        QContactRelationship relationship;
        relationship.setRelationshipType(QContactRelationship::HasMember);
        relationship.setFirst(mContact->id());
        relationship.setSecond(contact.id());
        
        // save relationship
        mContactManager->saveRelationship(&relationship);
    }
    
    return indexes.count() > 0;
}

bool CntGroupSelectionPopup::saveOldGroup()
{
    // Use relationship filter to get list of contacts in the relationship (if any)
    QContactRelationshipFilter rFilter;
    rFilter.setRelationshipType(QContactRelationship::HasMember);
    rFilter.setRelatedContactRole(QContactRelationship::First);
    rFilter.setRelatedContactId(mContact->id());

    QList<QContactLocalId> contactsLocalIdList = mContactManager->contactIds(rFilter);
    
    // get the contact from  new selection model indexes
    // for each contact, check if contact in this new index is member of mContactsLocalIdList( as achieved in activateView)
    // if yes, then do nothing
    // if no, then add contact to the relationship

    QModelIndexList indexes = mListView->selectionModel()->selection().indexes();
    QList<QContactLocalId> selectionList;

    QList<QContactRelationship> removedRelationships;
    QList<QContactRelationship> addedRelationships;

    for (int i = 0; i < indexes.count(); i++)
    {
        QContact contact = mCntModel->contact(indexes[i]);
        QContactLocalId locId = contact.localId();
        selectionList.append(locId);       
        
        if (!contactsLocalIdList.contains(locId))
        {
            // new contact added to the group
            QContactRelationship relationship;
            relationship.setRelationshipType(QContactRelationship::HasMember);
            relationship.setFirst(mContact->id());
            relationship.setSecond(contact.id());
            addedRelationships.append(relationship);
        }
    }
    
    // for each contact in mContactsLocalIdList, check if contact is also in new selection model
    // if yes, then do nothing
    // if no, then remove it from the relationship
    
    for (int j = 0; j < contactsLocalIdList.count(); j++)
    {
        QContactLocalId oldSelectedLocalContactId = contactsLocalIdList.at(j);
        if (!selectionList.contains(oldSelectedLocalContactId))
        {
            QContact contactInOldList = mContactManager->contact(contactsLocalIdList.at(j));          
            QContactRelationship relationship;
            relationship.setRelationshipType(QContactRelationship::HasMember);
            relationship.setFirst(mContact->id());
            relationship.setSecond(contactInOldList.id());
            removedRelationships.append(relationship);
        }
    }
    // save & remove relationships
    QMap<int, QContactManager::Error> errors;
    mContactManager->removeRelationships(removedRelationships, &errors);
    mContactManager->saveRelationships(&addedRelationships, &errors);
    
    return (removedRelationships.count() > 0 || addedRelationships.count() > 0);
}

void CntGroupSelectionPopup::closeFind()
{
    if (mSearchPanel)
    {
         mContainerLayout->removeItem(mEmptyListLabel);
         delete mEmptyListLabel;
         mEmptyListLabel = 0;

         mContainerLayout->removeItem(mSearchPanel);
         mContainerLayout->addItem(mListView);

         QContactDetailFilter filter;
         filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
         QString typeContact = QContactType::TypeContact;
         filter.setValue(typeContact);

         mSearchPanel->deleteLater();
     }
}

void CntGroupSelectionPopup::setFilter(const QString &filterString)
{
    QStringList searchList = filterString.split(QRegExp("\\s+"), QString::SkipEmptyParts);

    // find matches and existing members
    QContactRelationshipFilter relationFilter;
    relationFilter.setRelationshipType(QContactRelationship::HasMember);
    relationFilter.setRelatedContactRole(QContactRelationship::First);
    relationFilter.setRelatedContactId(mContact->id());
        
    QContactDetailFilter detailfilter;
    detailfilter.setDetailDefinitionName(QContactDisplayLabel::DefinitionName, QContactDisplayLabel::FieldLabel);
    detailfilter.setMatchFlags(QContactFilter::MatchStartsWith);
    detailfilter.setValue(searchList);
    
    QContactUnionFilter filter;
    filter.append(relationFilter);
    filter.append(detailfilter);
    
    mCntModel->setFilterAndSortOrder(filter);
    
    // select all contacts already in group relationship
    QList<QContactLocalId> contactsLocalIdList = mContactManager->contactIds(relationFilter);
    int countContacts = contactsLocalIdList.count();
    for (int i=0; i < countContacts; i++ )
    {
        // get QContact from QContactId
        QContact contactInList = mContactManager->contact(contactsLocalIdList.at(i));
        QModelIndex contactIndex = mCntModel->indexOfContact(contactInList);
        mListView->selectionModel()->select(contactIndex, QItemSelectionModel::Select);
    }

    if (!mCntModel->rowCount())
    {
        if (mEmptyListLabel == 0)
        {
            mListView->setVisible(false);
            mContainerLayout->removeItem(mListView);
            
            mEmptyListLabel = new HbTextItem(hbTrId("(no matching contacts)"));
            mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
            mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary));
            mEmptyListLabel->setAlignment(Qt::AlignCenter);
            mContainerLayout->insertItem(0, mEmptyListLabel);
        }
    }
    else
    {
        if (mEmptyListLabel != 0)
        {
            mListView->setVisible(true);
            mContainerLayout->insertItem(0, mListView);

            mContainerLayout->removeItem(mEmptyListLabel);
            delete mEmptyListLabel;
            mEmptyListLabel = 0;
        }
    }
}