diff -r b852595f5cbe -r 63be7eb3fc78 wlanutilities/wlansniffer/wlansnifferapplication/src/wlansnifferlistview.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wlanutilities/wlansniffer/wlansnifferapplication/src/wlansnifferlistview.cpp Tue Aug 31 16:18:40 2010 +0300 @@ -0,0 +1,687 @@ +/* +* Copyright (c) 2009-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: +* WLAN Sniffer List View. +*/ + +// System includes + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// User includes + +#include "wlanqtutils.h" +#include "wlanqtutilsap.h" +#include "wlanqtutilsiap.h" + +#include "wlansnifferengine.h" +#include "wlansniffermainwindow.h" +#include "wlansnifferlistview.h" +#include "wlansnifferlistitem.h" +#include "wlansnifferlistwidget.h" + +#include "OstTraceDefinitions.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "wlansnifferlistviewTraces.h" +#endif + +/*! + \class WlanSnifferListView + \brief WLAN Sniffer application's list view implementation. +*/ + +// External function prototypes + +// Local constants + +//! WLAN Sniffer list view docml file location +static const QString WlanSnifferListViewDocml(":/docml/wlansnifferlistview.docml"); + +//! WLAN Sniffer list view object name +static const QString WlanSnifferListViewName("occ_list"); + +// ======== LOCAL FUNCTIONS ======== + +// ======== MEMBER FUNCTIONS ======== + +/*! + Constructor. + + @param [in] engine WLAN Sniffer application engine. + @param [in] mainWindow WLAN Sniffer main window. +*/ + +WlanSnifferListView::WlanSnifferListView( + WlanSnifferEngine *engine, + WlanSnifferMainWindow *mainWindow) : + HbView(), + mDocLoader(new HbDocumentLoader(mainWindow)), + mWlanListWidget(), + mContextMenu(), + mContextMenuData(), + mWlanEnableDialog(), + mIgnoreWlanScanResults(false), + mConnectingIapId(WlanQtUtils::IapIdNone), + mEngine(engine), + mSwitchWlanAction(0), + mAddWlanAction(0), + mWlanList(0), + mStatusLabel(0), + mWlanButton(0) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_WLANSNIFFERLISTVIEW_ENTRY); + + // Initialize UI from the docml based on standalone/embedded status + loadDocml(mEngine->isEmbedded()); + + if (mEngine->isEmbedded()) { + // We need to create a custom navigation action and handle exiting + // from the application differently in case the application was + // launched as embedded via QtHighway + HbAction *completeAction = new HbAction(Hb::BackNaviAction, this); + setNavigationAction(completeAction); + bool connectStatus = connect( + completeAction, + SIGNAL(triggered(bool)), + mEngine, + SLOT(completeService())); + Q_ASSERT(connectStatus); + } + + // Connect WLAN network open & close signals + bool connectStatus = connect( + mEngine->wlanQtUtils(), + SIGNAL(wlanNetworkOpened(int)), + this, + SLOT(updateConnectionOpened(int))); + Q_ASSERT(connectStatus); + connectStatus = connect( + mEngine->wlanQtUtils(), + SIGNAL(wlanNetworkClosed(int, int)), + this, + SLOT(updateConnectionClosed(int))); // "reason" parameter ignored + Q_ASSERT(connectStatus); + + // Connect WLAN ON/OFF setting change signal + connectStatus = connect( + mEngine, + SIGNAL(masterWlanStatus(bool)), + this, + SLOT(updateWlanEnabled())); + Q_ASSERT(connectStatus); + + // Connect Force Disable WLAN setting change signal + connectStatus = connect( + mEngine, + SIGNAL(forceDisableWlanStatus(bool)), + this, + SLOT(updateWlanEnabled())); + Q_ASSERT(connectStatus); + + // Connect signals to catch user interaction with the WLAN network list + connectStatus = connect( + mWlanList, + SIGNAL(activated(HbListWidgetItem *)), + this, + SLOT(handleListItemActivated(HbListWidgetItem *))); + Q_ASSERT(connectStatus); + connectStatus = connect( + mWlanList, + SIGNAL(longPressed(HbListWidgetItem *, QPointF)), + this, + SLOT(handleListItemLongPressed(HbListWidgetItem *, QPointF))); + Q_ASSERT(connectStatus); + + // Connect signals to catch user interaction with WLAN ON/OFF switching + connectStatus = connect( + mWlanButton, + SIGNAL(clicked(bool)), + this, + SLOT(handleWlanToggled())); + Q_ASSERT(connectStatus); + connectStatus = connect( + mSwitchWlanAction, + SIGNAL(triggered(bool)), + this, + SLOT(handleWlanToggled())); + Q_ASSERT(connectStatus); + + // Connect adding WLAN manually + connectStatus = connect( + mAddWlanAction, + SIGNAL(triggered(bool)), + this, + SLOT(startWlanWizard())); + Q_ASSERT(connectStatus); + + // Connect WLAN scan results signal + connectStatus = connect( + mEngine, + SIGNAL(wlanScanReady()), + this, + SLOT(updateListContent())); + Q_ASSERT(connectStatus); + + // Set the initial value of WLAN state + updateWlanEnabled(); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_WLANSNIFFERLISTVIEW_EXIT); +} + +/*! + Destructor. +*/ + +WlanSnifferListView::~WlanSnifferListView() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_WLANSNIFFERLISTVIEWDESTR_ENTRY); + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_WLANSNIFFERLISTVIEWDESTR_EXIT); +} + +/*! + Loading of WLAN Sniffer List View docml. + + @param [in] isEmbedded TRUE if WLAN Sniffer is launched as embedded. +*/ + +void WlanSnifferListView::loadDocml(bool isEmbedded) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_LOADDOCML_ENTRY); + + // Pass the view to the document loader. Document loader uses this view + // when docml is parsed, instead of creating a new view. + setObjectName(WlanSnifferListViewName); + QObjectList objectList; + objectList.append(this); + mDocLoader->setObjectTree(objectList); + + // First load the common section + bool ok = false; + mDocLoader->load(WlanSnifferListViewDocml, &ok); + Q_ASSERT(ok); + + // Then load the mode specific section + if (isEmbedded) { + mDocLoader->load(WlanSnifferListViewDocml, "embedded", &ok); + } else { + mDocLoader->load(WlanSnifferListViewDocml, "standalone", &ok); + } + Q_ASSERT(ok); + + // Load the view by name from the xml file + QGraphicsWidget *widget = mDocLoader->findWidget(WlanSnifferListViewName); + Q_ASSERT(widget); + + // Set view menu + HbMenu *viewMenu = qobject_cast(mDocLoader->findWidget("viewMenu")); + Q_ASSERT(viewMenu); + setMenu(viewMenu); + + // WLAN Sniffer list widget takes responsibility of the list widget behaviour + mWlanList = qobject_cast(mDocLoader->findWidget("listWidget")); + Q_ASSERT(mWlanList); + mWlanListWidget = QSharedPointer(new WlanSnifferListWidget(mWlanList)); + + // Retrieve pointers to widgets we need to access from the code + mSwitchWlanAction = qobject_cast(mDocLoader->findObject("switchWlanAction")); + Q_ASSERT(mSwitchWlanAction); + + mAddWlanAction = qobject_cast(mDocLoader->findObject("addWlanAction")); + Q_ASSERT(mAddWlanAction); + + mWlanButton = qobject_cast(mDocLoader->findWidget("wlanButton")); + Q_ASSERT(mWlanButton); + + mStatusLabel = qobject_cast(mDocLoader->findWidget("statusLabel")); + Q_ASSERT(mStatusLabel); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_LOADDOCML_EXIT); +} + +/*! + Updates WLAN status label based on current WLAN status. + + @param [in] enabled True if WLAN is enabled. +*/ + +void WlanSnifferListView::updateWlanStatusLabel(bool enabled) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_UPDATEWLANSTATUSLABEL_ENTRY); + + QString status; + if (!enabled) { + // WLAN is OFF + status = hbTrId("txt_occ_grid_wlan_is_switched_off"); + } else { + int iapId = mEngine->wlanQtUtils()->activeIap(); + + switch (mEngine->wlanQtUtils()->connectionStatus()) { + case WlanQtUtils::ConnStatusConnecting: + // WLAN is connecting + Q_ASSERT(iapId != WlanQtUtils::IapIdNone); + status = HbParameterLengthLimiter( + "txt_occ_grid_connecting_to_1").arg( + mEngine->wlanQtUtils()->iapName(iapId)); + break; + + case WlanQtUtils::ConnStatusConnected: + // WLAN is connected + Q_ASSERT(iapId != WlanQtUtils::IapIdNone); + status = HbParameterLengthLimiter( + "txt_occ_grid_connected_to_1").arg( + mEngine->wlanQtUtils()->iapName(iapId)); + break; + + default: + // WLAN is disconnected + status = hbTrId("txt_occ_grid_not_connected"); + break; + } + } + mStatusLabel->setPlainText(status); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_UPDATEWLANSTATUSLABEL_EXIT); +} + +/*! + Handles a "Connect" action for the selected IAP or AP item. + + @param data IAP ID (int), or AP class (WlanQtUtilsAp) to connect. +*/ + +void WlanSnifferListView::handleConnect(QVariant data) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLECONNECT_ENTRY); + + // Check whether we need to disconnect a previous connection first + int activeWlanId = mEngine->wlanQtUtils()->activeIap(); + + // Get IAP ID if IAP is available + int iapId = WlanQtUtils::IapIdNone; + if (data.canConvert()) { + iapId = data.toInt(); + } + OstTraceExt2( + TRACE_NORMAL, + WLANSNIFFERLISTVIEW_HANDLECONNECT, + "WlanSnifferListView::handleConnect;activeWlanId=%d;iapId=%d", + activeWlanId, + iapId); + + // Skip connecting if the IAP is already connected + if (activeWlanId != WlanQtUtils::IapIdNone && iapId == activeWlanId) { + return; + } + + if (activeWlanId != WlanQtUtils::IapIdNone) { + mEngine->wlanQtUtils()->disconnectIap(activeWlanId); + + // Update list widget so that the IAP is no longer connected + updateListContent(); + } + + if (iapId != WlanQtUtils::IapIdNone) { + // Item was an IAP, connect it. + mConnectingIapId = iapId; + mStatusLabel->setPlainText( + HbParameterLengthLimiter( + "txt_occ_grid_connecting_to_1").arg( + mEngine->wlanQtUtils()->iapName(iapId))); + mEngine->wlanQtUtils()->connectIap(iapId); + } else { + // Item is a WLAN AP. Summon the Wlan Wizard to handle creation + // of the IAP and connecting it. + Q_ASSERT(data.canConvert()); + WlanQtUtilsAp ap = data.value(); + emit wizardTriggered(&ap); + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLECONNECT_EXIT); +} + +/*! + Updates WLAN list widget with new WLAN scan results. +*/ + +void WlanSnifferListView::updateListContent() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_UPDATELISTCONTENT_ENTRY); + + if (!mIgnoreWlanScanResults) { + // Get the latest scan results + QList< QSharedPointer > iaps; + QList< QSharedPointer > aps; + mEngine->wlanQtUtils()->availableWlans(iaps, aps); + + // Check for connected IAP + int iapId = WlanQtUtils::IapIdNone; + if (mEngine->wlanQtUtils()->connectionStatus() == + WlanQtUtils::ConnStatusConnected) { + iapId = mEngine->wlanQtUtils()->activeIap(); + } + + // Let the list widget class update the list content + mWlanListWidget->updateContent(iaps, aps, iapId); + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_UPDATELISTCONTENT_EXIT); +} + +/*! + WLAN state settings change handler. This slot handles both the + WLAN ON/OFF setting and WLAN forced OFF setting. + Updates all WLAN ON/OFF related (UI) elements. +*/ + +void WlanSnifferListView::updateWlanEnabled() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_UPDATEWLANENABLED_ENTRY); + + // Check the updated setting status + bool forcedOff = mEngine->forceDisableWlan(); + bool enabled = mEngine->masterWlan() && !forcedOff; + + // Update the WLAN status label + updateWlanStatusLabel(enabled); + + // Set the WLAN ON/OFF button state + mWlanButton->setChecked(enabled); + + // Select the right WLAN button icon and menu action text + if (enabled) { + mWlanButton->setIcon(HbIcon("qtg_mono_wlan")); + mSwitchWlanAction->setText(hbTrId("txt_occ_opt_switch_wlan_off")); + } else { + mWlanButton->setIcon(HbIcon("qtg_mono_wlan_offline")); + mSwitchWlanAction->setText(hbTrId("txt_occ_opt_switch_wlan_on")); + } + + // Set triggable WLAN UI elements disabled if WLAN is forced OFF + mWlanButton->setEnabled(!forcedOff); + mSwitchWlanAction->setEnabled(!forcedOff); + + // Disable manual WLAN IAP creation when WLAN is switched OFF + mAddWlanAction->setEnabled(enabled); + + // Switch WLAN scanning ON/OFF + if (enabled) { + mEngine->startWlanScanning(); + } else { + mEngine->stopWlanScanning(); + // Clear the network list when going to offline + mWlanList->clear(); + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_UPDATEWLANENABLED_EXIT); +} + +/*! + Connection opened slot. Updates connection status. + + @param [in] iapId IAP ID of the connected WLAN IAP. +*/ + +void WlanSnifferListView::updateConnectionOpened(int iapId) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_UPDATECONNECTIONOPENED_ENTRY); + + mConnectingIapId = WlanQtUtils::IapIdNone; + mStatusLabel->setPlainText( + HbParameterLengthLimiter( + "txt_occ_grid_connected_to_1").arg( + mEngine->wlanQtUtils()->iapName(iapId))); + + // Update the list widget content + updateListContent(); + + // Scroll to the top of the list + mWlanListWidget->scrollTo(0); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_UPDATECONNECTIONOPENED_EXIT); +} + +/*! + Connection closing handler. Updates connection status. + + @param [in] iapId Disconnected IAP ID. +*/ + +void WlanSnifferListView::updateConnectionClosed(int iapId) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_UPDATECONNECTIONCLOSED_ENTRY); + + if (mEngine->masterWlan() && !mEngine->forceDisableWlan()) { + // Check whether we can update the status text to "Not connected" + if (mConnectingIapId == WlanQtUtils::IapIdNone || + mConnectingIapId == iapId) { + mStatusLabel->setPlainText(hbTrId("txt_occ_grid_not_connected")); + } + // else: we are already connecting to another network so don't touch + // the status label + + // Update the list widget content + updateListContent(); + } + + if (mConnectingIapId == iapId) { + // Not connecting to this network anymore + mConnectingIapId = WlanQtUtils::IapIdNone; + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_UPDATECONNECTIONCLOSED_EXIT); +} + +/*! + Context menu closing handler. +*/ + +void WlanSnifferListView::handleContextMenuClosed() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLECONTEXTMENUCLOSED_ENTRY); + + // Let list updating start again + mIgnoreWlanScanResults = false; + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLECONTEXTMENUCLOSED_EXIT); +} + +/*! + List item activation handler. Connects the WLAN network, and if there + is no IAP yet for it, starts WLAN Wizard. + + @param [in] item Selected WLAN network list item. +*/ + +void WlanSnifferListView::handleListItemActivated(HbListWidgetItem *item) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLELISTITEMACTIVATED_ENTRY); + + handleConnect(item->data()); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLELISTITEMACTIVATED_EXIT); +} + +/*! + WLAN List item long press handler. + The long press of a list item (i.e. WLAN IAP) opens a context menu that + is populated depending on the state of the WLAN network in case. + + @param [in] item Selected list item. + @param [in] coords Coordinates of the long press. +*/ + +void WlanSnifferListView::handleListItemLongPressed( + HbListWidgetItem *item, + const QPointF &coords) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLELISTITEMLONGPRESSED_ENTRY); + + mContextMenu = QSharedPointer(new HbMenu()); + + int activeIap = mEngine->wlanQtUtils()->activeIap(); + + // Remember the item that was long pressed + mContextMenuData = item->data(); + if (mContextMenuData.canConvert() + && mContextMenuData.toInt() == activeIap) { + // Connected IAP, add "Disconnect" action + mContextMenu->addAction( + hbTrId("txt_common_menu_disconnect"), + this, + SLOT(handleListItemDisconnect())); + } else { + // Not connected IAP or AP, add "Connect" action + mContextMenu->addAction( + hbTrId("txt_common_menu_connect"), + this, + SLOT(handleListItemConnect())); + } + + // Show the menu and connect closure signal (to re-enable list refreshing) + bool connectStatus = connect( + mContextMenu.data(), + SIGNAL(aboutToClose()), + this, + SLOT(handleContextMenuClosed())); + Q_ASSERT(connectStatus); + mContextMenu->setTimeout(HbPopup::ContextMenuTimeout); + mContextMenu->setPreferredPos(coords); + mContextMenu->show(); + + // Skip WLAN scan result updates during context menu handling + mIgnoreWlanScanResults = true; + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLELISTITEMLONGPRESSED_EXIT); +} + +/*! + Handles the "Connect" action selected from the context menu for a list item. +*/ + +void WlanSnifferListView::handleListItemConnect() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLELISTITEMCONNECT_ENTRY); + + handleConnect(mContextMenuData); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLELISTITEMCONNECT_EXIT); +} + +/*! + Handles the "Disconnect" action selected from the context menu for a list item. +*/ + +void WlanSnifferListView::handleListItemDisconnect() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLELISTITEMDISCONNECT_ENTRY); + + // "Disconnect" was only added, if the item was an IAP and data was + // the IAP ID. + Q_ASSERT(mContextMenuData.canConvert()); + mEngine->wlanQtUtils()->disconnectIap(mContextMenuData.toInt()); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLELISTITEMDISCONNECT_EXIT); +} + +/*! + Function for handling WLAN ON/OFF switch initiation. +*/ + +void WlanSnifferListView::handleWlanToggled() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLEWLANTOGGLED_ENTRY); + + // Toggle the new WLAN ON/OFF value + bool wlanOn = mEngine->masterWlan(); + OstTraceExt1( + TRACE_NORMAL, + WLANSNIFFERLISTVIEW_HANDLEWLANTOGGLED, + "WlanSnifferListView::handleWlanToggled;wlan=%hhu", + wlanOn); + + // We have to check whether the offline mode is ON. If it is, then the + // user needs to be queried whether WLAN will be used in offline mode. + if (!wlanOn && mEngine->offlineMode()) { + // Show the dialog and wait for user input. + mWlanEnableDialog = QSharedPointer( + new HbMessageBox(HbMessageBox::MessageTypeQuestion)); + mWlanEnableDialog->setTimeout(HbPopup::StandardTimeout); + mWlanEnableDialog->setText(hbTrId("txt_occ_info_activate_wlan_in_airplane_mode")); + // Open the dialog and connect the result to the handleWlanEnableDialogClosed slot + mWlanEnableDialog->open(this, SLOT(handleWlanEnableDialogClosed(HbAction*))); + } else { + // Stop WLAN scanning immediately when switching WLAN OFF. + // WLAN might have sent scan results just before disabling WLAN. + if (wlanOn) { + mEngine->stopWlanScanning(); + } + mEngine->setMasterWlan(!wlanOn); + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLEWLANTOGGLED_EXIT); +} + +/*! + Function for handling WLAN Wizard starting when adding WLAN manually. +*/ + +void WlanSnifferListView::startWlanWizard() +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_STARTWLANWIZARD_ENTRY); + + // TODO: Stop connections & do other cleanup before wizard can start? + + emit wizardTriggered(NULL); + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_STARTWLANWIZARD_EXIT); +} + +/*! + Function to handle the input received when the wlan enabling + query is closed. + + @param [in] action The user action received from the dialog. +*/ + +void WlanSnifferListView::handleWlanEnableDialogClosed(HbAction *action) +{ + OstTraceFunctionEntry0(WLANSNIFFERLISTVIEW_HANDLEWLANENABLEDIALOGCLOSED_ENTRY); + + // The dialog must exist + Q_ASSERT(mWlanEnableDialog); + + // If the user selected yes, then the wlan value is toggled, + // otherwise nothing needs to be done. + // TODO: Update actions().at(0) when a better solution is provided by orbit + if (action == mWlanEnableDialog->actions().at(0)) { + mEngine->setMasterWlan(true); + } + + OstTraceFunctionExit0(WLANSNIFFERLISTVIEW_HANDLEWLANENABLEDIALOGCLOSED_EXIT); +}