phonebookui/pbkcommonui/src/cnteditview_p.cpp
author hgs
Fri, 23 Jul 2010 12:43:48 +0300
changeset 53 e6aff7b69165
parent 50 77bc263e1626
child 61 d30183af6ca6
permissions -rw-r--r--
201029

/*
* 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 "cnteditview_p.h"
#include "cnteditviewlistmodel.h"
#include "cntdocumentloader.h"
#include "cntdetailpopup.h"
#include "cnteditviewheadingitem.h"
#include "cntimagelabel.h"
#include "cntsavemanager.h"
#include "cntglobal.h"
#include "cntdebug.h"

#include <qtcontacts.h>
#include <hbdocumentloader.h>
#include <thumbnailmanager_qt.h>
#include <hbabstractviewitem.h>
#include <hbmessagebox.h>
#include <hbgroupbox.h>
#include <hbmainwindow.h>
#include <hbview.h>
#include <hblistview.h>
#include <hbaction.h>
#include <hbmenu.h>
#include <hbframebackground.h>
#include <hbparameterlengthlimiter.h>
#include <hbdevicenotificationdialog.h>
#include <xqaiwrequest.h>
#include <xqaiwdecl.h>
#include <cntservicescontact.h>

#include <QFileInfo>
#include <QApplication>
#include <QTimer>

const char *CNT_EDIT_XML = ":/xml/contacts_ev.docml";

CntEditViewPrivate::CntEditViewPrivate() :
    mModel( NULL ),
    mImageLabel( NULL ),
    mThumbnailManager( NULL ),
    mContact( NULL ),
    mReq(NULL),
    mMenu(NULL),
    mSaveManager(NULL)
{
    mDocument = new CntDocumentLoader;
    
    bool ok;
    mDocument->load( CNT_EDIT_XML, &ok );
    if ( !ok ){
        qFatal( "Unable to load %S", CNT_EDIT_XML );
    }
    mView = static_cast<HbView*>( mDocument->findWidget("view") );
    mListView = static_cast<HbListView*>( mDocument->findWidget("listView") );
    mListView->setLayoutName("editviewlist");
    HbFrameBackground frame;
    frame.setFrameGraphicsName("qtg_fr_list_normal");
    frame.setFrameType(HbFrameDrawer::NinePieces);
    mListView->itemPrototypes().first()->setDefaultFrame(frame);
    
    mHeading = static_cast<CntEditViewHeadingItem*>( mDocument->findWidget("editViewHeading") );
    mImageLabel = static_cast<CntImageLabel*>(mDocument->findWidget("editViewImage"));
    
    mSoftkey = new HbAction(Hb::BackNaviAction, mView);
    mDiscard = static_cast<HbAction*>( mDocument->findObject("cnt:discard") );
    mDiscard->setParent(mView);

    mSave = static_cast<HbAction*>( mDocument->findObject("cnt:savecontact") );
    mSave->setParent(mView);

    mDelete = static_cast<HbAction*>( mDocument->findObject("cnt:deletecontact") );
    mDelete->setParent(mView);
    
    HbAction* add = static_cast<HbAction*>( mDocument->findObject("cnt:adddetail_options") );
    add->setParent(mView);

    connect( add, SIGNAL(triggered()), this, SLOT(addDetailItem()) );
    connect( mDelete, SIGNAL(triggered()), this, SLOT(deleteContact()) );
    connect( mDiscard, SIGNAL(triggered()), this, SLOT(discardChanges()) );
    connect( mSave, SIGNAL(triggered()), this, SLOT(saveChanges()) );
        
    connect( mSoftkey, SIGNAL(triggered()), this, SLOT(saveChanges()) );
    connect( mImageLabel, SIGNAL(iconClicked()), this, SLOT(openImageEditor()) );
    connect( mHeading, SIGNAL(textClicked()), this, SLOT(openNameEditor()) );
    connect( mHeading, SIGNAL(iconClicked()), this, SLOT(openImageEditor()) );
    connect( mListView, SIGNAL(activated(const QModelIndex&)), this, SLOT(activated(const QModelIndex&)) );
    connect( mListView, SIGNAL(longPressed(HbAbstractViewItem*,const QPointF&)), this, SLOT(longPressed(HbAbstractViewItem*,const QPointF&)) );
    
    // closing the application from task swapper or end key will cause the contact to be saved
    connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(saveChanges()));
}

CntEditViewPrivate::~CntEditViewPrivate()
{
    mView->deleteLater();
    
    delete mDocument;
    mDocument = NULL;
    delete mModel;
    mModel = NULL;
    delete mContact;
    mContact = NULL;
    if (mMenu) 
    {
        delete mMenu;
        mMenu = NULL;
    }
    delete mThumbnailManager;
    mThumbnailManager = NULL;
    delete mSaveManager;
    mSaveManager = NULL;
}

void CntEditViewPrivate::setOrientation(Qt::Orientation orientation)
{
    if (orientation == Qt::Vertical) 
    {
        // reading "portrait" section
        mDocument->load( CNT_EDIT_XML, "portrait" );
    } 
    else 
    {
        // reading "landscape" section
        mDocument->load( CNT_EDIT_XML, "landscape" );
    }
}

void CntEditViewPrivate::activate( CntAbstractViewManager* aMgr, const CntViewParameters aArgs )
{
    CNT_ENTRY
    
    mMgr = aMgr;
    mArgs = aArgs;
    
    if ( mView->navigationAction() != mSoftkey)
    {
        mView->setNavigationAction(mSoftkey);
    }
    HbMainWindow* window = mView->mainWindow();
    if ( window )
    {
        connect(window, SIGNAL(viewReady()), this, SLOT(setScrollPosition()) );
        connect(window, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(setOrientation(Qt::Orientation)));
        setOrientation(window->orientation());
    }
        
    QString myCard = mArgs.value( EMyCard ).toString();
    QString selectedAction = mArgs.value( ESelectedAction ).toString();
    QVariant contact = aArgs.value( ESelectedContact );
    
    setSelectedContact( contact.value<QContact>() );
    mModel = new CntEditViewListModel( *mContact );
    mListView->setModel( mModel );
    
    QContactLocalId localId = mContact->localId();
    QContactManager* cm = mMgr->contactManager(SYMBIAN_BACKEND);
    QContactLocalId selfContactId = cm->selfContactId();
    mIsMyCard = ( localId == selfContactId && localId != 0 ) || !myCard.isEmpty();
    
    if (mIsMyCard)
    {
        mSaveManager = new CntSaveManager(CntSaveManager::EMyCard);
    }
    else
    {
        mSaveManager = new CntSaveManager();
    }
    
    if ( mHeading )
        mHeading->setDetails( mContact, mIsMyCard );

    // if "MyCard", set slightly different heading and options menu
    if ( mIsMyCard )
    {
        mSave->setText(hbTrId("txt_phob_opt_save_my_card"));
        mDelete->setText(hbTrId("txt_phob_opt_clear_my_card"));
        HbGroupBox* groupBox = static_cast<HbGroupBox*>( mDocument->findWidget("groupBox") );
        if ( groupBox )
        {
            groupBox->setHeading(hbTrId("txt_phob_subtitle_edit_my_details"));
        }
    }

    if ( localId == 0 && !mIsMyCard )
    {
        HbMenu* menu = mView->menu();
        menu->removeAction( mDelete );
    }
    
    // don't delete contact which is "MyCard" or not saved yet or both.
    if ( mIsMyCard && (mContact->details().count() <= 4 || localId == 0) )
    {
        mDelete->setEnabled( false );
    }

    // save and discard disabled if no changes found
    if ( *mContact == cm->contact( mContact->localId()) )
    {
        mDiscard->setEnabled( false );
        mSave->setEnabled( false );
    }
    
    mThumbnailManager = new ThumbnailManager(this);
    mThumbnailManager->setMode(ThumbnailManager::Default);
    mThumbnailManager->setQualityPreference(ThumbnailManager::OptimizeForQuality);
    mThumbnailManager->setThumbnailSize(ThumbnailManager::ThumbnailLarge);
    
    connect( mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void*, int, int)),
            this, SLOT(thumbnailReady(QPixmap, void*, int, int)) );

    loadAvatar();
    
    CNT_EXIT
}

void CntEditViewPrivate::deactivate()
{   
}

void CntEditViewPrivate::openView(CntViewParameters& viewParams)
{
    QList<int> keys = viewParams.keys();
    for(int i = 0;i < keys.count();i++)
    {
        mArgs.insert(keys.at(i), viewParams.value(keys.at(i)));
    }
    mMgr->changeView( mArgs );
}

void CntEditViewPrivate::requestRefresh()
{
    mModel->refreshExtensionItems();
}
    
void CntEditViewPrivate::activated( const QModelIndex& aIndex )
{
    CntEditViewItem* item = mModel->itemAt( aIndex );
    QVariant type = item->data( ERoleItemType );
    if ( type == QVariant(ETypeUiExtension) )
    {
        item->activated(this);
    }
    else if( item->data(ERoleEditorViewId) == ringToneFetcherView )
    {
       fetchTone();
    }
    else
    {
        // open editor view
        QVariant id = item->data( ERoleEditorViewId );
        mArgs.insert(EViewId, id.toInt());
        
        QVariant var;
        var.setValue(*mContact);
        mArgs.insert(ESelectedContact, var);
        mArgs.insert(ESelectedAction, QString() );
        mMgr->changeView( mArgs );
    }
    
}

void CntEditViewPrivate::longPressed( HbAbstractViewItem* aItem, const QPointF& aCoords )
{
    CntEditViewItem* item = mModel->itemAt( aItem->modelIndex() );
    QVariant type = item->data( ERoleItemType );
    
    // Ui extensions handle the long press by themselves.
    if ( type == QVariant(ETypeUiExtension) )
    {
        item->longPressed( aCoords, this );
    }
    // only detail items are able to show context specific menu
    else
    {
        if (mMenu) 
        {
            delete mMenu;
        }
        mMenu = createPopup( aItem->modelIndex(), item );
        mMenu->setPreferredPos( aCoords );
        mMenu->setModal( true );
        mMenu->open( this, SLOT(handleMenuAction(HbAction*)) );
    }
}

void CntEditViewPrivate::handleMenuAction( HbAction* aAction )
{
    HbMenu *menu = static_cast<HbMenu*>(sender());
    int row = aAction->data().toInt();
    mIndex = mModel->index(row, 0);
    CntEditViewItem* item = mModel->itemAt( mIndex );
    if ( aAction )
    {
        switch ( aAction->property("menu").toInt() )  
        {
        case HbAction::EditRole:
        {
            if( item->data(ERoleEditorViewId) == ringToneFetcherView )
                {
                fetchTone();
                menu->close();
                }
            else
                {
                editDetail( item );
                }
        }
        break;
        
        case HbAction::NewRole:
        {
            addDetail( item );
        }
        break;
        
        case HbAction::DeleteRole:
        {
          removeDetail( item, mIndex );
        }
        break;
        
        default:
            break;
        }
    }
}

void CntEditViewPrivate::addDetailItem()
{
    CntViewIdList list;
    mModel->allInUseFields( list );
    
    CntDetailPopup::selectDetail( list, this, SLOT(handleAddDetailItem(HbAction*)) );
}

void CntEditViewPrivate::handleAddDetailItem(HbAction *aAction)
{
    CntDetailPopup *popup = static_cast<CntDetailPopup*>(sender());
    
    if (popup && aAction != popup->actions().first() && popup->selectedItems().count())
    {
        int row = popup->selectedItems().first().toInt();
        QModelIndex index = popup->model()->index(row, 0);
        int id = popup->model()->data(index, Qt::UserRole).toInt();

        if (id != noView )
        {
            mArgs.insert(EViewId, id );

            switch ( id )
            {
            case phoneNumberEditorView:
            case emailEditorView:
            case urlEditorView:
            case noteEditorView:
                mArgs.insert( ESelectedAction, CNT_ADD_ACTION );
                changeEditorView();
                break;
            case addressEditorView:
            case dateEditorView:
            case companyEditorView:
            case familyDetailEditorView:
                mArgs.insert( ESelectedAction, CNT_FOCUS_ACTION );
                changeEditorView();
                break;            
            case ringToneFetcherView:
                fetchTone();
                break;                
            default:
                break;                
            }            
        }
    }
}

void CntEditViewPrivate::changeEditorView()
{
        QVariant var;
        var.setValue(*mContact);
        mArgs.insert(ESelectedContact, var);
        mMgr->changeView( mArgs );   
}

// Call IToneFetch Service
void CntEditViewPrivate::fetchTone()
{
        if(mReq)
         {
             delete mReq;
             mReq = 0;
         }
             //launch media fetcher
         mReq = mAppMgr.create(XQI_TONE_FETCH, XQOP_TONE_FETCH, true); // read strings from header file constants
         if (!mReq)
         {
           return;
         }
         else
         {
             connect(mReq, SIGNAL( requestOk( const QVariant&)), SLOT( ringToneFetchHandleOk(const QVariant&)) );
             connect(mReq, SIGNAL( requestError( int,const QString&)), SLOT(ringToneFetchHandleError(int,const QString&)) );
         }
         
         // Make the request
         mReq->send();
}

void CntEditViewPrivate::ringToneFetchHandleOk(const QVariant &result)
{
          
    QContactRingtone ringtone = mContact->detail<QContactRingtone>();
    QUrl ringtoneUrl = ringtone.audioRingtoneUrl();
    QFileInfo ringtoneFileInfo(ringtoneUrl.toString());
    QString ringtoneFileName = ringtoneFileInfo.fileName();
     // Contact can have only one ringtone at a time
     // remove existing ringtone detail if any
     
     if(!(ringtone.isEmpty()))
         {
         mContact->removeDetail(&ringtone);
         }
     
     ringtone.setAudioRingtoneUrl(result.value<QString>());
     mContact->saveDetail( &ringtone );
     mModel->updateRingtone();
     mSave->setEnabled( true );
     mDiscard->setEnabled( true );
     
}
 
void CntEditViewPrivate::ringToneFetchHandleError(int errorCode, const QString& errorMessage)
{
    Q_UNUSED(errorCode);
    Q_UNUSED(errorMessage);
    
}


void CntEditViewPrivate::deleteContact()
{
    if ( mIsMyCard )
    {
        HbMessageBox::question(hbTrId("txt_phob_dialog_remove_all_personal_data_from_my_c"), this, 
                SLOT(handleDeleteContact(int)), 
                HbMessageBox::Yes | HbMessageBox::No);
    }
    else
    {
        QContactManager* cm = mMgr->contactManager( SYMBIAN_BACKEND );
        QString name = cm->synthesizedContactDisplayLabel( *mContact );
        if (name.isEmpty())
        {
            name = hbTrId("txt_phob_list_unnamed");
        }
        
        HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_delete_1")).arg(name), this, SLOT(handleDeleteContact(int)), 
                HbMessageBox::Delete | HbMessageBox::Cancel);
    }
}

void CntEditViewPrivate::handleDeleteContact(int action)
{
    Q_Q(CntEditView);

    if(action == HbMessageBox::Yes || action == HbMessageBox::Delete)
    {
        QContactManager* cm = mMgr->contactManager( SYMBIAN_BACKEND );

        disconnect(cm, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)),
                this, SLOT(contactDeletedFromOtherSource(const QList<QContactLocalId>&)));
        emit q->contactRemoved(cm->removeContact( mContact->localId() ));
        
        mMgr->back( mArgs, true );
    }
}

void CntEditViewPrivate::discardChanges()
{
    Q_Q(CntEditView);
    
    emit q->changesDiscarded();
    
    // get a fresh one from backend.
    QContactManager* mgr = mMgr->contactManager(SYMBIAN_BACKEND);
    setSelectedContact( mgr->contact( mContact->localId()) );
    
    QVariant var;
    var.setValue(*mContact);
    
    CntViewParameters viewParameters;
    viewParameters.insert(ESelectedContact, var);
    
    if ( mArgs.value( EExtraAction ).toString() == CNT_ROOT_ACTION )
    {
        mMgr->back( viewParameters, true );
    }
    else
    {
        mMgr->back( viewParameters );
    }
       
}   

void CntEditViewPrivate::saveChanges()
{
    Q_Q(CntEditView);
    
    QString name = mMgr->contactManager(SYMBIAN_BACKEND)->synthesizedContactDisplayLabel(*mContact);
    
    if (name.isEmpty())
    {
        name = hbTrId("txt_phob_list_unnamed");
    }
    
    CntSaveManager::CntSaveResult result = mSaveManager->saveContact(mContact, mMgr->contactManager(SYMBIAN_BACKEND));
    
    QVariant var;
    bool backToRoot(false);
    
    switch (result)
    {
    case CntSaveManager::ESaved:
        emit q->contactUpdated(KCntServicesReturnValueContactSaved);
        HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contact_1_saved")).arg(name));
        var.setValue(*mContact);
        mArgs.insert(ESelectedContact, var);
        mArgs.insert(ESelectedAction, CNT_CREATE_ACTION);
        break;
    case CntSaveManager::EUpdated:
        emit q->contactUpdated(KCntServicesReturnValueContactSaved);
        HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contacts_1_updated")).arg(name));
        var.setValue(*mContact);
        mArgs.insert(ESelectedContact, var);
        mArgs.insert(ESelectedAction, CNT_EDIT_ACTION);
        break;
    case CntSaveManager::EFailed:
        emit q->contactUpdated(KCntServicesReturnValueContactNotModified);
        HbDeviceNotificationDialog::notification(QString(),hbTrId("SAVING FAILED!"));
        break;
    case CntSaveManager::EDeleted:
        emit q->contactRemoved(true);
        backToRoot = true;
        break;
    case CntSaveManager::ENothingDone:
    default:
        emit q->contactUpdated(KCntServicesReturnValueContactNotModified);
        break;
    }

    if ( mArgs.value( EExtraAction ).toString() == CNT_ROOT_ACTION )
    {
        backToRoot = true;
    }
    
    mMgr->back( mArgs, backToRoot );
}

void CntEditViewPrivate::openNameEditor()
{
    QVariant var;
    var.setValue(*mContact);
            
    mArgs.insert(EViewId, namesEditorView);
    mArgs.insert(ESelectedAction, QString());
    mArgs.insert(ESelectedContact, var);
    
    mMgr->changeView( mArgs );
}

void CntEditViewPrivate::openImageEditor()
{
    QVariant var;
    var.setValue(*mContact);
                
    mArgs.insert(ESelectedContact, var);
    mArgs.insert(ESelectedAction, QString());
    mArgs.insert(EViewId, imageEditorView );
        
    mMgr->changeView( mArgs );
}

void CntEditViewPrivate::loadAvatar()
{
    QList<QContactAvatar> details = mContact->details<QContactAvatar>();
    for (int i = 0;i < details.count();i++)
    {
        QUrl url = details.at(i).imageUrl();
        if ( url.isValid() )
        {
            mThumbnailManager->getThumbnail( url.toString() );
            break;
        }
    }
}

void CntEditViewPrivate::setScrollPosition()
{
    if ( mArgs.contains(ESelectedDetail) )
    {
        QContactDetail d = mArgs.value( ESelectedDetail ).value<QContactDetail>();
        
        QModelIndex index = mModel->itemIndex( d );
        if ( index.isValid() )
        {
            mListView->scrollTo( index, HbListView::EnsureVisible );
        }
    }
}

void CntEditViewPrivate::thumbnailReady( const QPixmap& pixmap, void *data, int id, int error )
{
    Q_UNUSED(data);
    Q_UNUSED(id);
    if (!error)
    {
        HbIcon icon(pixmap);
        mHeading->setIcon(icon);
        
        mImageLabel->clear();
        mImageLabel->setIcon(pixmap);
    }
}

HbMenu* CntEditViewPrivate::createPopup( const QModelIndex aIndex, CntEditViewItem* aDetail )
{
    HbMenu* menu = new HbMenu();
    CntStringMapper* map = new CntStringMapper();
    QVariant cd = aDetail->data( ERoleContactDetail );
    QContactDetail detail = cd.value<QContactDetail>();
    
    QVariant data( aIndex.row() );
    
    if ( !mModel->isEmptyItem(aDetail) ) 
    {
        // add is supported only on these items:
        // QContactPhonenumber, QContactOnlineAccount, QContactEmail, QContactUrl and QContactNote
        QString def = detail.definitionName(); 
        if ( def == QContactPhoneNumber::DefinitionName   || 
             def == QContactOnlineAccount::DefinitionName ||
             def == QContactEmailAddress::DefinitionName  ||
             def == QContactUrl::DefinitionName || 
             def == QContactNote::DefinitionName )
        {
            HbAction* add = menu->addAction(map->getContactEditorAddLocString(detail.definitionName(), ""));
            add->setProperty( "menu", HbAction::NewRole );
            add->setData( data );
        }
        
        QString context;
        QString subtype;
        if ( def == QContactPhoneNumber::DefinitionName )
        {
            QContactPhoneNumber number(detail); 
            context = number.contexts().isEmpty() ? QString() : number.contexts().first();
            subtype = number.subTypes().isEmpty() ? number.definitionName() : number.subTypes().first();
        }
        else if ( def == QContactOnlineAccount::DefinitionName )
        {
            QContactOnlineAccount number(detail); 
            context = number.contexts().isEmpty() ? QString() : number.contexts().first();
            subtype = number.subTypes().isEmpty() ? number.definitionName() : number.subTypes().first();
        }
        else if ( def == QContactFamily::DefinitionName )
        {
            QStringList fields = aDetail->data(ERoleContactDetailFields).toStringList();
            subtype = fields.first();
        }
        else
        {
            context = QString();
            subtype = detail.definitionName();
        }
        
        HbAction* edit = menu->addAction(hbTrId("txt_common_menu_edit"));
        HbAction* del = menu->addAction(map->getContactEditorDelLocString(subtype, context));
        edit->setProperty( "menu", HbAction::EditRole );
        del->setProperty( "menu" , HbAction::DeleteRole );
        edit->setData( data );
        del->setData( data );
    }
    else
    {
        HbAction* add = menu->addAction(map->getContactEditorAddLocString(detail.definitionName(), ""));
        add->setProperty( "menu", HbAction::NewRole );
        add->setData( data );
    }
    delete map;
    return menu;
}

void CntEditViewPrivate::addDetail( CntEditViewItem* aDetail )
{
    QVariant id = aDetail->data( ERoleEditorViewId );
    
    mArgs.insert(EViewId, id.toInt());
    mArgs.insert(ESelectedAction, CNT_ADD_ACTION );
    QVariant var;
    var.setValue(*mContact);
    
    mArgs.insert(ESelectedContact, var);
                                        
    mMgr->changeView( mArgs );
}

void CntEditViewPrivate::editDetail( CntEditViewItem* aDetail )
{
    QVariant id = aDetail->data( ERoleEditorViewId );
    
    mArgs.insert(EViewId, id.toInt());
    mArgs.insert(ESelectedAction, QString() );
    QVariant var;
    var.setValue(*mContact);
    
    mArgs.insert(ESelectedContact, var);
                                              
    mMgr->changeView( mArgs );
}

void CntEditViewPrivate::removeDetail( CntEditViewItem* aDetail, const QModelIndex& aIndex )
{
    mModel->removeItem( aDetail, aIndex );
    mSave->setEnabled( true );
    mDiscard->setEnabled( true );
}

void CntEditViewPrivate::setSelectedContact( QContact aContact )
{
    if ( mContact )
    {
        delete mContact;
        mContact = NULL;
    }
    mContact = new QContact( aContact );
    
    QContactManager* cm = mMgr->contactManager( SYMBIAN_BACKEND );
    connect(cm, SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), 
        this, SLOT(contactDeletedFromOtherSource(const QList<QContactLocalId>&)), Qt::UniqueConnection);
}

void CntEditViewPrivate::contactDeletedFromOtherSource(const QList<QContactLocalId>& contactIds)
{
    CNT_ENTRY
    
    if ( contactIds.contains(mContact->localId()) )
    {
        // Do not switch to the previous view immediately. List views are
        // not updated properly if this is not done in the event loop
        QTimer::singleShot(0, this, SLOT(showRootView()));
    }
    
    CNT_EXIT
}

void CntEditViewPrivate::showRootView()
{
    CNT_ENTRY
    
    Q_Q(CntEditView);
    
    emit q->contactRemoved(true);
    mMgr->back( mArgs, true );
    
    CNT_EXIT
}

// End of File