|
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 <hbmainwindow.h> |
|
25 #include <hblistviewitem.h> |
|
26 #include <hblistview.h> |
|
27 #include <hbsearchpanel.h> |
|
28 #include <hbstaticvkbhost.h> |
|
29 #include <QGraphicsLinearLayout> |
|
30 #include <QContactId.h> |
|
31 #include <QDebug> |
|
32 #include <mobcntmodel.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 connect(mSearchPanel, SIGNAL(exitClicked()), this, SLOT(closeFind())); |
|
57 connect(mSearchPanel, SIGNAL(criteriaChanged(QString)), this, SLOT(setFilter(QString))); |
|
58 |
|
59 mLayout = new QGraphicsLinearLayout(Qt::Vertical); |
|
60 |
|
61 mContainerWidget = new HbWidget(); |
|
62 |
|
63 // set up the list with all contacts |
|
64 QList<QContactSortOrder> sortOrders; |
|
65 QContactSortOrder sortOrderFirstName; |
|
66 sortOrderFirstName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldFirst); |
|
67 sortOrderFirstName.setCaseSensitivity(Qt::CaseInsensitive); |
|
68 sortOrders.append(sortOrderFirstName); |
|
69 |
|
70 QContactSortOrder sortOrderLastName; |
|
71 sortOrderLastName.setDetailDefinitionName(QContactName::DefinitionName, QContactName::FieldLast); |
|
72 sortOrderLastName.setCaseSensitivity(Qt::CaseInsensitive); |
|
73 sortOrders.append(sortOrderLastName); |
|
74 |
|
75 QContactDetailFilter contactsFilter; |
|
76 contactsFilter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType); |
|
77 contactsFilter.setValue(QString(QLatin1String(QContactType::TypeContact))); |
|
78 mCntModel = new MobCntModel(mManager, contactsFilter, sortOrders, false); |
|
79 } |
|
80 |
|
81 CntFetchContacts::~CntFetchContacts() |
|
82 { |
|
83 delete mCntModel; |
|
84 mCntModel = NULL; |
|
85 |
|
86 delete mVirtualKeyboard; |
|
87 mVirtualKeyboard = NULL; |
|
88 |
|
89 delete mIndexFeedback; |
|
90 mIndexFeedback = NULL; |
|
91 } |
|
92 |
|
93 /*! |
|
94 Query to see if the user decided to press Cancel after selecting |
|
95 group members. Must be called to see if results are valid. |
|
96 */ |
|
97 bool CntFetchContacts::wasCanceled() const |
|
98 { |
|
99 return mWasCanceled; |
|
100 } |
|
101 |
|
102 void CntFetchContacts::setDetails(QString aTitle, QString aButtonText) |
|
103 { |
|
104 mButtonText = aButtonText; |
|
105 |
|
106 if (!mLabel) { |
|
107 mLabel = new HbLabel(aTitle); |
|
108 } |
|
109 } |
|
110 |
|
111 /*! |
|
112 Brings up a list of contacts, awaiting user response. This function is asynchronous. |
|
113 When a response is given, a clicked signal will be sent. |
|
114 */ |
|
115 void CntFetchContacts::displayContacts(DisplayType aType, HbAbstractItemView::SelectionMode aMode, QSet<QContactLocalId> aContacts) |
|
116 { |
|
117 switch (aType) { |
|
118 case view: |
|
119 { |
|
120 // TODO Currently only services will need a view |
|
121 break; |
|
122 } |
|
123 |
|
124 case popup: |
|
125 { |
|
126 doInitialize(aMode,aContacts); |
|
127 markMembersInView(); |
|
128 connectSignal(); |
|
129 showPopup(); |
|
130 |
|
131 mLayout->addItem(mSearchPanel); |
|
132 mContainerWidget->setLayout(mLayout); |
|
133 mContainerWidget->setPreferredHeight(mListView->mainWindow()->size().height()); |
|
134 mContainerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
135 break; |
|
136 } |
|
137 |
|
138 default: |
|
139 break; |
|
140 } |
|
141 } |
|
142 |
|
143 QSet<QContactLocalId> CntFetchContacts::getSelectedContacts() const |
|
144 { |
|
145 return mCurrentlySelected; |
|
146 } |
|
147 |
|
148 void CntFetchContacts::closeFind() |
|
149 { |
|
150 if (mSearchPanel) { |
|
151 QContactDetailFilter filter; |
|
152 filter.setDetailDefinitionName(QContactType::DefinitionName, QContactType::FieldType); |
|
153 QString typeContact = QContactType::TypeContact; |
|
154 filter.setValue(typeContact); |
|
155 |
|
156 mSearchPanel->deleteLater(); |
|
157 } |
|
158 } |
|
159 |
|
160 void CntFetchContacts::setFilter(const QString &filterString) |
|
161 { |
|
162 QStringList searchList = filterString.split(QRegExp("\\s+"), QString::SkipEmptyParts); |
|
163 |
|
164 QContactDetailFilter detailfilter; |
|
165 detailfilter.setDetailDefinitionName(QContactDisplayLabel::DefinitionName, QContactDisplayLabel::FieldLabel); |
|
166 detailfilter.setMatchFlags(QContactFilter::MatchStartsWith); |
|
167 detailfilter.setValue(searchList); |
|
168 |
|
169 mCntModel->setFilterAndSortOrder(detailfilter); |
|
170 |
|
171 markMembersInView(); |
|
172 |
|
173 if (mCntModel->rowCount() == 0) { |
|
174 mLayout->removeItem(mListView); |
|
175 |
|
176 if (mEmptyListLabel) { |
|
177 qreal searchHeight = mSearchPanel->size().height(); |
|
178 HbLabel* heading = static_cast<HbLabel*>(mPopup->headingWidget()); |
|
179 qreal heightToSet = mPopup->size().height() - mVirtualKeyboard->keyboardArea().height() - searchHeight - heading->size().height(); |
|
180 mEmptyListLabel->setMaximumHeight(heightToSet); |
|
181 mEmptyListLabel->setVisible(true); |
|
182 mLayout->insertItem(0, mEmptyListLabel); |
|
183 } |
|
184 |
|
185 mListView->setVisible(false); |
|
186 mSearchPanel->setVisible(true); |
|
187 } |
|
188 else { |
|
189 if (mEmptyListLabel) { |
|
190 mEmptyListLabel->setVisible(false); |
|
191 } |
|
192 mLayout->removeItem(mEmptyListLabel); |
|
193 mLayout->insertItem(0, mListView); |
|
194 mListView->setVisible(true); |
|
195 } |
|
196 } |
|
197 |
|
198 void CntFetchContacts::handleKeypadOpen() |
|
199 { |
|
200 qreal searchHeight = mSearchPanel->size().height(); |
|
201 HbLabel* heading = static_cast<HbLabel*>(mPopup->headingWidget()); |
|
202 qreal heightToSet = mPopup->size().height() - mVirtualKeyboard->keyboardArea().height() - searchHeight - heading->size().height(); |
|
203 |
|
204 if (mEmptyListLabel) { |
|
205 mEmptyListLabel->setMaximumHeight( heightToSet - mEmptyListLabel->size().height() ); |
|
206 } |
|
207 |
|
208 mListView->setMaximumHeight(heightToSet); |
|
209 } |
|
210 |
|
211 void CntFetchContacts::handleKeypadClose() |
|
212 { |
|
213 mListView->setMaximumHeight(mPopup->size().height()); |
|
214 |
|
215 if (mEmptyListLabel) { |
|
216 mEmptyListLabel->setMaximumHeight(mPopup->size().height()); |
|
217 } |
|
218 } |
|
219 |
|
220 void CntFetchContacts::handleUserResponse(HbAction* action) |
|
221 { |
|
222 HbDialog *popup = static_cast<HbDialog*>(sender()); |
|
223 |
|
224 bool userCanceled = (action == mSecondaryAction); |
|
225 if (popup && userCanceled) { |
|
226 mCurrentlySelected.clear(); |
|
227 |
|
228 // Notify that the user canceled. |
|
229 mWasCanceled = true; |
|
230 } |
|
231 else { |
|
232 mWasCanceled = false; |
|
233 } |
|
234 |
|
235 emit clicked(); |
|
236 } |
|
237 |
|
238 void CntFetchContacts::memberSelectionChanged(const QModelIndex &index) |
|
239 { |
|
240 if (!index.isValid()) return; |
|
241 |
|
242 if (mSelectionMode == HbAbstractItemView::SingleSelection) { |
|
243 mCurrentlySelected.clear(); |
|
244 } |
|
245 |
|
246 QContactLocalId contactId = mCntModel->contact(index).localId(); |
|
247 |
|
248 bool isSelected = mListView->selectionModel()->isSelected(index); |
|
249 if (isSelected != mCurrentlySelected.contains(contactId)) { |
|
250 if (isSelected) { |
|
251 mCurrentlySelected.insert(contactId); |
|
252 } |
|
253 else { |
|
254 mCurrentlySelected.remove(contactId); |
|
255 } |
|
256 } |
|
257 } |
|
258 |
|
259 void CntFetchContacts::doInitialize(HbAbstractItemView::SelectionMode aMode, |
|
260 QSet<QContactLocalId> aContacts) |
|
261 { |
|
262 mSelectionMode = aMode; |
|
263 mCurrentlySelected = aContacts; |
|
264 |
|
265 mSearchPanel->setVisible(true); |
|
266 |
|
267 mPopup = new HbDialog; |
|
268 mListView = new HbListView(mPopup); |
|
269 mListView->setModel(mCntModel); |
|
270 mListView->setSelectionMode(mSelectionMode); |
|
271 mListView->setFrictionEnabled(true); |
|
272 mListView->setScrollingStyle(HbScrollArea::PanWithFollowOn); |
|
273 mListView->verticalScrollBar()->setInteractive(true); |
|
274 |
|
275 HbListViewItem *prototype = mListView->listItemPrototype(); |
|
276 prototype->setGraphicsSize(HbListViewItem::Thumbnail); |
|
277 prototype->setStretchingStyle(HbListViewItem::StretchLandscape); |
|
278 |
|
279 mIndexFeedback = new HbIndexFeedback(mPopup); |
|
280 mIndexFeedback->setIndexFeedbackPolicy(HbIndexFeedback::IndexFeedbackSingleCharacter); |
|
281 mIndexFeedback->setItemView(mListView); |
|
282 |
|
283 // Note that the layout takes ownership of the item(s) it contains. |
|
284 if (!mCntModel->rowCount()) { |
|
285 mListView->setVisible(false); |
|
286 if (!mEmptyListLabel) { |
|
287 mEmptyListLabel = new HbTextItem(hbTrId("(no matching contacts)")); |
|
288 mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); |
|
289 mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary)); |
|
290 mEmptyListLabel->setAlignment(Qt::AlignCenter); |
|
291 mLayout->insertItem(0, mEmptyListLabel); |
|
292 } |
|
293 } |
|
294 else { |
|
295 mLayout->addItem(mListView); |
|
296 } |
|
297 |
|
298 mCntModel->showMyCard(false); |
|
299 } |
|
300 |
|
301 void CntFetchContacts::connectSignal() |
|
302 { |
|
303 connect(mListView, SIGNAL(activated(const QModelIndex&)), |
|
304 this, SLOT(memberSelectionChanged(const QModelIndex&))); |
|
305 } |
|
306 |
|
307 void CntFetchContacts::showPopup() |
|
308 { |
|
309 mPopup->setTimeout(HbPopup::NoTimeout); |
|
310 mPopup->setDismissPolicy(HbPopup::NoDismiss); |
|
311 mPopup->setModal(true); |
|
312 mPopup->setContentWidget(mContainerWidget); |
|
313 |
|
314 if (!mVirtualKeyboard) { |
|
315 mVirtualKeyboard = new HbStaticVkbHost(mPopup); |
|
316 connect(mVirtualKeyboard, SIGNAL(keypadOpened()), this, SLOT(handleKeypadOpen())); |
|
317 connect(mVirtualKeyboard, SIGNAL(keypadClosed()), this, SLOT(handleKeypadClose())); |
|
318 } |
|
319 |
|
320 if (!mLabel) { |
|
321 mLabel = new HbLabel(hbTrId("txt_phob_title_contacts")); |
|
322 } |
|
323 mPopup->setHeadingWidget(mLabel); |
|
324 |
|
325 if (!mButtonText.isEmpty()) { |
|
326 mPrimaryAction = new HbAction(hbTrId(mButtonText.toAscii())); |
|
327 mPopup->addAction(mPrimaryAction); |
|
328 } |
|
329 |
|
330 mSecondaryAction = new HbAction(hbTrId("txt_common_button_cancel")); |
|
331 mPopup->addAction(mSecondaryAction); |
|
332 |
|
333 mPopup->open(this, SLOT(handleUserResponse(HbAction*))); |
|
334 } |
|
335 |
|
336 void CntFetchContacts::markMembersInView() |
|
337 { |
|
338 // if there are no contacts matching the current filter, |
|
339 // show "no matching contacts" label |
|
340 if (mCntModel->rowCount() == 0) { |
|
341 if (!mEmptyListLabel) { |
|
342 mEmptyListLabel = new HbTextItem(hbTrId("(no matching contacts)")); |
|
343 mEmptyListLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); |
|
344 mEmptyListLabel->setFontSpec(HbFontSpec(HbFontSpec::Primary)); |
|
345 mEmptyListLabel->setAlignment(Qt::AlignCenter); |
|
346 mLayout->insertItem(1, mEmptyListLabel); |
|
347 } |
|
348 } |
|
349 else { |
|
350 mLayout->removeItem(mEmptyListLabel); |
|
351 delete mEmptyListLabel; |
|
352 mEmptyListLabel = 0; |
|
353 } |
|
354 |
|
355 // Mark group members in the listview |
|
356 foreach (QContactLocalId id, mCurrentlySelected) { |
|
357 QContact contact = mManager->contact(id); |
|
358 QModelIndex contactIndex = mCntModel->indexOfContact(contact); |
|
359 mListView->selectionModel()->select(contactIndex, QItemSelectionModel::Select); |
|
360 } |
|
361 } |
|
362 |
|
363 // End of file |