phonebookui/pbkcommonui/src/cnteditview_p.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 03 May 2010 12:24:20 +0300
changeset 27 de1630741fbe
child 31 2a11b5b00470
permissions -rw-r--r--
Revision: 201015 Kit: 201018

/*
* 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 <hbdocumentloader.h>
#include <thumbnailmanager_qt.h>
#include <hbabstractviewitem.h>
#include <hbmessagebox.h>
#include <hbmainwindow.h>
#include <hbview.h>
#include <hblistview.h>
#include <hbaction.h>
#include <hbmenu.h>
#include <hbframebackground.h>

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

CntEditViewPrivate::CntEditViewPrivate() :
mModel( NULL ),
mImageLabel( NULL ),
mThumbnailManager( 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") );
    mSave = static_cast<HbAction*>( mDocument->findObject("cnt:savecontact") );
    mDelete = static_cast<HbAction*>( mDocument->findObject("cnt:deletecontact") );
    
    HbAction* add = static_cast<HbAction*>( mDocument->findObject("cnt:adddetail_options") );
    HbAction* removeContact = static_cast<HbAction*>( mDocument->findObject("cnt:deletecontact") );
    
    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&)) );
}

CntEditViewPrivate::~CntEditViewPrivate()
{
    mView->deleteLater();
    delete mDocument;
    delete mListView;
    delete mModel;
    delete mContact;
    delete mThumbnailManager;
}

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 )
{
    mMgr = aMgr;
    if ( mView->navigationAction() != mSoftkey)
    {
        mView->setNavigationAction(mSoftkey);
    }
    HbMainWindow* window = mView->mainWindow();
    if ( window )
    {
        connect(window, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(setOrientation(Qt::Orientation)));
        setOrientation(window->orientation());
    }
        
    QVariant contact = aArgs.value( ESelectedContact );
    mContact = new QContact( contact.value<QContact>() );
    QContactLocalId localId = mContact->localId();
    
    QContactManager* cm = mMgr->contactManager(SYMBIAN_BACKEND);
    QContactLocalId selfContactId = cm->selfContactId();
    
    HbMenu* menu = mView->menu();
    // don't delete contact which is "MyCard" or not saved yet or both.
    if ( localId == selfContactId && selfContactId != 0 && 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 );
    }
    
    mHeading->setDetails( mContact );
    mModel = new CntEditViewListModel( mContact );
    mListView->setModel( mModel );

    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();
}

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

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 );
        mModel->refreshExtensionItems( aItem->modelIndex() );
    }
    // only detail items are able to show context specific menu
    else
    {
        QVariant cd = item->data( ERoleContactDetail );
        
        HbMenu* menu = new HbMenu();
        menu->addActions( createPopup(item) );
        HbAction* selected = menu->exec( aCoords );
        
        if ( selected )
        {
            switch ( selected->commandRole() )  
            {
                case HbAction::EditRole:
                {
                    editDetail( item );
                }
                break;
                
                case HbAction::NewRole:
                {
                    addDetail( item );
                }
                break;
                
                case HbAction::DeleteRole:
                {
                    removeDetail( item, aItem->modelIndex() );
                }
                break;
                
                default:
                    break;
            }
        }
        
        delete menu;
    }
}

void CntEditViewPrivate::addDetailItem()
{
    int detailEditorId = CntDetailPopup::selectDetail();
    if (detailEditorId != noView )
    {
        CntViewParameters viewParameters;
        viewParameters.insert(EViewId, detailEditorId );
        switch ( detailEditorId )
        {
        case phoneNumberEditorView:
        case emailEditorView:
        case urlEditorView:
        case noteEditorView:
            viewParameters.insert( ESelectedAction, "add" );
            break;
        case addressEditorView:
        case dateEditorView:
        case companyEditorView:
        case familyDetailEditorView:
            viewParameters.insert( ESelectedAction, "focus" );
            break;
        default:
            break;
        }
        QVariant var;
        var.setValue(*mContact);
        viewParameters.insert(ESelectedContact, var);
        mMgr->changeView(viewParameters);
    }
}

void CntEditViewPrivate::deleteContact()
{
    QContactManager* cm = mMgr->contactManager( SYMBIAN_BACKEND );
    QString name = cm->synthesizedDisplayLabel( *mContact );

    HbMessageBox *note = new HbMessageBox(hbTrId("txt_phob_info_delete_1").arg(name), HbMessageBox::MessageTypeQuestion);
    note->setPrimaryAction(new HbAction(hbTrId("txt_phob_button_delete"), note));
    note->setSecondaryAction(new HbAction(hbTrId("txt_common_button_cancel"), note));
    HbAction *selected = note->exec();
    if (selected == note->primaryAction())
    {
        cm->removeContact( mContact->localId() );
        emit contactRemoved();
        
        CntViewParameters viewParameters;
        mMgr->back( viewParameters );
    }
    delete note;
}

void CntEditViewPrivate::discardChanges()
{
    emit changesDiscarded();
    
    // get a fresh one from backend.
    QContactManager* mgr = mMgr->contactManager(SYMBIAN_BACKEND);
    mContact = new QContact(mgr->contact( mContact->localId() ));
    
    QVariant var;
    var.setValue(*mContact);
    
    CntViewParameters viewParameters;
    viewParameters.insert(ESelectedContact, var);
            
    mMgr->back( viewParameters );
}

void CntEditViewPrivate::saveChanges()
{
    QContactManager* mgr = mMgr->contactManager( SYMBIAN_BACKEND );
    mgr->saveContact( mContact );
    emit contactUpdated();
    
    QVariant var;
    var.setValue(*mContact);
        
    CntViewParameters viewParameters;
    viewParameters.insert(ESelectedContact, var);
    viewParameters.insert( ESelectedAction, "save" );    
    
    mMgr->back( viewParameters );
}

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

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

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::thumbnailReady( const QPixmap& pixmap, void *data, int id, int error )
{
    Q_UNUSED(data);
    Q_UNUSED(id);
    if (!error)
    {
        QIcon qicon(pixmap);
        HbIcon icon(qicon);
        mHeading->setIcon(icon);
        
        mImageLabel->clear();
        mImageLabel->setIcon(icon);
    }
}

QList<QAction*> CntEditViewPrivate::createPopup( CntEditViewItem* aDetail )
{
    QList<QAction*> actions;
    CntStringMapper* map = new CntStringMapper();
    QVariant cd = aDetail->data( ERoleContactDetail );
    QContactDetail detail = cd.value<QContactDetail>();
    
    HbAction* edit = static_cast<HbAction*>(mDocument->findObject("cnt:editdetail"));
            
    HbAction* add = static_cast<HbAction*>(mDocument->findObject("cnt:adddetail_popup"));
    QString text = add->text();
    add->setText( text.arg( "%1", map->getMappedDetail(detail.definitionName())) );
            
    HbAction* del = static_cast<HbAction*>(mDocument->findObject("cnt:deletedetail"));
    text = edit->text();
    del->setText( text.arg("%1", map->getMappedDetail(detail.definitionName())) );
        
    add->setCommandRole( HbAction::NewRole );
    edit->setCommandRole( HbAction::EditRole );
    del->setCommandRole( HbAction::DeleteRole );
            
    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 )
        {
            actions.append( add );
        }
        actions.append( edit );
        actions.append( del );
    }
    else
    {
        actions.append( edit );
    }
    delete map;
    return actions;
}

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

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

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