bluetoothengine/btui/btcpplugin/btcpuimainview.cpp
changeset 19 43824b19ee35
child 31 a0ea99b6fa53
equal deleted inserted replaced
17:f05641c183ff 19:43824b19ee35
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  BtCpUiMainView implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include "btcpuimainview.h"
       
    19 #include <QtGlobal>
       
    20 #include <QGraphicsLinearLayout>
       
    21 #include <HbInstance>
       
    22 //#include "btuiviewutil.h"
       
    23 #include <hbdocumentloader.h>
       
    24 #include <hbnotificationdialog.h>
       
    25 #include <hbgridview.h>
       
    26 #include <hbpushbutton.h>
       
    27 #include <hblabel.h>
       
    28 #include <hbicon.h>
       
    29 #include <hblineedit.h>
       
    30 #include <hbtooltip.h>
       
    31 #include <btengconstants.h>
       
    32 #include <hbmenu.h>
       
    33 #include <hbaction.h>
       
    34 #include <hbcombobox.h>
       
    35 #include "btcpuisearchview.h"
       
    36 #include <bluetoothuitrace.h>
       
    37 #include <btdelegatefactory.h>
       
    38 #include <btabstractdelegate.h>
       
    39 #include "btqtconstants.h"
       
    40 
       
    41 
       
    42 // docml to load
       
    43 const char* BTUI_MAINVIEW_DOCML = ":/docml/bt-main-view.docml";
       
    44 
       
    45 /*!
       
    46     Constructs a new BtUiMainView using HBDocumentLoader.  Docml (basically xml) file
       
    47     has been generated using Application Designer.   
       
    48 
       
    49  */
       
    50 BtCpUiMainView::BtCpUiMainView( BtuiModel &model, QGraphicsItem *parent )
       
    51     : BtCpUiBaseView( model, parent ), mAbstractDelegate(0)
       
    52 {
       
    53     bool ret(false);
       
    54     
       
    55     mMainWindow = hbInstance->allMainWindows().first();
       
    56     mMainView = this;
       
    57     
       
    58     // Create view for the application.
       
    59     // Set the name for the view. The name should be same as the view's
       
    60     // name in docml.
       
    61     setObjectName("view");
       
    62 
       
    63     QObjectList objectList;
       
    64     objectList.append(this);
       
    65     // Pass the view to documentloader. Document loader uses this view
       
    66     // when docml is parsed, instead of creating new view.
       
    67     mLoader = new HbDocumentLoader();
       
    68     mLoader->setObjectTree(objectList);
       
    69 
       
    70     bool ok = false;
       
    71     mLoader->load( BTUI_MAINVIEW_DOCML, &ok );
       
    72     // Exit if the file format is invalid
       
    73     BTUI_ASSERT_X( ok, "bt-main-view", "Invalid docml file" );
       
    74     
       
    75     mOrientation = mMainWindow->orientation();
       
    76     
       
    77     if (mOrientation == Qt::Horizontal) {
       
    78         mLoader->load(BTUI_MAINVIEW_DOCML, "landscape", &ok);
       
    79         BTUI_ASSERT_X( ok, "bt-main-view", "Invalid docml file: landscape section problem" );
       
    80     }
       
    81     else {
       
    82         mLoader->load(BTUI_MAINVIEW_DOCML, "portrait", &ok);
       
    83         BTUI_ASSERT_X( ok, "bt-main-view", "Invalid docml file: landscape section problem" );        
       
    84     }
       
    85 
       
    86     mDeviceNameEdit=0;
       
    87     mDeviceNameEdit = qobject_cast<HbLineEdit *>( mLoader->findWidget( "lineEdit" ) );
       
    88     BTUI_ASSERT_X( mDeviceNameEdit != 0, "bt-main-view", "Device Name not found" );
       
    89     ret =  connect(mDeviceNameEdit, SIGNAL(editingFinished ()), this, SLOT(changeBtLocalName()));
       
    90     
       
    91     mPowerButton=0;
       
    92     mPowerButton = qobject_cast<HbPushButton *>( mLoader->findWidget( "pushButton" ) );
       
    93     BTUI_ASSERT_X( mPowerButton != 0, "bt-main-view", "power button not found" );
       
    94     ret =  connect(mPowerButton, SIGNAL(clicked()), this, SLOT(changePowerState()));
       
    95     BTUI_ASSERT_X( ret, "BtCpUiMainView::BtCpUiMainView", "can't connect power button" );
       
    96     
       
    97     mVisibilityMode=0;
       
    98     mVisibilityMode = qobject_cast<HbComboBox *>( mLoader->findWidget( "combobox" ) );
       
    99     BTUI_ASSERT_X( mVisibilityMode != 0, "bt-main-view", "visibility combobox not found" );
       
   100         
       
   101     mDeviceList=0;
       
   102     mDeviceList = qobject_cast<HbGridView *>( mLoader->findWidget( "gridView" ) );
       
   103     BTUI_ASSERT_X( mDeviceList != 0, "bt-main-view", "Device List (grid view) not found" );   
       
   104     
       
   105     // listen for orientation changes
       
   106     ret = connect(mMainWindow, SIGNAL(orientationChanged(Qt::Orientation)),
       
   107             this, SLOT(changeOrientation(Qt::Orientation)));
       
   108     BTUI_ASSERT_X( ret, "BtCpUiMainView::BtCpUiMainView()", "connect orientationChanged() failed");
       
   109 
       
   110     // load tool bar actions
       
   111     HbAction *discoverAction = static_cast<HbAction*>( mLoader->findObject( "discoverAction" ) );
       
   112     BTUI_ASSERT_X( discoverAction, "bt-main-view", "discover action missing" ); 
       
   113     ret = connect(discoverAction, SIGNAL(triggered()), this, SLOT(goToDiscoveryView()));
       
   114     BTUI_ASSERT_X( ret, "bt-main-view", "orientation toggle can't connect" ); 
       
   115     
       
   116     // load menu
       
   117     HbMenu *optionsMenu = qobject_cast<HbMenu *>(mLoader->findWidget("viewMenu"));
       
   118     BTUI_ASSERT_X( optionsMenu != 0, "bt-main-view", "Options menu not found" );   
       
   119     this->setMenu(optionsMenu);
       
   120     
       
   121     // update display when setting data changed
       
   122     ret = connect(&mModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 
       
   123             this, SLOT(updateSettingItems(QModelIndex,QModelIndex)));
       
   124     BTUI_ASSERT_X( ret, "BtCpUiMainView::BtCpUiMainView", "can't connect dataChanged" );
       
   125     
       
   126     QModelIndex top = mModel.index( BtuiModel::LocalSettingRow, BtuiModel::BluetoothNameCol );
       
   127     QModelIndex bottom = mModel.index( BtuiModel::LocalSettingRow, BtuiModel::VisibilityCol );
       
   128     // update name, power and visibility rows
       
   129     updateSettingItems( top, bottom );
       
   130 
       
   131     //Handle Visibility Change User Interaction
       
   132     ret = connect(mVisibilityMode, SIGNAL(currentIndexChanged (int)), 
       
   133             this, SLOT(visibilityChanged (int)));
       
   134     // create other views
       
   135     createViews();
       
   136     mCurrentView = this;
       
   137     mCurrentViewId = MainView;
       
   138 
       
   139 }
       
   140 
       
   141 /*!
       
   142     Destructs the BtCpUiMainView.
       
   143  */
       
   144 BtCpUiMainView::~BtCpUiMainView()
       
   145 {
       
   146     delete mLoader; // Also deletes all widgets that it constructed.
       
   147     mMainWindow->removeView(mSearchView);
       
   148     delete mSearchView;
       
   149 	 if (mAbstractDelegate)
       
   150     {
       
   151         delete mAbstractDelegate;
       
   152     }
       
   153 }
       
   154 
       
   155 /*! 
       
   156     from base class, initialize the view
       
   157  */
       
   158 void BtCpUiMainView::activateView(const QVariant& value, int cmdId )
       
   159 {
       
   160     Q_UNUSED(value);
       
   161     Q_UNUSED(cmdId);
       
   162 
       
   163 }
       
   164 
       
   165 /*! 
       
   166     From base class. Handle resource before the current view is deactivated.
       
   167  */
       
   168 void BtCpUiMainView::deactivateView()
       
   169 {
       
   170 
       
   171 }
       
   172 
       
   173 void BtCpUiMainView::itemActivated(QModelIndex index)
       
   174 {
       
   175     Q_UNUSED(index);
       
   176 }
       
   177 
       
   178 void BtCpUiMainView::goToDiscoveryView()
       
   179 {
       
   180     changeView( SearchView, false, 0 );
       
   181 }
       
   182 
       
   183 Qt::Orientation BtCpUiMainView::orientation()
       
   184 {
       
   185     return mOrientation;
       
   186 }
       
   187 
       
   188 void BtCpUiMainView::changeBtLocalName()
       
   189 {
       
   190     //Error handling has to be done.  
       
   191     if (!mAbstractDelegate) {
       
   192         mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::DeviceName, mModel); 
       
   193         connect( mAbstractDelegate, SIGNAL(commandCompleted(int,QVariant)), this, SLOT(btNameDelegateCompleted(int,QVariant)) );
       
   194         mAbstractDelegate->exec(mDeviceNameEdit->text ());
       
   195     }
       
   196     else {
       
   197         setPrevBtLocalName();
       
   198     }
       
   199 }
       
   200 
       
   201 void BtCpUiMainView::setPrevBtLocalName()
       
   202 {
       
   203     //Should we notify user this as Error...?
       
   204     HbNotificationDialog::launchDialog(hbTrId("Error"));
       
   205     QModelIndex index = mModel.index( BtuiModel::LocalSettingRow, BtuiModel::BluetoothNameCol );
       
   206     
       
   207     mDeviceNameEdit->setText( mModel.data(index,BtuiModel::settingDisplay).toString() );
       
   208 }
       
   209 
       
   210 
       
   211 void BtCpUiMainView::btNameDelegateCompleted(int status, QVariant param)
       
   212 {
       
   213     if(KErrNone == status) {
       
   214         mDeviceNameEdit->setText(param.toString());
       
   215     }
       
   216     else {
       
   217         setPrevBtLocalName();
       
   218     }
       
   219     //Error handling has to be done.    
       
   220     if (mAbstractDelegate)
       
   221     {
       
   222         disconnect(mAbstractDelegate);
       
   223         delete mAbstractDelegate;
       
   224         mAbstractDelegate = 0;
       
   225     }
       
   226 
       
   227 }
       
   228 
       
   229 void BtCpUiMainView::visibilityChanged (int index)
       
   230 {
       
   231     QList<QVariant> list;
       
   232     
       
   233     VisibilityMode mode = indexToVisibilityMode(index);
       
   234     list.append(QVariant((int)mode));
       
   235     if(BtTemporary == VisibilityMode(mode)) {
       
   236         //Right now hardcoded to 5 Mins.
       
   237         list.append(QVariant(5));
       
   238     }
       
   239     //Error handling has to be done.    
       
   240     if (!mAbstractDelegate) {
       
   241         mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::Visibility, mModel); 
       
   242         connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(visibilityDelegateCompleted(int)) );
       
   243         mAbstractDelegate->exec(list);
       
   244     }
       
   245     else {
       
   246         setPrevVisibilityMode();
       
   247     }
       
   248 
       
   249 }
       
   250 
       
   251 void BtCpUiMainView::setPrevVisibilityMode()
       
   252 {
       
   253     bool ret(false);
       
   254     
       
   255     //Should we notify this error to user..?
       
   256     HbNotificationDialog::launchDialog(hbTrId("Error"));
       
   257     QModelIndex index = mModel.index( BtuiModel::LocalSettingRow, BtuiModel::VisibilityCol );
       
   258     
       
   259     ret = disconnect(mVisibilityMode, SIGNAL(currentIndexChanged (int)), 
       
   260                     this, SLOT(visibilityChanged (int)));
       
   261     BTUI_ASSERT_X( ret, "BtCpUiMainView::setPrevVisibilityMode", "can't disconnect signal" );
       
   262     
       
   263         mVisibilityMode->setCurrentIndex ( visibilityModeToIndex((VisibilityMode)
       
   264                 mModel.data(index,BtuiModel::SettingValue).toInt()) );
       
   265     
       
   266     //Handle Visibility Change User Interaction
       
   267     ret = connect(mVisibilityMode, SIGNAL(currentIndexChanged (int)), 
       
   268             this, SLOT(visibilityChanged (int)));
       
   269     BTUI_ASSERT_X( ret, "BtCpUiMainView::setPrevVisibilityMode", "can't connect signal" );
       
   270 
       
   271 }
       
   272 
       
   273 
       
   274 void BtCpUiMainView::visibilityDelegateCompleted(int status)
       
   275 {
       
   276     
       
   277     //This should be mapped to Qt error
       
   278     if(KErrNone != status) {
       
   279         setPrevVisibilityMode();
       
   280     }
       
   281     
       
   282     //Error handling has to be done.    
       
   283     if (mAbstractDelegate)
       
   284     {
       
   285         disconnect(mAbstractDelegate);
       
   286         delete mAbstractDelegate;
       
   287         mAbstractDelegate = 0;
       
   288     }
       
   289 
       
   290 }
       
   291 
       
   292 
       
   293 // called due to real orientation change event coming from main window
       
   294 void BtCpUiMainView::changeOrientation( Qt::Orientation orientation )
       
   295 {
       
   296     bool ok = false;
       
   297     mOrientation = orientation;
       
   298     if( orientation == Qt::Vertical ) {
       
   299         // load "portrait" section
       
   300         mLoader->load( BTUI_MAINVIEW_DOCML, "portrait", &ok );
       
   301         BTUI_ASSERT_X( ok, "bt-main-view", "Invalid docml file: portrait section problem" );
       
   302     } else {
       
   303         // load "landscape" section
       
   304         mLoader->load( BTUI_MAINVIEW_DOCML, "landscape", &ok );
       
   305         BTUI_ASSERT_X( ok, "bt-main-view", "Invalid docml file: landscape section problem" );
       
   306     }
       
   307 }
       
   308 
       
   309 void BtCpUiMainView::commandCompleted( int cmdId, int err, const QString &diagnostic )
       
   310 {
       
   311     Q_UNUSED(cmdId);
       
   312     Q_UNUSED(err);
       
   313     Q_UNUSED(diagnostic);
       
   314 
       
   315 }
       
   316 
       
   317 /*!
       
   318     Slot for receiving notification of data changes from the model.
       
   319     Identify the setting changed and update the corresponding UI item.
       
   320  */
       
   321 void BtCpUiMainView::updateSettingItems(const QModelIndex &topLeft, const QModelIndex &bottomRight)
       
   322 {   
       
   323 
       
   324     // update only the part of the view specified by the model's row(s)
       
   325 
       
   326     for (int i=topLeft.column(); i <= bottomRight.column(); i++) {
       
   327         QModelIndex index = mModel.index( BtuiModel::LocalSettingRow, i);
       
   328         // Distinguish which setting value is changed.
       
   329         switch ( i ) {
       
   330         case BtuiModel::BluetoothNameCol :
       
   331             mDeviceNameEdit->setText( mModel.data(index,BtuiModel::settingDisplay).toString() );
       
   332             break;
       
   333         case BtuiModel::PowerStateCol:
       
   334             mPowerButton->setText( mModel.data(index,BtuiModel::settingDisplay).toString() );
       
   335             break;
       
   336         case BtuiModel::VisibilityCol:
       
   337             mVisibilityMode->setCurrentIndex ( visibilityModeToIndex((VisibilityMode)
       
   338                     mModel.data(index,BtuiModel::SettingValue).toInt()) );
       
   339             break;
       
   340         }
       
   341     }
       
   342 
       
   343     
       
   344 }
       
   345 
       
   346 /*!
       
   347     Slot for receiving notification for user interaction on power state.
       
   348     Manually update model data since HbPushButton is not linked to model directly.
       
   349  */
       
   350 void BtCpUiMainView::changePowerState()
       
   351 {
       
   352     
       
   353     QModelIndex index = mModel.index(BtuiModel::LocalSettingRow, BtuiModel::PowerStateCol);
       
   354     QVariant powerState = mModel.data(index, Qt::EditRole);
       
   355     if (!mAbstractDelegate)//if there is no other delegate running
       
   356     { 
       
   357         mAbstractDelegate = BtDelegateFactory::newDelegate(BtDelegate::ManagePower, mModel); 
       
   358         connect( mAbstractDelegate, SIGNAL(commandCompleted(int)), this, SLOT(powerDelegateCompleted(int)) );
       
   359         mAbstractDelegate->exec(powerState);
       
   360     }
       
   361    
       
   362 }
       
   363 
       
   364 void BtCpUiMainView::powerDelegateCompleted(int status)
       
   365 {
       
   366     Q_UNUSED(status);
       
   367     //ToDo: Error handling here 
       
   368     if (mAbstractDelegate)
       
   369     {
       
   370         disconnect(mAbstractDelegate);
       
   371         delete mAbstractDelegate;
       
   372         mAbstractDelegate = 0;
       
   373     }
       
   374     //BTUI_ASSERT_X( status, "bt-main-view", "error in delegate complete" );  
       
   375 }
       
   376 
       
   377 /*!
       
   378  * Mapping from visibility mode UI row to VisibilityMode
       
   379  */
       
   380 VisibilityMode BtCpUiMainView::indexToVisibilityMode(int index)
       
   381 {
       
   382     VisibilityMode mode; 
       
   383     switch(index) {
       
   384     case UiRowBtHidden:  
       
   385         mode = BtHidden;
       
   386         break;
       
   387     case UiRowBtVisible:  
       
   388         mode = BtVisible;
       
   389         break;
       
   390     case UiRowBtTemporary:  
       
   391         mode = BtTemporary;
       
   392         break;
       
   393     default:
       
   394         mode = BtUnknown;
       
   395     }
       
   396     return mode;
       
   397 }
       
   398 
       
   399 /*!
       
   400  * Mapping from VisibilityMode to visibility mode UI row  
       
   401  */
       
   402 int BtCpUiMainView::visibilityModeToIndex(VisibilityMode mode)
       
   403 {
       
   404     int uiRow;
       
   405     switch(mode) {
       
   406     case BtHidden:  
       
   407         uiRow = UiRowBtHidden;
       
   408         break;
       
   409     case BtVisible:  
       
   410         uiRow = UiRowBtVisible;
       
   411         break;
       
   412     case BtTemporary:  
       
   413         uiRow = UiRowBtTemporary;
       
   414         break;
       
   415     default:
       
   416         uiRow = -1;  // error
       
   417     }
       
   418     return uiRow;
       
   419 }
       
   420 //////////////////////
       
   421 //
       
   422 // from view manager
       
   423 // 
       
   424 //////////////////////
       
   425 
       
   426 /*!
       
   427     Create views(main view, device view and search view).
       
   428     Add them to MainWindow.  All views are long-lived and are deleted only when exiting the application 
       
   429     (or when main view is deleted).
       
   430  */
       
   431 void BtCpUiMainView::createViews()
       
   432 {
       
   433     Qt::Orientation orientation = mMainWindow->orientation();
       
   434     // Create other views
       
   435     mSearchView = new BtCpUiSearchView( mModel, this );
       
   436     mMainWindow->addView(mSearchView);
       
   437     mDeviceView = 0;  // ToDo: add this later
       
   438     
       
   439     mCurrentView = this;
       
   440     mCurrentViewId = MainView;
       
   441 
       
   442     
       
   443     // QList<int> stores the previous view ids for each view.
       
   444     for( int i=0; i < LastView; i++ ) {
       
   445         mPreviousViewIds.append( 0 );
       
   446     }
       
   447 }
       
   448 
       
   449 /*!
       
   450     Switch between the views.  
       
   451     Parameter cmdId is used for automatically executing command.
       
   452     Parameter "value" is optional except for GadgetView, 
       
   453     which needs the BT address (QString)
       
   454  */
       
   455 void BtCpUiMainView::changeView(int targetViewId, bool fromBackButton, 
       
   456         int cmdId, const QVariant& value )
       
   457 {
       
   458     mCurrentView->deactivateView();
       
   459 
       
   460     // update the previous view Id in QList<int> 
       
   461     // If launching the target view from back softkey, 
       
   462     // the previous viewId of target view should not be changed. 
       
   463     // Otherwise, loop happens between two views.
       
   464     if(!fromBackButton) {
       
   465         if ((targetViewId == DeviceView) && (mCurrentViewId == SearchView)) {
       
   466             // we don't want to return to search view after e.g. pairing a new device
       
   467             mPreviousViewIds[ targetViewId ] = MainView;  
       
   468         } 
       
   469         else {
       
   470             // normal case:  return to previous view
       
   471             mPreviousViewIds[ targetViewId ] = mCurrentViewId;
       
   472         }
       
   473     }
       
   474 
       
   475     // set the new current view 
       
   476     mCurrentView = idToView(targetViewId);
       
   477     mCurrentViewId = targetViewId;
       
   478     mMainWindow->setCurrentView( mCurrentView );
       
   479 
       
   480     // do preparation or some actions when new view is activated 
       
   481     mCurrentView->activateView( value, cmdId );
       
   482 }
       
   483  
       
   484 
       
   485 BtCpUiBaseView * BtCpUiMainView::idToView(int targetViewId)
       
   486 {
       
   487     switch (targetViewId) {
       
   488     case MainView:
       
   489         return mMainView;
       
   490     case SearchView:
       
   491         return mSearchView;
       
   492     case DeviceView:
       
   493         return mDeviceView;
       
   494     default :
       
   495         BTUI_ASSERT_X(false, "BtCpUiMainView::idToView", "invalid view id");
       
   496     }
       
   497     return 0;
       
   498 }
       
   499 
       
   500 /*
       
   501    Jump to previous view.  This function is used when back button is pressed.
       
   502  */
       
   503 void BtCpUiMainView::switchToPreviousViewReally()
       
   504 {  
       
   505     // jump to previous view of current view.
       
   506     if( (mCurrentViewId >= 0) && (mCurrentViewId < LastView)) {
       
   507         changeView( mPreviousViewIds[mCurrentViewId], true, 0 );
       
   508     } 
       
   509     else {
       
   510         BTUI_ASSERT_X(false, "BtCpUiMainView::switchToPreviousViewReally", "invalid view id");
       
   511     }
       
   512 }
       
   513 
       
   514 
       
   515 void BtCpUiMainView::setSoftkeyBack()
       
   516 {
       
   517 
       
   518 }
       
   519 
       
   520 void BtCpUiMainView::switchToPreviousView()
       
   521 {
       
   522         
       
   523 }
       
   524