|
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 * Definition file for NotesMainView class. |
|
16 * |
|
17 */ |
|
18 |
|
19 // System includes |
|
20 #include <QDebug> |
|
21 #include <QDateTime> |
|
22 #include <HbListView> |
|
23 #include <HbListWidget> |
|
24 #include <HbAction> |
|
25 #include <HbTextEdit> |
|
26 #include <HbInstance> |
|
27 #include <HbMainWindow> |
|
28 #include <HbMenu> |
|
29 #include <HbLabel> |
|
30 #include <HbAbstractViewItem> |
|
31 #include <HbAbstractItemView> |
|
32 #include <HbGroupBox> |
|
33 #include <HbListViewItem> |
|
34 |
|
35 // User includes |
|
36 #include "agendaeventviewer.h" |
|
37 #include "notesmainview.h" |
|
38 #include "notescommon.h" |
|
39 #include "notesdocloader.h" |
|
40 #include "agendautil.h" |
|
41 #include "notesmodel.h" |
|
42 #include "notessortfilterproxymodel.h" |
|
43 #include "noteseditor.h" |
|
44 |
|
45 /*! |
|
46 \class NotesMainView |
|
47 \brief The main view of the notes application. Responsible for displaying |
|
48 notes and todos. |
|
49 |
|
50 \sa NotesViewManager |
|
51 */ |
|
52 |
|
53 /*! |
|
54 Constructs the NotesMainView object. |
|
55 |
|
56 \param parent The parent of type QGraphicsWidget. |
|
57 */ |
|
58 NotesMainView::NotesMainView(QGraphicsWidget *parent) |
|
59 :HbView(parent), |
|
60 mSelectedItem(0), |
|
61 mDeleteAction(0) |
|
62 { |
|
63 qDebug() << "notes: NotesMainView::NotesMainView -->"; |
|
64 |
|
65 // Nothing yet. |
|
66 |
|
67 qDebug() << "notes: NotesMainView::NotesMainView <--"; |
|
68 } |
|
69 |
|
70 /*! |
|
71 Destructor. |
|
72 */ |
|
73 NotesMainView::~NotesMainView() |
|
74 { |
|
75 qDebug() << "notes: NotesMainView::~NotesMainView -->"; |
|
76 |
|
77 if (mDocLoader) { |
|
78 delete mDocLoader; |
|
79 mDocLoader = 0; |
|
80 } |
|
81 |
|
82 qDebug() << "notes: NotesMainView::~NotesMainView <--"; |
|
83 } |
|
84 |
|
85 /*! |
|
86 Called by the NotesViewManager after loading the view from the docml. |
|
87 The initializaion/setup of the view is done here. |
|
88 |
|
89 \param controller The NotesAppController object. |
|
90 \param docLoader Pointer to NotesDocLoader object. |
|
91 */ |
|
92 void NotesMainView::setupView( |
|
93 NotesAppControllerIf &controllerIf, NotesDocLoader *docLoader) |
|
94 { |
|
95 qDebug() << "notes: NotesMainView::setupView -->"; |
|
96 |
|
97 mDocLoader = docLoader; |
|
98 mAppControllerIf = &controllerIf; |
|
99 mNotesModel = mAppControllerIf->notesModel(); |
|
100 mAgendaUtil = mAppControllerIf->agendaUtil(); |
|
101 |
|
102 mProxyModel = new NotesSortFilterProxyModel(*mAgendaUtil, this); |
|
103 mProxyModel->setDynamicSortFilter(true); |
|
104 mProxyModel->setSourceModel(mNotesModel->sourceModel()); |
|
105 |
|
106 NotesSortFilterProxyModel *subModel = |
|
107 new NotesSortFilterProxyModel(*mAgendaUtil, this); |
|
108 subModel->setDynamicSortFilter(true); |
|
109 subModel->setSourceModel(mProxyModel); |
|
110 |
|
111 // Get the list object from the document and update the model. |
|
112 mListView = static_cast<HbListView *> (mDocLoader->findWidget("listView")); |
|
113 Q_ASSERT_X( |
|
114 mListView, |
|
115 "notesmainview.cpp", |
|
116 "Unable to find list view."); |
|
117 // Update the list view model. |
|
118 mListView->setModel(subModel); |
|
119 |
|
120 // Setup the operations that can be done with a list view. |
|
121 connect( |
|
122 mListView, SIGNAL(activated(const QModelIndex &)), |
|
123 this, SLOT(handleItemReleased(const QModelIndex &))); |
|
124 connect( |
|
125 mListView, |
|
126 SIGNAL(longPressed(HbAbstractViewItem *, const QPointF &)), |
|
127 this, |
|
128 SLOT(handleItemLongPressed(HbAbstractViewItem *, const QPointF &))); |
|
129 connect( |
|
130 mNotesModel, SIGNAL(rowAdded(QModelIndex)), |
|
131 this, SLOT(scrollTo(QModelIndex))); |
|
132 |
|
133 // Get the view heading label |
|
134 mViewHeading = static_cast<HbLabel *> ( |
|
135 mDocLoader->findWidget("viewHeading")); |
|
136 |
|
137 // Get the toolbar/menu actions. |
|
138 mAddNoteAction = static_cast<HbAction *> ( |
|
139 mDocLoader->findObject("newNoteAction")); |
|
140 Q_ASSERT_X( |
|
141 mAddNoteAction, |
|
142 "notesmainview.cpp", |
|
143 "Unable to find addNoteAction."); |
|
144 connect( |
|
145 mAddNoteAction, SIGNAL(triggered()), |
|
146 this, SLOT(createNewNote())); |
|
147 |
|
148 mAllNotesAction = static_cast<HbAction *> ( |
|
149 mDocLoader->findObject("allNotesAction")); |
|
150 Q_ASSERT_X( |
|
151 mAllNotesAction, |
|
152 "notesmainview.cpp", |
|
153 "Unable to find allNotesAction."); |
|
154 mAllNotesAction->setCheckable(true); |
|
155 mAllNotesAction->setChecked(true); |
|
156 connect( |
|
157 mAllNotesAction, SIGNAL(changed()), |
|
158 this, SLOT(handleActionStateChanged())); |
|
159 |
|
160 mViewCollectionAction = static_cast<HbAction *> ( |
|
161 mDocLoader->findObject("collectionsViewAction")); |
|
162 Q_ASSERT_X( |
|
163 mViewCollectionAction, |
|
164 "notescollectionview.cpp", |
|
165 "Unable to find viewCollectionAction."); |
|
166 |
|
167 connect( |
|
168 mViewCollectionAction, SIGNAL(triggered()), |
|
169 this, SLOT(displayCollectionView())); |
|
170 |
|
171 mSubTitle = static_cast<HbGroupBox *>( |
|
172 mDocLoader->findWidget("viewHeading")); |
|
173 |
|
174 // Handles the orientation change for list items |
|
175 HbMainWindow *window = hbInstance->allMainWindows().first(); |
|
176 handleOrientationChanged(window->orientation()); |
|
177 connect( |
|
178 window, SIGNAL(orientationChanged(Qt::Orientation)), |
|
179 this, SLOT(handleOrientationChanged(Qt::Orientation))); |
|
180 |
|
181 // Update sub heading text for main view. |
|
182 updateSubTitle(); |
|
183 |
|
184 connect( |
|
185 mAgendaUtil, SIGNAL(entryAdded(ulong)), |
|
186 this,SLOT(updateSubTitle(ulong))); |
|
187 connect( |
|
188 mAgendaUtil, SIGNAL(entryDeleted(ulong)), |
|
189 this,SLOT(updateSubTitle(ulong))); |
|
190 connect( |
|
191 mAgendaUtil, SIGNAL(entryUpdated(ulong)), |
|
192 this, SLOT(updateSubTitle(ulong))); |
|
193 qDebug() << "notes: NotesMainView::setupView <--"; |
|
194 } |
|
195 |
|
196 /*! |
|
197 Slot which gets called when `+ New note' action is triggered from the view |
|
198 toolbar. This is responsible for launching the editor to create a new note. |
|
199 */ |
|
200 void NotesMainView::createNewNote() |
|
201 { |
|
202 qDebug() << "notes: NotesMainView::createNewNote -->"; |
|
203 |
|
204 // Here we Display an editor to the use to enter text. |
|
205 mNotesEditor = new NotesEditor(mAgendaUtil, this); |
|
206 connect( |
|
207 mNotesEditor, SIGNAL(editingCompleted(bool)), |
|
208 this, SLOT(handleEditingCompleted(bool))); |
|
209 mNotesEditor->create(NotesEditor::CreateNote); |
|
210 |
|
211 qDebug() << "notes: NotesMainView::createNewNote <--"; |
|
212 } |
|
213 |
|
214 /*! |
|
215 Handles the pressing of a list item in the view. |
|
216 |
|
217 Here we open the editor for viewing/editing. |
|
218 |
|
219 \param index Reference to the QModelIndex representing the view item. |
|
220 \sa HbAbstractViewItem |
|
221 */ |
|
222 void NotesMainView::handleItemReleased(const QModelIndex &index) |
|
223 { |
|
224 qDebug() << "notes: NotesMainView::handleItemReleased -->"; |
|
225 |
|
226 // Sanity check. |
|
227 if (!index.isValid()) { |
|
228 qDebug() << "notes: NotesMainView::handleItemReleased <--"; |
|
229 |
|
230 return; |
|
231 } |
|
232 |
|
233 // First get the id of the note and get the corresponding information from |
|
234 // agendautil. |
|
235 ulong noteId = index.data(NotesNamespace::IdRole).value<qulonglong>(); |
|
236 |
|
237 if (0 >= noteId) { |
|
238 qDebug() << "notes: NotesMainView::handleItemReleased <--"; |
|
239 |
|
240 // Something wrong. |
|
241 return; |
|
242 } |
|
243 |
|
244 // Get the entry details. |
|
245 AgendaEntry entry = mAgendaUtil->fetchById(noteId); |
|
246 if (entry.isNull()) { |
|
247 qDebug() << "notes: NotesMainView::handleItemReleased <--"; |
|
248 |
|
249 // Entry invalid. |
|
250 return; |
|
251 } |
|
252 |
|
253 if(AgendaEntry::TypeTodo == entry.type()) { |
|
254 // Construct agenda event viewer. |
|
255 mAgendaEventViewer = new AgendaEventViewer(mAgendaUtil, this); |
|
256 |
|
257 connect( |
|
258 mAgendaEventViewer, SIGNAL(viewingCompleted(bool)), |
|
259 this, SLOT(handleViewingCompleted(bool))); |
|
260 // Launch agenda event viewer |
|
261 mAgendaEventViewer->view( |
|
262 entry, AgendaEventViewer::ActionEditDelete); |
|
263 }else if(AgendaEntry::TypeNote == entry.type()) { |
|
264 // Construct notes editor. |
|
265 mNotesEditor = new NotesEditor(mAgendaUtil, this); |
|
266 connect( |
|
267 mNotesEditor, SIGNAL(editingCompleted(bool)), |
|
268 this, SLOT(handleEditingCompleted(bool))); |
|
269 |
|
270 // Launch the notes editor with the obtained info. |
|
271 mNotesEditor->edit(entry); |
|
272 } |
|
273 |
|
274 qDebug() << "notes: NotesMainView::handleItemReleased <--"; |
|
275 } |
|
276 |
|
277 /*! |
|
278 Displays a list item specific context menu. |
|
279 |
|
280 \param item The HbAbstractViewItem that was long pressed. |
|
281 \param coords The position where mouse was pressed. |
|
282 |
|
283 \sa HbAbstractViewItem, HbListView, HbMenu. |
|
284 */ |
|
285 void NotesMainView::handleItemLongPressed( |
|
286 HbAbstractViewItem *item, const QPointF &coords) |
|
287 { |
|
288 qDebug() << "notes: NotesMainView::handleItemLongPressed -->"; |
|
289 |
|
290 mSelectedItem = item; |
|
291 |
|
292 ulong noteId = item->modelIndex().data( |
|
293 NotesNamespace::IdRole).value<qulonglong>(); |
|
294 AgendaEntry entry = mAgendaUtil->fetchById(noteId); |
|
295 |
|
296 // Display a context specific menu. |
|
297 HbMenu *contextMenu = new HbMenu(); |
|
298 |
|
299 // Add actions to the context menu. |
|
300 if (AgendaEntry::TypeTodo == entry.type()) { |
|
301 mEditTodoAction = |
|
302 contextMenu->addAction(hbTrId("txt_common_menu_edit")); |
|
303 connect( |
|
304 mEditTodoAction, SIGNAL(triggered()), |
|
305 this, SLOT(editTodo())); |
|
306 } |
|
307 |
|
308 mDeleteAction = |
|
309 contextMenu->addAction(hbTrId("txt_common_menu_delete")); |
|
310 connect( |
|
311 mDeleteAction, SIGNAL(triggered()), |
|
312 this, SLOT(deleteNote())); |
|
313 |
|
314 if (AgendaEntry::TypeNote == entry.type()) { |
|
315 if (entry.favourite()) { |
|
316 mMakeFavouriteAction = contextMenu->addAction( |
|
317 hbTrId("txt_notes_menu_remove_from_favorites")); |
|
318 |
|
319 connect( |
|
320 mMakeFavouriteAction, SIGNAL(triggered()), |
|
321 this, SLOT(markNoteAsFavourite())); |
|
322 |
|
323 } else { |
|
324 mMakeFavouriteAction = contextMenu->addAction( |
|
325 hbTrId("txt_notes_menu_mark_as_favorite")); |
|
326 |
|
327 connect( |
|
328 mMakeFavouriteAction, SIGNAL(triggered()), |
|
329 this, SLOT(markNoteAsFavourite())); |
|
330 } |
|
331 |
|
332 } else if (AgendaEntry::TypeTodo == entry.type()) { |
|
333 if (AgendaEntry::TodoNeedsAction == entry.status()) { |
|
334 mTodoStatusAction = contextMenu->addAction( |
|
335 hbTrId("txt_notes_menu_mark_as_done")); |
|
336 |
|
337 connect( |
|
338 mTodoStatusAction , SIGNAL(triggered()), |
|
339 this, SLOT(markTodoStatus())); |
|
340 |
|
341 } else if (AgendaEntry::TodoCompleted == entry.status()) { |
|
342 mTodoStatusAction = contextMenu->addAction( |
|
343 hbTrId("txt_notes_menu_mark_as_not_done")); |
|
344 |
|
345 connect( |
|
346 mTodoStatusAction , SIGNAL(triggered()), |
|
347 this, SLOT(markTodoStatus())); |
|
348 } |
|
349 } |
|
350 |
|
351 // Show the menu. |
|
352 contextMenu->exec(coords); |
|
353 |
|
354 qDebug() << "notes: NotesMainView::handleItemLongPressed <--"; |
|
355 } |
|
356 |
|
357 /*! |
|
358 Slot to delete a selected note. |
|
359 */ |
|
360 void NotesMainView::deleteNote() |
|
361 { |
|
362 qDebug() << "notes: NotesMainView::deleteNote -->"; |
|
363 |
|
364 Q_ASSERT(mSelectedItem); |
|
365 |
|
366 QModelIndex index = mSelectedItem->modelIndex(); |
|
367 if (!index.isValid()) { |
|
368 qDebug() << "notes: NotesMainView::deleteNote <--"; |
|
369 |
|
370 return; |
|
371 } |
|
372 ulong noteId = |
|
373 index.data(NotesNamespace::IdRole).value<qulonglong>(); |
|
374 if (!noteId) { |
|
375 qDebug() << "notes: NotesMainView::deleteNote <--"; |
|
376 |
|
377 return; |
|
378 } |
|
379 |
|
380 // Delete the given note. |
|
381 mAgendaUtil->deleteEntry(noteId); |
|
382 |
|
383 mSelectedItem = 0; |
|
384 |
|
385 qDebug() << "notes: NotesMainView::deleteNote <--"; |
|
386 } |
|
387 |
|
388 /*! |
|
389 Marks to-do entry as done or undone based on the completed value |
|
390 |
|
391 \param entry reference to the agenda entry |
|
392 \param status is true if to-do entry to be marked as done |
|
393 is false if to-do entry to be marked as undone |
|
394 */ |
|
395 void NotesMainView::markTodoStatus() |
|
396 { |
|
397 qDebug() << "notes: NotesMainView::markTodoStatus -->"; |
|
398 |
|
399 ulong noteId = mSelectedItem->modelIndex().data( |
|
400 NotesNamespace::IdRole).value<qulonglong>(); |
|
401 AgendaEntry entry = mAgendaUtil->fetchById(noteId); |
|
402 |
|
403 QDateTime currentDateTime = QDateTime::currentDateTime(); |
|
404 |
|
405 if (AgendaEntry::TodoNeedsAction == entry.status()) { |
|
406 mAgendaUtil->setCompleted(entry, true, currentDateTime); |
|
407 } else if (AgendaEntry::TodoCompleted == entry.status()) { |
|
408 mAgendaUtil->setCompleted(entry, false, currentDateTime); |
|
409 } |
|
410 |
|
411 qDebug() << "notes: NotesMainView::markTodoStatus <-- "; |
|
412 } |
|
413 |
|
414 /*! |
|
415 Marks/unmarks the note as favourite. |
|
416 */ |
|
417 void NotesMainView::markNoteAsFavourite() |
|
418 { |
|
419 qDebug() << "notes : NotesMainView::markNoteAsFavourite -->"; |
|
420 |
|
421 ulong noteId = mSelectedItem->modelIndex().data( |
|
422 NotesNamespace::IdRole).value<qulonglong>(); |
|
423 AgendaEntry entry = mAgendaUtil->fetchById(noteId); |
|
424 |
|
425 if (entry.favourite()) { |
|
426 entry.setFavourite(0); |
|
427 } else { |
|
428 entry.setFavourite(1); |
|
429 } |
|
430 mAgendaUtil->updateEntry(entry); |
|
431 |
|
432 qDebug() << "notes : NotesMainView::markNoteAsFavourite <--"; |
|
433 } |
|
434 |
|
435 /*! |
|
436 Slot to handle the signal editingCompleted by the notes editor. |
|
437 |
|
438 \param status Boolean value indicating whether the note was saved or not. |
|
439 |
|
440 \sa NotesEditor. |
|
441 */ |
|
442 void NotesMainView::handleEditingCompleted(bool status) |
|
443 { |
|
444 qDebug() << "notes: NotesMainView::handleEditingCompleted -->"; |
|
445 |
|
446 Q_UNUSED(status) |
|
447 |
|
448 // Cleanup. |
|
449 mNotesEditor->deleteLater(); |
|
450 |
|
451 qDebug() << "notes: NotesMainView::handleEditingCompleted <--"; |
|
452 } |
|
453 |
|
454 /*! |
|
455 Displays the collections' view. |
|
456 */ |
|
457 void NotesMainView::displayCollectionView() |
|
458 { |
|
459 qDebug() << "notes: NotesMainView::displayCollectionView -->"; |
|
460 |
|
461 // Switch to collections view. |
|
462 mAppControllerIf->switchToView(NotesNamespace::NotesCollectionViewId); |
|
463 |
|
464 qDebug() << "notes: NotesMainView::displayCollectionView <--"; |
|
465 } |
|
466 |
|
467 /*! |
|
468 Slot where the list view is made to scroll to the QModelIndex index. |
|
469 |
|
470 \param index QModelIndex to be scrolled to. |
|
471 */ |
|
472 void NotesMainView::scrollTo(QModelIndex index) |
|
473 { |
|
474 qDebug() << "notes: NotesMainView::scrollTo -->"; |
|
475 |
|
476 mListView->scrollTo(index, HbAbstractItemView::EnsureVisible); |
|
477 |
|
478 qDebug() << "notes: NotesMainView::scrollTo <--"; |
|
479 } |
|
480 |
|
481 /*! |
|
482 Slot to handle viewing Completed signal from agenda event viewer |
|
483 |
|
484 \param status Indicates the status of viewing |
|
485 */ |
|
486 void NotesMainView::handleViewingCompleted(bool status) |
|
487 { |
|
488 qDebug() << "notes: NotesMainView::handleViewingCompleted -->"; |
|
489 |
|
490 Q_UNUSED(status) |
|
491 |
|
492 mAgendaEventViewer->deleteLater(); |
|
493 |
|
494 qDebug() << "notes: NotesMainView::handleViewingCompleted <--"; |
|
495 } |
|
496 |
|
497 /*! |
|
498 Slot to handle the case when the state of an action has changed. |
|
499 */ |
|
500 void NotesMainView::handleActionStateChanged() |
|
501 { |
|
502 qDebug() << "notes: NotesMainView::handleActionStateChanged -->"; |
|
503 |
|
504 mAllNotesAction->setChecked(true); |
|
505 |
|
506 qDebug() << "notes: NotesMainView::handleActionStateChanged <--"; |
|
507 } |
|
508 |
|
509 /*! |
|
510 Launches the to-do editor to edit the to-do entry |
|
511 */ |
|
512 |
|
513 void NotesMainView::editTodo() |
|
514 { |
|
515 qDebug() << "notes: NotesMainView::editTodo -->"; |
|
516 |
|
517 // Get the selected list item index |
|
518 QModelIndex index = mSelectedItem->modelIndex(); |
|
519 if (!index.isValid()) { |
|
520 qDebug() << "notes: NotesMainView::editTodo <--"; |
|
521 return; |
|
522 } |
|
523 ulong todoId = |
|
524 index.data(NotesNamespace::IdRole).value<qulonglong>(); |
|
525 if (!todoId) { |
|
526 qDebug() << "notes: NotesMainView::editTodo <--"; |
|
527 |
|
528 return; |
|
529 } |
|
530 |
|
531 // Construct notes editor. |
|
532 mNotesEditor = new NotesEditor(mAgendaUtil, this); |
|
533 connect( |
|
534 mNotesEditor, SIGNAL(editingCompleted(bool)), |
|
535 this, SLOT(handleEditingCompleted(bool))); |
|
536 |
|
537 // Launch the to-do editor with the obtained info. |
|
538 mNotesEditor->edit(todoId); |
|
539 |
|
540 qDebug() << "notes: NotesMainView::editTodo <--"; |
|
541 } |
|
542 |
|
543 /*! |
|
544 Handles the orientation changes.Updates the list |
|
545 item when orientation is changed |
|
546 |
|
547 \param orientation Value of the orientation |
|
548 */ |
|
549 void NotesMainView::handleOrientationChanged(Qt::Orientation orientation) |
|
550 { |
|
551 HbListViewItem *prototype = mListView->listItemPrototype(); |
|
552 |
|
553 if (Qt::Horizontal == orientation) { |
|
554 prototype->setStretchingStyle(HbListViewItem::StretchLandscape); |
|
555 |
|
556 // Set the text in landscape mode |
|
557 mAllNotesAction->setText(hbTrId("txt_notes_button_all")); |
|
558 mViewCollectionAction->setText(hbTrId("txt_notes_button_collections")); |
|
559 mAddNoteAction->setText(hbTrId("txt_notes_button_new_note")); |
|
560 } else { |
|
561 prototype->setStretchingStyle(HbListViewItem::NoStretching); |
|
562 |
|
563 // Set empty text in portriat mode so that only icons are visible. |
|
564 mAllNotesAction->setText(""); |
|
565 mViewCollectionAction->setText(""); |
|
566 mAddNoteAction->setText(""); |
|
567 } |
|
568 } |
|
569 |
|
570 /*! |
|
571 Updates the sub heading text |
|
572 */ |
|
573 void NotesMainView::updateSubTitle(ulong id) |
|
574 { |
|
575 Q_UNUSED(id) |
|
576 |
|
577 // Get the number of notes and to-do entries. |
|
578 QList<ulong> entries = mAgendaUtil->entryIds( |
|
579 (AgendaUtil::FilterFlags) |
|
580 (AgendaUtil::IncludeNotes |
|
581 | AgendaUtil::IncludeCompletedTodos |
|
582 | AgendaUtil::IncludeIncompletedTodos)); |
|
583 int c= entries.count(); |
|
584 mSubTitle->setHeading( |
|
585 hbTrId("txt_notes_subhead_ln_notes",entries.count())); |
|
586 } |
|
587 // End of file --Don't remove this. |