cmmanager/cpdestinationplugin/src/cpiapitem.cpp
changeset 20 9c97ad6591ae
child 23 7ec726f93df1
child 28 860702281757
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmmanager/cpdestinationplugin/src/cpiapitem.cpp	Mon May 03 12:53:07 2010 +0300
@@ -0,0 +1,527 @@
+/*
+* Copyright (c) 2010 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:  
+*   Data item for representing access points in UI.
+*/
+
+// System includes
+#include <QObject>
+#include <HbMenu>
+#include <HbAction>
+#include <HbDocumentLoader>
+#include <HbRadioButtonList>
+#include <HbDialog>
+#include <HbMessageBox>
+#include <HbPopup>
+#include <HbLabel>
+#include <HbDataFormViewItem>
+#include <HbDataForm>
+#include <HbDataFormModel>
+#include <cpbasesettingview.h>
+#include <cpsettingformitemdata.h>
+#include <cpsettingformentryitemdata.h>
+#include <cpitemdatahelper.h>
+#include <cmdestination_shim.h>
+#include <cmmanager_shim.h>
+#include <cmconnectionmethod_shim.h>
+
+// User includes
+#include "cpiapitem.h"
+#include "cpdestinationentryitem.h"
+#include "cpbearerapplugininterface.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "cpiapitemTraces.h"
+#endif
+/*!
+    \class  CpIapItem
+    \brief  This class represents access point in data model. 
+            It takes care of all access point related operations.
+*/
+
+// External function prototypes
+
+// Local constants
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+/*!         
+   Constructor.
+   
+   @param[in] itemDataHelper Helper for connecting signals and slots.
+   @param[in] iapId Unique ID if the access point this object represents.
+   @param[in] iapName Name of the access point this object represents.
+   @param[in] destId Unique ID of the destination that contains reference to 
+              the access point this object represents.
+   @param[in] bearerPlugin Pointer to the object that implements settings view
+              for this access point.
+ */
+CpIapItem::CpIapItem(
+    CpItemDataHelper &itemDataHelper,  
+    int iapId, 
+    const QString &iapName, 
+    int destId,
+    bool apProtected,
+    CpBearerApPluginInterface *bearerPlugin) :
+    CpSettingFormEntryItemData(itemDataHelper), 
+    mIapId(iapId), 
+    mIapName(iapName),
+    mDestId(destId),
+    mProtected(apProtected),
+    mBearerPlugin(bearerPlugin),
+    mMoveOngoing(false),
+    mDialog(0),
+    mList(0)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_CPIAPITEM_ENTRY);
+    try {
+        mCmm = new CmManagerShim();
+    } catch (const std::exception&) {
+        OstTrace0(TRACE_NORMAL, CPIAPITEM_CPIAPITEM, "CpIapItem::CpIapItem: Exception caught");
+        mCmm = NULL;
+    }
+    
+    // Fix connections
+    itemDataHelper.removeConnection(this,SIGNAL(pressed()),this,SLOT(onLaunchView()));
+    itemDataHelper.addConnection(
+        this,
+        SIGNAL(longPress(QPointF)),
+        this,
+        SLOT(showItemMenu(QPointF)));
+    if (!apProtected) {
+        itemDataHelper.addConnection(this,SIGNAL(clicked()),this,SLOT(onLaunchView()));
+    }
+    OstTraceFunctionExit0(CPIAPITEM_CPIAPITEM_EXIT);
+}
+
+/*!
+    Destructor
+ */
+CpIapItem::~CpIapItem()
+{
+    OstTraceFunctionEntry0(DUP1_CPIAPITEM_CPIAPITEM_ENTRY);
+    delete mCmm;
+    OstTraceFunctionExit0(DUP1_CPIAPITEM_CPIAPITEM_EXIT);
+}
+
+/*!
+    \return Returns ID of this access point
+ */
+int CpIapItem::getIapId() const
+{
+    OstTraceFunctionEntry0(CPIAPITEM_GETIAPID_ENTRY);
+    OstTraceFunctionExit0(CPIAPITEM_GETIAPID_EXIT);
+    return mIapId;
+}
+
+/*!
+    Shows user the item specific menu. The menu is triggered by long pressing
+    the access point item.
+    
+    @param[in] position Preferred position for the item specific menu.
+ */
+void CpIapItem::showItemMenu(QPointF position)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SHOWITEMMENU_ENTRY);
+    if (isCmManagerAvailable()) {
+        bool settingsReadSuccessful = true;
+        CMManagerShim::CmmProtectionLevel protLvl;
+        try {      
+            if (mDestId == 0) {
+                protLvl = CMManagerShim::ProtLevel0;
+            } else {
+                CmDestinationShim *destination = mCmm->destination(mDestId);
+                protLvl = destination->protectionLevel();
+                delete destination;
+            }              
+        } 
+        catch (const std::exception&)  {
+            OstTrace0(TRACE_NORMAL, CPIAPITEM_SHOWITEMMENU, "CpIapItem::showItemMenu: Exception caught");
+            settingsReadSuccessful = false;
+        }
+        if (settingsReadSuccessful) {
+            // Settings could be read from commsdat: show menu.
+            createItemMenu(protLvl, position)->show();
+        }    
+    }
+    OstTraceFunctionExit0(CPIAPITEM_SHOWITEMMENU_EXIT);
+}
+
+/*!
+    Prompts user for destination where access point is to be 
+    added and then makes the move in commsdat.
+ */
+void CpIapItem::moveIap()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_MOVEIAP_ENTRY);
+    mMoveOngoing = true;
+    queryDestination();
+    OstTraceFunctionExit0(CPIAPITEM_MOVEIAP_EXIT);
+}
+
+/*!
+    Shows confirmation query for access point deletion.
+ */
+void CpIapItem::showDeleteConfirmation()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SHOWDELETECONFIRMATION_ENTRY);
+    HbMessageBox *note = new HbMessageBox(HbMessageBox::MessageTypeQuestion);
+    note->clearActions();
+    note->setAttribute(Qt::WA_DeleteOnClose);
+    note->setText(hbTrId("txt_occ_info_delete_access_point_1").arg(mIapName));
+    HbAction *primaryAction = new HbAction(hbTrId("txt_common_button_yes"));
+    bool connected = connect(
+        primaryAction, 
+        SIGNAL(triggered()), 
+        this, 
+        SLOT(deleteConfirmed()));
+    Q_ASSERT(connected);
+    note->addAction(primaryAction);
+    note->addAction(new HbAction(hbTrId("txt_common_button_no")));
+    note->setTimeout(HbPopup::NoTimeout);
+    note->show();
+    OstTraceFunctionExit0(CPIAPITEM_SHOWDELETECONFIRMATION_EXIT);
+}
+
+/*!
+    Prompts user for target destination and then adds access point 
+    that this object represents to the prompted destination.
+ */
+void CpIapItem::shareIap()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SHAREIAP_ENTRY);
+    mMoveOngoing = false;
+    queryDestination();
+    OstTraceFunctionExit0(CPIAPITEM_SHAREIAP_EXIT);
+}
+
+/*!
+    Completes either saving or sharing of access point by 
+    making the move in commsdat.
+ */
+void CpIapItem::queryDialogClosed()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_QUERYDIALOGCLOSED_ENTRY);
+    if (mMoveOngoing) {
+        saveMove(mDestinationList[mList->selected()]);
+    } else {
+        saveShare(mDestinationList[mList->selected()]);
+    }
+    OstTraceFunctionExit0(CPIAPITEM_QUERYDIALOGCLOSED_EXIT);
+}
+
+/*!
+    Completes the deletion process by deleting access point from
+    commsdat.
+ */
+void CpIapItem::deleteConfirmed()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_DELETECONFIRMED_ENTRY);
+    bool deleteSuccessful = true;
+    try  {
+        if (mDestId != 0) {
+            CmDestinationShim *destination = mCmm->destination(mDestId);
+            CmConnectionMethodShim *cm = destination->connectionMethodByID(mIapId);
+            destination->deleteConnectionMethod(cm);
+            destination->update();
+            delete destination;
+        } else {
+            CmConnectionMethodShim *cm = mCmm->connectionMethod(mIapId);
+            cm->deleteConnectionMethod();
+            delete cm;
+        }
+    } catch (const std::exception&) {
+        OstTrace0(TRACE_NORMAL, DUP1_CPIAPITEM_DELETECONFIRMED, "CpIapItem::deleteConfirmed: Exception caught");
+        deleteSuccessful = false;
+    }
+    if (deleteSuccessful) {
+        HbDataForm *form = static_cast<HbDataForm*>(model()->parent());
+        QModelIndex index = static_cast<HbDataFormModel*>(this->model())->indexFromItem(this);
+        HbDataFormViewItem *viewItem = form->dataFormViewItem(index);
+        viewItem->deleteLater();
+        OstTrace0(TRACE_NORMAL, CPIAPITEM_DELETECONFIRMED, "CpIapItem::deleteConfirmed: Emit access point changed signal");
+        emit iapChanged();
+    } else {
+        showErrorNote(hbTrId("txt_occ_info_unable_to_save_setting"));
+    }
+    OstTraceFunctionExit0(CPIAPITEM_DELETECONFIRMED_EXIT);
+}
+
+/*!
+    Updates access point item name when the item becomes visible.
+ */
+void CpIapItem::updateIap(const QModelIndex index)
+{
+    OstTrace0( TRACE_FLOW, CPIAPITEM_UPDATEIAP_ENTRY, "CpIapItem::updateIap entry" );
+    Q_UNUSED(index);
+    try {
+        CmConnectionMethodShim *cm = mCmm->connectionMethod(mIapId);
+        this->setContentWidgetData("text", cm->getStringAttribute(CMManagerShim::CmName));
+        delete cm;
+    } catch (const std::exception&) {
+        OstTrace0( TRACE_NORMAL, CPIAPITEM_UPDATEIAP, "CpIapItem::updateIap: exception caught, CM name reading failed" );
+    }
+    // Disconnect because we need to do this only after returning
+    // from accees point settings view
+    HbDataForm *form = static_cast<HbDataForm*>(model()->parent());
+    disconnect(
+        form, 
+        SIGNAL(itemShown(const QModelIndex)),
+        this, 
+        SLOT(updateIap(const QModelIndex)));
+    OstTrace0( TRACE_FLOW, DUP1_CPIAPITEM_UPDATEIAP_EXIT, "CpIapItem::updateIap exit" );
+}
+
+/*!
+    Gets access point specific view from bearer plugin.
+    
+    \return Returns settings view containing access point settings.
+ */
+CpBaseSettingView *CpIapItem::createSettingView() const
+{
+    OstTraceFunctionEntry0(CPIAPITEM_CREATESETTINGVIEW_ENTRY);
+    CpBaseSettingView *view = NULL;
+    if (mBearerPlugin != NULL) {
+        HbDataForm *form = static_cast<HbDataForm*>(model()->parent()); 
+        bool connected = connect(
+            form, 
+            SIGNAL(itemShown(const QModelIndex)),
+            this, 
+            SLOT(updateIap(const QModelIndex)));
+        Q_ASSERT(connected);
+        view = mBearerPlugin->createSettingView(mIapId);
+    }
+    OstTraceFunctionExit0(CPIAPITEM_CREATESETTINGVIEW_EXIT);
+    return view;
+}
+
+/*!
+    Prompts user for destination.
+ */
+void CpIapItem::queryDestination()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_QUERYDESTINATION_ENTRY);
+    bool readingSuccessful = true;
+    QStringList destinations;
+    try {
+        mCmm->allDestinations(mDestinationList);
+        
+        for (int i = 0; i < mDestinationList.count(); i++) {
+            CmDestinationShim *destination = mCmm->destination(mDestinationList[i]);
+            if ((destination->id() != mDestId)
+                && !destination->isHidden()) {
+
+                QString dest = destination->name();
+                destinations.append(dest);
+            } else {
+                // Remove this destination from list to sync both lists
+                mDestinationList.removeAt(i);
+                i--;
+            }
+            delete destination;
+        }
+    } catch (const std::exception&) {
+        OstTrace0(TRACE_NORMAL, CPIAPITEM_QUERYDESTINATION, "CpIapItem::queryDestination: exception caught");
+        readingSuccessful = false;
+    }
+    
+    if (readingSuccessful) {
+        // Load DocML 
+        bool ok = false;
+        HbDocumentLoader *loader = new HbDocumentLoader();
+        loader->load(":/docml/cpdestinationplugindialogs.docml", &ok);
+        mDialog = qobject_cast<HbDialog *>(loader->findWidget("dialog"));
+        HbLabel *heading = qobject_cast<HbLabel *>(loader->findWidget("heading"));
+        heading->setPlainText(hbTrId("txt_occ_dialog_select_network_destination_to_be_ac"));
+        mList = qobject_cast<HbRadioButtonList *>(loader->findWidget("radioButtonList")); 
+        mList->setItems(destinations);
+        mList->setSelected(0);
+        mOk = qobject_cast<HbAction *>(loader->findObject("okAction"));
+        bool connected = connect(mOk, 
+                                 SIGNAL(triggered()), 
+                                 this, 
+                                 SLOT(queryDialogClosed()));
+        Q_ASSERT(connected);
+        mDialog->show();
+        delete loader;
+    } else {
+        OstTrace0(TRACE_NORMAL, DUP1_CPIAPITEM_QUERYDESTINATION, " CpIapItem::queryDestination: exception caught");
+        showErrorNote(hbTrId("txt_occ_info_unable_to_read_settings"));
+    }
+    OstTraceFunctionExit0(CPIAPITEM_QUERYDESTINATION_EXIT);
+}
+
+/*!
+    Shares access point to given destination.
+    
+    @param[in] id Target destination's ID
+ */
+void CpIapItem::saveShare(int id)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SAVESHARE_ENTRY);
+    try {
+        CmConnectionMethodShim *cm;
+        if (mDestId != 0) {
+            CmDestinationShim *source = mCmm->destination(mDestId);
+            cm = source->connectionMethodByID(mIapId);
+            delete source;
+        } else {
+            cm = mCmm->connectionMethod(mIapId);
+        }
+        CmDestinationShim *target = mCmm->destination(id);
+        target->addConnectionMethod(cm);
+        target->update();
+        delete cm;
+        delete target;
+        OstTrace0(TRACE_NORMAL, CPIAPITEM_SAVESHARE, "CpIapItem::saveShare: Emit access point changed signal");
+        emit iapChanged();
+    } catch (const std::exception&) {
+        OstTrace0(TRACE_NORMAL, DUP1_CPIAPITEM_SAVESHARE, "CpIapItem::saveShare: Exception caught");
+        showErrorNote(hbTrId("txt_occ_info_unable_to_read_settings"));
+    }
+    OstTraceFunctionExit0(CPIAPITEM_SAVESHARE_EXIT);
+}
+
+/*!
+    Moves access point from current destination to given destination.
+    
+    @param[in] id Target destination's ID
+ */
+void CpIapItem::saveMove(int id)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SAVEMOVE_ENTRY);
+    try {
+        // Make move in commsdat
+        CmConnectionMethodShim *cm = NULL;
+        if (mDestId != 0) {
+            CmDestinationShim *source = mCmm->destination(mDestId);
+            cm = source->connectionMethodByID(mIapId);
+            source->removeConnectionMethod(cm);
+            source->update();
+            delete source;
+        } else {
+            cm = mCmm->connectionMethod(mIapId);
+        }
+        CmDestinationShim *target = mCmm->destination(id);
+        target->addConnectionMethod(cm);
+        target->update();
+        delete target;
+        delete cm;
+    }
+    catch (const std::exception&) {
+        OstTrace0(TRACE_NORMAL, DUP1_CPIAPITEM_SAVEMOVE, "CpIapItem::saveMove: Exception caught");
+        showErrorNote(hbTrId("txt_occ_info_unable_to_save_setting"));
+    }
+    OstTrace0(TRACE_NORMAL, CPIAPITEM_SAVEMOVE, "CpIapItem::saveMove: Emit access point changed signal");
+    emit iapChanged(); 
+    OstTraceFunctionExit0(CPIAPITEM_SAVEMOVE_EXIT);
+}
+
+/*!
+    Tests if CmManagerShim has been created successfully
+    earlier. If not, it retries.
+ */
+bool CpIapItem::isCmManagerAvailable()
+{
+    OstTraceFunctionEntry0(CPIAPITEM_ISCMMANAGERAVAILABLE_ENTRY);
+    bool retval = false;
+    if (mCmm == NULL) {
+        try {
+            mCmm = new CmManagerShim();
+            retval = true;
+        }
+        catch (const std::exception&) {
+            OstTrace0(TRACE_NORMAL, CPIAPITEM_ISCMMANAGERAVAILABLE, "CpIapItem::isCmManagerAvailable: Exception caught");
+            mCmm = NULL;
+        }
+    } else {
+        retval = true;
+    }
+    OstTraceFunctionExit0(CPIAPITEM_ISCMMANAGERAVAILABLE_EXIT);
+    return retval;
+}
+
+/*!
+    Helper function for creating item specific menu.
+    
+    @param[in] protLvl Effective protection level for this
+                       access point.
+ */
+HbMenu *CpIapItem::createItemMenu(
+    CMManagerShim::CmmProtectionLevel protLvl,
+    const QPointF &position)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_CREATEITEMMENU_ENTRY);
+    HbMenu* menu = new HbMenu();
+    menu->setAttribute(Qt::WA_DeleteOnClose);
+    HbAction* moveIapAction 
+        = menu->addAction(hbTrId("txt_occ_menu_move_to_other_destination"));
+    bool connected = connect(moveIapAction, SIGNAL(triggered()), this, SLOT(moveIap()));
+    Q_ASSERT(connected);
+    HbAction* deleteIapAction 
+        = menu->addAction(hbTrId("txt_common_menu_delete"));
+    connected = connect(
+        deleteIapAction, 
+        SIGNAL(triggered()), 
+        this, 
+        SLOT(showDeleteConfirmation()));
+    Q_ASSERT(connected);
+    HbAction* shareIapAction 
+        = menu->addAction(hbTrId("txt_occ_menu_share_to_other_destination"));
+    connected = connect(shareIapAction, SIGNAL(triggered()), this, SLOT(shareIap()));
+    Q_ASSERT(connected);
+       
+    if (protLvl == CMManagerShim::ProtLevel1) {
+        // Disable operations for protected destinations
+        moveIapAction->setDisabled(true);
+        deleteIapAction->setDisabled(true);
+        shareIapAction->setDisabled(true);
+    } else if (protLvl == CMManagerShim::ProtLevel3) {
+        // Disable operations for protected access points.
+        moveIapAction->setDisabled(mProtected);
+        deleteIapAction->setDisabled(mProtected);
+        shareIapAction->setDisabled(mProtected);
+    }
+    
+    // Can't share uncategorised APs
+    if (mDestId == 0)
+    {
+        shareIapAction->setDisabled(true);
+    }
+       
+    menu->setPreferredPos(position);
+    OstTraceFunctionExit0(CPIAPITEM_CREATEITEMMENU_EXIT);
+    return menu;
+}
+
+/*!
+    Helper function for showing error notes.
+    
+    @param[in] info Info string to be shown in note.
+ */
+void CpIapItem::showErrorNote(const QString &info)
+{
+    OstTraceFunctionEntry0(CPIAPITEM_SHOWERRORNOTE_ENTRY);
+    HbMessageBox *note = new HbMessageBox(HbMessageBox::MessageTypeInformation);
+    note->clearActions();
+    note->setAttribute(Qt::WA_DeleteOnClose);
+    note->setText(info);
+    note->setTimeout(HbPopup::NoTimeout);
+    HbAction *errorOk = new HbAction(hbTrId("txt_common_button_ok"));                       
+    note->addAction(errorOk);
+    note->show();    
+    OstTraceFunctionExit0(CPIAPITEM_SHOWERRORNOTE_EXIT);
+}