phonebookui/cntcommonui/views/cntimageeditorview.cpp
changeset 75 4ecbe3571b5a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/cntcommonui/views/cntimageeditorview.cpp	Mon Oct 04 00:06:02 2010 +0300
@@ -0,0 +1,473 @@
+/*
+* 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 "cntimageeditorview.h"
+#include "cntthumbnailmanager.h"
+#include "cntimageutility.h"
+#include "cntsavemanager.h"
+#include "cntimagelabel.h"
+
+#include <hblabel.h>
+#include <xqaiwrequest.h>
+#include <xqaiwdecl.h>
+
+#include "cntdebug.h"
+#include "cntglobal.h"
+
+#include <hbaction.h>
+#include <hbview.h>
+#include <hbmainwindow.h>
+#include <hblistview.h>
+#include <hblistviewitem.h>
+#include <hbframebackground.h>
+#include <hbdevicenotificationdialog.h>
+#include <hbparameterlengthlimiter.h>
+
+#include <QStandardItemModel>
+#include <QApplication>
+
+const char *CNT_IMAGE_XML = ":/xml/contacts_if.docml";
+
+/*!
+Constructor
+*/
+CntImageEditorView::CntImageEditorView() :
+    mContact(NULL),
+    mAvatar(NULL),
+    mImageLabel(NULL),
+    mRequest(NULL),
+    mViewManager(NULL),
+    mListView(NULL),
+    mModel(NULL),
+    mSaveManager(NULL)
+{
+    bool ok = false;
+    mDocumentLoader.load(CNT_IMAGE_XML, &ok);
+
+    if (ok)
+    {
+        mView = static_cast<HbView*>(mDocumentLoader.findWidget(QString("view")));
+    }
+    else
+    {
+        qFatal("Unable to read :/xml/contacts_if.docml");
+    }
+    
+    //back button
+    mSoftkey = new HbAction(Hb::BackNaviAction, mView);
+    connect(mSoftkey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
+    
+    // menu action
+    mRemoveImage = static_cast<HbAction*>(mDocumentLoader.findObject("cnt:removeimage"));
+    connect(mRemoveImage, SIGNAL(triggered()), this, SLOT(removeImage()));
+
+    // closing the application from task swapper or end key will cause the contact to be saved
+    connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(saveContact()));
+}
+
+/*!
+Destructor
+*/
+CntImageEditorView::~CntImageEditorView()
+{
+    CNT_ENTRY
+    
+    mView->deleteLater();
+
+    delete mAvatar;
+    mAvatar = NULL;
+    delete mContact;
+    mContact = NULL;
+    delete mRequest;
+    mRequest = NULL;
+    delete mRemoveImage;
+    mRemoveImage = NULL;
+    delete mModel;
+    mModel = NULL;
+    delete mSaveManager;
+    mSaveManager = NULL;
+    
+    CNT_EXIT
+}
+
+/*!
+Called when activating the view
+*/
+void CntImageEditorView::activate( const CntViewParameters aArgs )
+{
+    mArgs = aArgs;
+    
+    mViewManager = &mEngine->viewManager();
+    mThumbnailManager = &mEngine->thumbnailManager();
+    connect( mThumbnailManager, SIGNAL(thumbnailReady(QPixmap, void*, int, int)),
+            this, SLOT(thumbnailReady(QPixmap, void*, int, int)) );
+       
+    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());
+    }
+    
+    if ( mArgs.contains(ESelectedContact))
+    {
+        mContact = new QContact(mArgs.value(ESelectedContact).value<QContact>());
+    }
+    
+    if ( mArgs.contains(ESelectedGroupContact) && !mContact ) 
+    {
+        mContact = new QContact(mArgs.value(ESelectedGroupContact).value<QContact>());
+    }
+    
+    QString myCard = mArgs.value( EMyCard ).toString();
+    QContactLocalId localId = mContact->localId();
+    QContactLocalId selfContactId = mEngine->contactManager(SYMBIAN_BACKEND).selfContactId();
+    bool isMyCard = ( localId == selfContactId && localId != 0 ) || !myCard.isEmpty();
+    
+    if (isMyCard)
+    {
+        mSaveManager = new CntSaveManager(CntSaveManager::EMyCard);
+    }
+    else if (mContact->type() == QContactType::TypeGroup)
+    {
+        mSaveManager = new CntSaveManager(CntSaveManager::EGroup);
+    }
+    else
+    {
+        mSaveManager = new CntSaveManager();
+    }
+    
+    // set the correct image if the contact already has an image set
+    mImageLabel = static_cast<CntImageLabel*>(mDocumentLoader.findWidget(QString("cnt_image_label")));
+    mImageLabel->ungrabGesture(Qt::TapGesture);
+    QList<QContactAvatar> details = mContact->details<QContactAvatar>();
+    if (details.count() > 0)
+        {
+        for (int i = 0;i < details.count();i++)
+            {
+                if (details.at(i).imageUrl().isValid())
+                    {
+                    mAvatar = new QContactAvatar(details.at(i));
+                    mThumbnailManager->getThumbnail(ThumbnailManager::ThumbnailLarge, mAvatar->imageUrl().toString());
+                    break;
+                    }
+            }
+        }
+    else
+        {
+        mAvatar = new QContactAvatar();
+        mRemoveImage->setEnabled(false);
+        if (mContact->type() == QContactType::TypeGroup)
+            {
+            mImageLabel->setAvatarIcon(HbIcon("qtg_large_add_group_picture"));
+            }
+        }
+    
+    // set up the list
+    mListView = static_cast<HbListView*>(mDocumentLoader.findWidget(QString("cnt_listview")));
+    
+    connect(mListView, SIGNAL(activated(const QModelIndex&)), this,
+        SLOT(listViewActivated(const QModelIndex&)));
+    
+    HbFrameBackground frame;
+    frame.setFrameGraphicsName("qtg_fr_list_normal");
+    frame.setFrameType(HbFrameDrawer::NinePieces);
+    mListView->itemPrototypes().first()->setDefaultFrame(frame);
+    
+    mListView->listItemPrototype()->setGraphicsSize(HbListViewItem::LargeIcon);
+    mListView->setUniformItemSizes(true);
+    
+    mModel = new QStandardItemModel();
+    populateModel(mModel);
+    mListView->setModel(mModel);
+}
+
+void CntImageEditorView::deactivate()
+{
+
+}
+
+void CntImageEditorView::populateModel(QStandardItemModel *model)
+{
+    QStandardItem *newPhoto = new QStandardItem();
+    newPhoto->setText(hbTrId("txt_phob_list_take_a_new_photo"));
+    newPhoto->setData(HbIcon("qtg_large_camera"), Qt::DecorationRole);
+    model->appendRow(newPhoto);
+    
+    QStandardItem *fromGallery = new QStandardItem();
+    fromGallery->setText(hbTrId("txt_phob_list_chooce_from_gallery"));
+    fromGallery->setData(HbIcon("qtg_large_photos"), Qt::DecorationRole);
+    model->appendRow(fromGallery);
+}
+
+/*!
+Open camera and get new image for contact
+*/
+void CntImageEditorView::openCamera()
+{
+    CNT_ENTRY
+    
+    if (mRequest)
+    {
+        delete mRequest;
+        mRequest = 0;
+    }
+    
+    mRequest = mAppManager.create(XQI_CAMERA_CAPTURE, XQOP_CAMERA_CAPTURE, false);
+    if ( mRequest ) 
+    {
+        int mode = 0; //image mode
+        
+        QVariantMap map;
+        map.insert(XQCAMERA_INDEX, 0);
+        map.insert(XQCAMERA_QUALITY, 0);
+        map.insert(XQCAMERA_MODE_SWITCH, false);
+        map.insert(XQCAMERA_INDEX_SWITCH, false);
+        map.insert(XQCAMERA_QUALITY_CHANGE, true);
+        
+        // Set function parameters
+        QList<QVariant> args;
+        args << mode;
+        args << map;
+        mRequest->setArguments(args);
+        
+        connect(mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleImageChange(const QVariant&)));
+        connect(mRequest, SIGNAL(requestError(int,const QString&)), this, SLOT(handleError(int,const QString&)));
+
+        mRequest->send();
+    }
+    
+    CNT_EXIT
+}
+
+/*!
+Open gallery and select image for contact
+*/
+void CntImageEditorView::openGallery()
+{
+    if (mRequest)
+    {
+        delete mRequest;
+        mRequest = 0;
+    }
+    
+    mRequest = mAppManager.create(XQI_IMAGE_FETCH, XQOP_IMAGE_FETCH, true);
+    if ( mRequest ) 
+    {
+        connect(mRequest, SIGNAL(requestOk(const QVariant&)), this, SLOT(handleImageChange(const QVariant&)));
+        mRequest->send();
+    }
+}
+
+/*!
+Called when user closes the view
+*/
+void CntImageEditorView::showPreviousView()
+{
+    mContact->saveDetail(mAvatar);
+
+    if ( mAvatar->imageUrl().isEmpty())
+    {
+        mContact->removeDetail(mAvatar);
+    }
+    
+    QVariant var;
+    var.setValue(*mContact);
+    
+    // If the arguments didn't originally contain "normal" contact,
+    // then the group contact should be updated. This case applies only
+    // when group image is edited
+    if ( !mArgs.contains(ESelectedContact) )
+    {
+        mArgs.insert(ESelectedGroupContact, var);
+    }
+    else
+    {
+        mArgs.insert(ESelectedContact, var);
+    }
+    
+    mArgs.insert(ECustomParam, viewId());
+    mViewManager->back( mArgs );
+}
+
+void CntImageEditorView::removeImage()
+{
+    QString filePath=mAvatar->imageUrl().toString();
+    if(!filePath.isEmpty())
+    {
+        // Check if image removable.
+        CntImageUtility imageUtility;
+        if(imageUtility.isImageRemovable(filePath))
+        {
+            imageUtility.removeImage(filePath);
+        }
+        
+        mAvatar->setImageUrl(QUrl());
+        mImageLabel->clear();
+        if (mContact->type() == QContactType::TypeGroup)
+            mImageLabel->setAvatarIcon(HbIcon("qtg_large_add_group_picture"));
+        else
+            mImageLabel->setAvatarIcon(HbIcon("qtg_large_add_contact_picture"));
+        mRemoveImage->setEnabled(false);
+    }
+}
+
+/*!
+Set the selected image as new QContactAvatar::SubTypeImage
+*/
+void CntImageEditorView::handleImageChange(const QVariant &value)
+{
+    CNT_ENTRY_ARGS("image path = " << value.toString())
+    
+    if(value.canConvert<QString>())
+    {
+        CntImageUtility imageUtility;
+        if(imageUtility.isMassStorageAvailable())
+        {
+            CNT_LOG_ARGS("mass storage available")
+            /* Copy image and create thumbnail
+             * When contact image removed only copy is deleted
+             */
+            QString imagepath;
+            if(imageUtility.createImage(value.toString(),imagepath))
+            {
+                
+                // If image already assigned, delete
+                QString filePath=mAvatar->imageUrl().toString();
+                if(!filePath.isEmpty()
+                   && imageUtility.isImageRemovable(filePath))
+                    imageUtility.removeImage(filePath);
+            
+                CNT_LOG_ARGS("image created, image = " << filePath)
+                
+                mAvatar->setImageUrl(QUrl(imagepath));
+                mThumbnailManager->getThumbnail(ThumbnailManager::ThumbnailLarge, imagepath);
+                mRemoveImage->setEnabled(true);
+            }
+        }
+        else
+        {
+            // No mass memory, use the orginal image
+            mAvatar->setImageUrl(QUrl(value.toString()));
+            mThumbnailManager->getThumbnail(ThumbnailManager::ThumbnailLarge, value.toString());
+            mRemoveImage->setEnabled(true);
+        }
+    }
+    
+    CNT_EXIT
+}
+
+void CntImageEditorView::thumbnailReady(const QPixmap& pixmap, void *data, int id, int error)
+{
+    CNT_ENTRY_ARGS("error code = " << error)
+    
+    Q_UNUSED(data);
+    Q_UNUSED(id);
+    if (!error)
+    {
+        mImageLabel->clear();
+        mImageLabel->setIcon(pixmap);
+    }
+    
+    CNT_EXIT
+}
+
+void CntImageEditorView::setOrientation(Qt::Orientation orientation)
+{
+    if (orientation == Qt::Vertical) 
+    {
+        // reading "portrait" section
+        mDocumentLoader.load(CNT_IMAGE_XML, "portrait");
+    } 
+    else 
+    {
+        // reading "landscape" section
+        mDocumentLoader.load(CNT_IMAGE_XML, "landscape");
+    }
+}
+
+/*!
+Figure out which item was selected according to row number
+*/
+void CntImageEditorView::listViewActivated(const QModelIndex &index)
+{
+    if (index.isValid())
+    {
+        int row = index.row();
+        switch(row)
+        {
+        case 0: // first item is always "take photo"
+            openCamera();
+            break;
+        case 1: // and the second one is always "choose from gallery"
+            openGallery();
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+void CntImageEditorView::handleError(int errorCode, const QString& errorMessage)
+{
+    Q_UNUSED(errorCode);
+    Q_UNUSED(errorMessage);
+    CNT_LOG_ARGS("error code = " << errorCode << "errorMessage=" << errorMessage)
+}
+
+void CntImageEditorView::saveContact()
+{
+    mContact->saveDetail(mAvatar);
+
+    if ( mAvatar->imageUrl().isEmpty())
+    {
+        mContact->removeDetail(mAvatar);
+    }
+    
+    QString name = mEngine->contactManager(SYMBIAN_BACKEND).synthesizedContactDisplayLabel(*mContact);
+    
+    if (name.isEmpty())
+    {
+        name = hbTrId("txt_phob_list_unnamed");
+    }
+    
+    CntSaveManager::CntSaveResult result = mSaveManager->saveContact(mContact, &mEngine->contactManager(SYMBIAN_BACKEND));
+    
+    if (mContact->type() != QContactType::TypeGroup)
+    {
+        switch (result)
+        {
+        case CntSaveManager::ESaved:
+            HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contact_1_saved")).arg(name));
+            break;
+        case CntSaveManager::EUpdated:
+            HbDeviceNotificationDialog::notification(QString(),HbParameterLengthLimiter(hbTrId("txt_phob_dpophead_contacts_1_updated")).arg(name));
+            break;
+        case CntSaveManager::EFailed:
+            HbDeviceNotificationDialog::notification(QString(),hbTrId("SAVING FAILED!"));
+            break;
+        case CntSaveManager::EDeleted:
+        case CntSaveManager::ENothingDone:
+        default:
+            break;
+        }
+    }
+}
+