phonebookui/pbkcommonui/src/cntfetchcontactsview.cpp
changeset 59 a642906a277a
parent 47 7cbcb2896f0e
child 65 ae724a111993
equal deleted inserted replaced
47:7cbcb2896f0e 59:a642906a277a
     1 /*
       
     2 * Copyright (c) 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:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <hbdialog.h>
       
    19 #include <hbscrollbar.h>
       
    20 #include <hbindexfeedback.h>
       
    21 #include <hbaction.h>
       
    22 #include <hblabel.h>
       
    23 #include <hbaction.h>
       
    24 #include <hblineedit.h>
       
    25 #include <hbmainwindow.h>
       
    26 #include <hblistviewitem.h>
       
    27 #include <hblistview.h>
       
    28 #include <hbsearchpanel.h>
       
    29 #include <hbstaticvkbhost.h>
       
    30 #include <QGraphicsLinearLayout>
       
    31 #include <qcontactid.h>
       
    32 #include <cntlistmodel.h>
       
    33 #include "cntfetchcontactsview.h"
       
    34 
       
    35 /*!
       
    36 Given a contact manager, CntFetchContacts is responsible for 
       
    37 retrieving a set of contacts, if any were chosen by the user. 
       
    38 */
       
    39 CntFetchContacts::CntFetchContacts(QContactManager &aManager) :
       
    40 QObject(),
       
    41 mPopup(NULL),
       
    42 mCntModel(NULL),
       
    43 mListView(NULL),
       
    44 mEmptyListLabel(NULL),
       
    45 mSelectionMode(HbAbstractItemView::MultiSelection),
       
    46 mManager(&aManager),
       
    47 mWasCanceled(false),
       
    48 mLabel(NULL),
       
    49 mVirtualKeyboard(NULL),
       
    50 mPrimaryAction(NULL),
       
    51 mSecondaryAction(NULL),
       
    52 mIndexFeedback(NULL)
       
    53 {
       
    54     mSearchPanel = new HbSearchPanel();
       
    55     mSearchPanel->setVisible(false);
       
    56     mSearchPanel->setCancelEnabled(false);
       
    57     connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString)));
       
    58     
       
    59     HbLineEdit *editor = static_cast<HbLineEdit*>(mSearchPanel->primitive("lineedit"));
       
    60     editor->setInputMethodHints(Qt::ImhNoPredictiveText);
       
    61     
       
    62     mLayout = new QGraphicsLinearLayout(Qt::Vertical);
       
    63     
       
    64     mContainerWidget = new HbWidget();
       
    65 }
       
    66 
       
    67 CntFetchContacts::~CntFetchContacts()
       
    68 {
       
    69     delete mCntModel;
       
    70     mCntModel = NULL;
       
    71     
       
    72     delete mVirtualKeyboard;
       
    73     mVirtualKeyboard = NULL;
       
    74     
       
    75     delete mIndexFeedback;
       
    76     mIndexFeedback = NULL;
       
    77 }
       
    78 
       
    79 /*!
       
    80 Query to see if the user decided to press Cancel after selecting 
       
    81 group members. Must be called to see if results are valid.
       
    82 */
       
    83 bool CntFetchContacts::wasCanceled() const
       
    84 {
       
    85     return mWasCanceled;
       
    86 }
       
    87 
       
    88 void CntFetchContacts::setDetails(QString aTitle, QString aButtonText)
       
    89 {
       
    90     mButtonText = aButtonText;
       
    91     
       
    92     if (!mLabel) {
       
    93         mLabel = new HbLabel(aTitle);
       
    94     }
       
    95 }
       
    96 
       
    97 /*!
       
    98 Brings up a list of contacts, awaiting user response. This function is asynchronous.
       
    99 When a response is given, a clicked signal will be sent.
       
   100 */
       
   101 void CntFetchContacts::displayContacts(HbAbstractItemView::SelectionMode aMode,
       
   102                                                    QSet<QContactLocalId> aContacts)
       
   103 {
       
   104     doInitialize(aMode,aContacts);
       
   105     markMembersInView();
       
   106     showPopup();
       
   107 }
       
   108 
       
   109 QSet<QContactLocalId> CntFetchContacts::getSelectedContacts() const
       
   110 {
       
   111    return mCurrentlySelected;
       
   112 }
       
   113 
       
   114 void CntFetchContacts::setFilter(const QString &filterString)
       
   115 {
       
   116     QStringList searchList = filterString.split(QRegExp("\\s+"), QString::SkipEmptyParts);
       
   117 
       
   118     QContactDetailFilter detailfilter;
       
   119     detailfilter.setDetailDefinitionName(QContactDisplayLabel::DefinitionName, QContactDisplayLabel::FieldLabel);
       
   120     detailfilter.setMatchFlags(QContactFilter::MatchStartsWith);
       
   121     detailfilter.setValue(searchList);
       
   122     
       
   123     mCntModel->setFilter(detailfilter);
       
   124 
       
   125     markMembersInView();
       
   126 
       
   127     if (mCntModel->rowCount() == 0) {
       
   128         mLayout->removeItem(mListView);
       
   129         
       
   130         if (mEmptyListLabel) {
       
   131             qreal searchHeight = mSearchPanel->size().height();
       
   132             HbLabel* heading = static_cast<HbLabel*>(mPopup->headingWidget());
       
   133             qreal heightToSet =  mPopup->size().height() - mVirtualKeyboard->keyboardArea().height() - searchHeight - heading->size().height();
       
   134             mEmptyListLabel->setMaximumHeight(heightToSet);
       
   135             mEmptyListLabel->setVisible(true);
       
   136             mLayout->insertItem(0, mEmptyListLabel);
       
   137         }
       
   138 
       
   139         mListView->setVisible(false);
       
   140         mSearchPanel->setVisible(true);
       
   141     }
       
   142     else {
       
   143         if (mEmptyListLabel) {
       
   144             mEmptyListLabel->setVisible(false);
       
   145         }
       
   146         mLayout->removeItem(mEmptyListLabel);
       
   147         mLayout->insertItem(0, mListView);
       
   148         mListView->setVisible(true);
       
   149     }
       
   150 }
       
   151 
       
   152 void CntFetchContacts::handleKeypadOpen()
       
   153 {
       
   154     qreal searchHeight = mSearchPanel->size().height();
       
   155     HbLabel* heading = static_cast<HbLabel*>(mPopup->headingWidget());
       
   156     qreal heightToSet =  mPopup->size().height() - mVirtualKeyboard->keyboardArea().height() - searchHeight - heading->size().height();
       
   157 
       
   158     if (mEmptyListLabel) {
       
   159         mEmptyListLabel->setMaximumHeight( heightToSet - mEmptyListLabel->size().height() );
       
   160     }
       
   161     
       
   162     mListView->setMaximumHeight(heightToSet);
       
   163 }
       
   164 
       
   165 void CntFetchContacts::handleKeypadClose()
       
   166 {
       
   167     mListView->setMaximumHeight(mPopup->size().height());
       
   168 
       
   169     if (mEmptyListLabel) {
       
   170         mEmptyListLabel->setMaximumHeight(mPopup->size().height());
       
   171     }
       
   172 }
       
   173 
       
   174 /*!
       
   175 Notify client that we're done.
       
   176 */
       
   177 void CntFetchContacts::handleUserResponse(HbAction* action)
       
   178 {
       
   179     bool userCanceled = (action == mSecondaryAction); 
       
   180     if (userCanceled) {
       
   181         mCurrentlySelected.clear();
       
   182         
       
   183         mWasCanceled = true;
       
   184     }
       
   185     else {
       
   186         mWasCanceled = false;
       
   187     }
       
   188     
       
   189     mPopup->setVisible(false);
       
   190     mListView->setModel(NULL);
       
   191     delete mCntModel;
       
   192     mCntModel = NULL;
       
   193     
       
   194     emit clicked();
       
   195 }
       
   196 
       
   197 void CntFetchContacts::memberSelectionChanged(const QModelIndex &index)
       
   198 {
       
   199     if (!index.isValid()) return;
       
   200 
       
   201     if (mSelectionMode == HbAbstractItemView::SingleSelection) {
       
   202         mCurrentlySelected.clear();
       
   203     }
       
   204 
       
   205     QContactLocalId contactId = mCntModel->contact(index).localId();
       
   206 
       
   207     bool isSelected = mListView->selectionModel()->isSelected(index);
       
   208     if (isSelected != mCurrentlySelected.contains(contactId)) {
       
   209         if (isSelected) {
       
   210             mCurrentlySelected.insert(contactId);
       
   211         }
       
   212         else {
       
   213             mCurrentlySelected.remove(contactId);
       
   214         }
       
   215     }
       
   216     
       
   217     // Check for the case where there is a cancel button only. If so, 
       
   218     // after selecting any contact, should dismiss the dialog immediately.
       
   219     if (mButtonText.isEmpty() && mSelectionMode == HbAbstractItemView::SingleSelection) {
       
   220         mPopup->close();
       
   221     }
       
   222 }
       
   223 
       
   224 void CntFetchContacts::doInitialize(HbAbstractItemView::SelectionMode aMode,
       
   225                                                 QSet<QContactLocalId> aContacts)
       
   226 {
       
   227     mSelectionMode = aMode;
       
   228     mCurrentlySelected = aContacts;
       
   229 
       
   230     if (!mPopup) {
       
   231         mPopup = new HbDialog;
       
   232     }
       
   233 
       
   234     QContactDetailFilter contactsFilter;
       
   235     contactsFilter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType);
       
   236     contactsFilter.setValue(QString(QLatin1String(QContactType::TypeContact)));
       
   237     if (!mCntModel) {
       
   238         mCntModel = new CntListModel(mManager, contactsFilter, false);
       
   239     }
       
   240     
       
   241     if (!mListView) {
       
   242         mListView = new HbListView(mPopup);
       
   243         mListView->setModel(mCntModel);
       
   244         mListView->setSelectionMode(mSelectionMode);
       
   245         mListView->setFrictionEnabled(true);
       
   246         mListView->setScrollingStyle(HbScrollArea::PanWithFollowOn);
       
   247         mListView->verticalScrollBar()->setInteractive(true);
       
   248 
       
   249         HbListViewItem *prototype = mListView->listItemPrototype();
       
   250         prototype->setGraphicsSize(HbListViewItem::Thumbnail);
       
   251         prototype->setStretchingStyle(HbListViewItem::StretchLandscape);
       
   252 
       
   253         mIndexFeedback = new HbIndexFeedback(mPopup);
       
   254         mIndexFeedback->setIndexFeedbackPolicy(HbIndexFeedback::IndexFeedbackSingleCharacter);
       
   255         mIndexFeedback->setItemView(mListView);
       
   256 
       
   257         // Note that the layout takes ownership of the item(s) it contains.
       
   258         if (mCntModel->rowCount()== 0) {
       
   259             mListView->setVisible(false);
       
   260             if (!mEmptyListLabel) {
       
   261                 mEmptyListLabel = new HbTextItem(hbTrId("txt_phob_info_no_matching_contacts"));
       
   262                 mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
       
   263                 mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary));
       
   264                 mEmptyListLabel->setAlignment(Qt::AlignCenter);
       
   265                 mLayout->insertItem(0, mEmptyListLabel);
       
   266             }
       
   267         }
       
   268         else {
       
   269             mLayout->addItem(mListView);
       
   270         }
       
   271 
       
   272         mCntModel->showMyCard(false);
       
   273     }
       
   274     
       
   275     // Handle the case where the model was removed for the list view
       
   276     if (!mListView->model()) {
       
   277         mListView->setModel(mCntModel);
       
   278     }
       
   279     
       
   280     // Main window is NULL in unit tests
       
   281     HbMainWindow* window = mListView->mainWindow();
       
   282     if (window) {
       
   283         mContainerWidget->setPreferredHeight(mListView->mainWindow()->size().height());
       
   284     }
       
   285     mContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
       
   286     
       
   287     mSearchPanel->setVisible(true);
       
   288     mLayout->addItem(mSearchPanel);
       
   289     mContainerWidget->setLayout(mLayout);
       
   290     
       
   291     connect(mListView, SIGNAL(activated(const QModelIndex&)),
       
   292             this, SLOT(memberSelectionChanged(const QModelIndex&)), Qt::UniqueConnection);
       
   293 }
       
   294 
       
   295 void CntFetchContacts::showPopup()
       
   296 {
       
   297     mPopup->setTimeout(HbPopup::NoTimeout);
       
   298     mPopup->setDismissPolicy(HbPopup::NoDismiss);
       
   299     mPopup->setModal(true);
       
   300     mPopup->setContentWidget(mContainerWidget);
       
   301 
       
   302     if (!mVirtualKeyboard) {
       
   303         mVirtualKeyboard = new HbStaticVkbHost(mPopup);
       
   304         connect(mVirtualKeyboard, SIGNAL(keypadOpened()), this, SLOT(handleKeypadOpen()));
       
   305         connect(mVirtualKeyboard, SIGNAL(keypadClosed()), this, SLOT(handleKeypadClose()));
       
   306     }
       
   307     
       
   308     if (!mLabel) {
       
   309         mLabel = new HbLabel(hbTrId("txt_phob_title_contacts"));
       
   310     }
       
   311     mPopup->setHeadingWidget(mLabel);
       
   312 
       
   313     if (!mButtonText.isEmpty() && !mPrimaryAction) {
       
   314         mPrimaryAction = new HbAction(hbTrId(mButtonText.toAscii()));
       
   315         mPopup->addAction(mPrimaryAction);
       
   316     }
       
   317     
       
   318     if (!mSecondaryAction) {
       
   319         mSecondaryAction = new HbAction(hbTrId("txt_common_button_cancel"));
       
   320         mPopup->addAction(mSecondaryAction);
       
   321     }
       
   322 
       
   323     mPopup->open(this, SLOT(handleUserResponse(HbAction*)));
       
   324 }
       
   325 
       
   326 void CntFetchContacts::markMembersInView()
       
   327 {
       
   328     // If there are no contacts matching the current filter,
       
   329     // show "no matching contacts" label
       
   330     if (mCntModel->rowCount() == 0) {
       
   331         if (!mEmptyListLabel) {
       
   332             mEmptyListLabel = new HbTextItem(hbTrId("txt_phob_info_no_matching_contacts"));
       
   333             mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
       
   334             mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary));
       
   335             mEmptyListLabel->setAlignment(Qt::AlignCenter);
       
   336             mLayout->insertItem(1, mEmptyListLabel);
       
   337         }
       
   338     }
       
   339     else {
       
   340         mLayout->removeItem(mEmptyListLabel);
       
   341         delete mEmptyListLabel;
       
   342         mEmptyListLabel = 0;
       
   343     }
       
   344 
       
   345     // Mark group members in the listview
       
   346     foreach (QContactLocalId id, mCurrentlySelected) {
       
   347         QContact contact = mManager->contact(id);
       
   348         QModelIndex contactIndex = mCntModel->indexOfContact(contact);
       
   349         mListView->selectionModel()->select(contactIndex, QItemSelectionModel::Select);
       
   350     }
       
   351 }
       
   352 
       
   353 // End of file