diff -r 4b686cfad39d -r e6894b852bc6 calendarui/views/src/calenagendaviewwidget.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarui/views/src/calenagendaviewwidget.cpp Thu Jul 22 16:32:51 2010 +0100 @@ -0,0 +1,1142 @@ +/* +* Copyright (c) 2009 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: CalenAgendaViewWidget implementation +* +*/ + +// System includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// User includes +#include "calenagendaviewwidget.h" +#include "calencommon.h" +#include "calenagendaview.h" +#include "calendocloader.h" +#include "calenservices.h" +#include "calencontext.h" +#include "calendateutils.h" +#include "CalenUid.h" +#include "caleneventlistviewitem.h" +#include "calenpluginlabel.h" +#include "calendarprivatecrkeys.h" + +// Constants +const QString singleSpace(" "); +const QString doubleSpace(" "); +const QString space(" "); +const QString singleHyphen("-"); +const QString customLayout("custom"); +const char *stretchLayout("stretchItem"); +const QString toDoIcon("qtg_small_todo"); +const QString reminderIcon("qtg_mono_alarm"); +const QString locationIcon("qtg_mono_location"); +const QString repeatIcon("qtg_mono_repeat"); +// TODO: Replace with actual image name once its available +//const QString allDayIcon("qtg_small_allday"); +const QString allDayIcon(":/qgn_indi_cdr_meeting_layer0.svg"); +const QString exceptionIcon("qtg_mono_repeat_exception"); +const int singleColumn(1); + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::CalenAgendaViewWidget +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +EXPORT_C CalenAgendaViewWidget::CalenAgendaViewWidget(MCalenServices &services, + CalenDocLoader *docLoader) : +mServices(services), +mDocLoader(docLoader), +mRegionalInfoGroupBox(NULL), +mLongTapEventFlag(false), +mNotesPluginLoaded(false) +{ + // Construct the list view prototype + mListViewPrototype = new CalenEventListViewItem(this); + + // Create the list model + mListModel = new QStandardItemModel(this); + + // Register the custom docml and css to provide our own style to the list items + HbStyleLoader::registerFilePath(":/"); + + //Create the setting manager + mSettingsManager = new XQSettingsManager(this); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::~CalenAgendaViewWidget +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +EXPORT_C CalenAgendaViewWidget::~CalenAgendaViewWidget() +{ + // Unload notes editor if loaded. + if (mNotesEditorPluginLoader) { + mNotesEditorPluginLoader->unload(); + delete mNotesEditorPluginLoader; + mNotesEditorPluginLoader = 0; + } + + if (mListViewPrototype) { + delete mListViewPrototype; + mListViewPrototype = NULL; + } + if (mListModel) { + // Do not delete the model since its owned by the view + mListModel->clear(); + } + if (mSettingsManager) { + delete mSettingsManager; + mSettingsManager = NULL; + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::setupWidget +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::setupWidget(CalenAgendaView *view) +{ + // Store the view for future reference + mView = view; + + if (!mDocLoader) { + // Nothing much can be done. Simply return + return; + } + + // Initialize the child widgets + initChildWidgets(); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::showWidget +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::showWidget() +{ + // Get the date for which this view has been launched + mDate = mServices.Context().focusDateAndTime(); + + // Set the heading text + setHeadingText(); + + // Get the instance list + getInstanceList(); + + // Check if regional information needs to be shown + // and add it or remove it + showHideRegionalInformation(); + + // Load the appropriate section based on the number of events for the day + if (0 == mInstanceArray.count()) { + // There are no entries for the day + // Load and show the empty list section + bool loadSuccess = false; + + // Hide the list which shows the events + mEventsList->hide(); + + // Show the empty list text + mEmptyListLabel->show(); + + // Get the current device orientation + int orientation = mServices.MainWindow().orientation(); + if (Qt::Vertical == orientation) { + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "emptyList", &loadSuccess); + } else { + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "emptyLandscape", &loadSuccess); + } + if (!loadSuccess) { + qFatal("calenagendaviewwidget.cpp : Unable to load empty list section"); + } + } else { + // Hide the empty view label + mEmptyListLabel->hide(); + + // Show the events list + mEventsList->show(); + + // There are one or more events. Load the non-empty section + bool loadSuccess = false; + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "nonEmptyList", &loadSuccess); + if (!loadSuccess) { + qFatal("calenagendaviewwidget.cpp : Unable to load non-empty list section"); + } + // Now populate the list with the events + populateListWidget(); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::orientationChanged +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::orientationChanged(Qt::Orientation orientation) +{ + // Load the appropriate section based on the number of events for the day + if (0 == mInstanceArray.count()) { + // There are no entries for the day + // Load and show the empty list section + bool loadSuccess = false; + + // Hide the list which shows the events + mEventsList->hide(); + + // Show the empty list text + mEmptyListLabel->show(); + + if (Qt::Vertical == orientation) { + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "emptyList", &loadSuccess); + } else { + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "emptyLandscape", &loadSuccess); + } + if (!loadSuccess) { + qFatal("calenagendaviewwidget.cpp : Unable to load empty list section"); + } + } else { + // Hide the empty view label + mEmptyListLabel->hide(); + + // Show the events list + mEventsList->show(); + + // There are one or more events. Load the non-empty section + bool loadSuccess = false; + mDocLoader->load(CALEN_AGENDAVIEW_XML_FILE, "nonEmptyList", &loadSuccess); + if (!loadSuccess) { + qFatal("calenagendaviewwidget.cpp : Unable to load non-empty list section"); + } + handleListItemStretching(orientation); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::handleLocaleChange +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::handleLocaleChange() +{ + +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::setContextFromHighlight +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::setContextFromHighlight(AgendaEntry entry) +{ + if (entry.isTimedEntry()) { + // Timed entry. + QDateTime start = entry.startTime(); + // start.setDate(mDate.date()); + mServices.Context().setFocusDateAndTimeAndInstance(start, + TCalenInstanceId::create(entry)); + } else { + // Untimed entry. + if (CalenDateUtils::onSameDay(TCalenInstanceId::create(entry).mInstanceTime, + mDate)) { + mServices.Context().setInstanceId(TCalenInstanceId::create(entry)); + } else { + // Multi-day untimed note (either multi-day day note or weird todo). + // Focus on the instance and set the focus time to the highlighted day. + mServices.Context().setFocusDateAndTimeAndInstance(mDate, + TCalenInstanceId::create(entry)); + } + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::initChildWidgets +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::initChildWidgets() +{ + // Get the pointer to the events list + mEventsList = static_cast (mDocLoader->findWidget(CALEN_AGENDAVIEW_LISTWIDGET)); + if (!mEventsList) { + qFatal("calenagendaviewwidget.cpp : Unable to find the events list"); + } + // NOTE: Layout name MUST be same as the name mentioned in the css + mEventsList->setLayoutName(customLayout); + + // TODO : remove this line after gestures are available + mEventsList->installEventFilter(mView); + + // Connect to the long press and activation signals + connect(mEventsList, SIGNAL(longPressed(HbAbstractViewItem*, const QPointF&)), + this, SLOT(itemLongPressed(HbAbstractViewItem*, const QPointF&))); + connect(mEventsList, SIGNAL(activated(const QModelIndex&)), this, + SLOT(itemActivated(const QModelIndex&))); + + // Get the pointer to label from the loader. + mHeadingLabel = qobject_cast (mDocLoader->findWidget(CALEN_AGENDAVIEW_HEADING)); + if (!mHeadingLabel) { + qFatal("calenagendaviewwidget.cpp : Unable to find heading widget"); + } + + // Get the pointer to the empty view label + mEmptyListLabel = qobject_cast (mDocLoader->findWidget("noEventsLabel")); + if (!mEmptyListLabel) { + qFatal("calenagendaviewwidget.cpp : Unable to find empty list label"); + } + HbWidget *headingPluginWidget = + qobject_cast (mDocLoader->findWidget(CALEN_AGENDAVIEW_HEADING_REGIONALPLUGIN_WIDGET)); + + mRegionalPluginLayout = static_cast(headingPluginWidget->layout()); + +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::populateListWidget +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::populateListWidget() +{ + // Recycle the list items so that only needed rows + // are added or removed + if (mInstanceArray.count() == 0) { + // Reset the list + mEventsList->reset(); + // Clear the model to ensure it does not have any old items + mListModel->clear(); + return; + } else if (mInstanceArray.count() > mListModel->rowCount()) { + // There are more events than the number of items + // in the list. Add more rows + mListModel->insertRows(0, mInstanceArray.count() - mListModel->rowCount()); + } else if (mInstanceArray.count() < mListModel->rowCount()) { + // There are less number of events than the number + // of items in the list. Remove the extra rows + mListModel->removeRows(0, mListModel->rowCount() - mInstanceArray.count()); + } + mListModel->setColumnCount(singleColumn); + + // Add all the events to the list + for (int index = 0; index < mInstanceArray.count(); index++) { + // Get each of the entry details + AgendaEntry entry = mInstanceArray[index]; + // Create a list item for each entry + createListItem(index, entry); + } + // Add the item on to the list widget + mEventsList->setModel(mListModel, mListViewPrototype); + + // Now get the item to scroll to + int scrollToIndex = getIndexToScrollTo(); + if (mListModel->rowCount() > 0) { + // Scroll to the index only if index is valid + mEventsList->scrollTo(mListModel->index(scrollToIndex, 0)); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::getInstanceList +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::getInstanceList() +{ + // Clear the previous instance list + mInstanceArray.clear(); + + // Check if the date is valid + if (!CalenDateUtils::isValidDay(mDate)) { + mDate = CalenDateUtils::today(); + } + + // Set the filter flags to fetch all relevant entries + AgendaUtil::FilterFlags filter = AgendaUtil::FilterFlags(AgendaUtil::IncludeAnniversaries | + AgendaUtil::IncludeAppointments | + AgendaUtil::IncludeEvents | + AgendaUtil::IncludeReminders | + AgendaUtil::IncludeIncompletedTodos); + + // Fetch the instance list from the agenda interface + mInstanceArray = mServices.agendaInterface()->createEntryIdListForDay(mDate, filter); + +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::setDateToLabel +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::setHeadingText() + { + // Format the date as per the device locale settings + HbExtendedLocale systemLocale = HbExtendedLocale::system(); + + // Get localised name of the day from locale + QString dayString = systemLocale.dayName(mDate.date().dayOfWeek()); + // Append a single space + dayString.append(singleSpace); + // Set the heading + // Append the date which is formatted as per the locale + mHeadingLabel->setHeading(hbTrId( + "txt_calendar_subhead_1_2").arg(dayString).arg( + systemLocale.format(mDate.date(), r_qtn_date_usual_with_zero))); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::createListItem +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::createListItem(int index, AgendaEntry entry) +{ + if (index < 0 || entry.isNull()) { + // Not a valid index or entry. Dont do anything + return; + } + // Check if the entry is a timed entry + // TODO: Right now, only appointment/meeting type is being handled + // Handle other timed entry types like reminder etc + if (entry.isTimedEntry()) { + // Get the text and icon data for the entry + addTimedEventToList(index, entry); + } else { + addNonTimedEventToList(index, entry); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::addTimedEventToList +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::addTimedEventToList(int index, AgendaEntry entry) +{ + // Create text and icon list to set to the model + QVariantList textData; + QVariantList iconData; + bool twoLines = false; + + /** + * IMPORTANT NOTE: All the text and icon items must be + * inserted into the variant list in a specific order. + * If not, chaos will set it!!! + * On a more serious note, the mesh layout depends on the + * fact that the icons and text data will be added in a + * particular order. If one of the items go missing, the + * layout might get messed up. Also in case a particular item + * is not required to be added in the middle of the list, an + * empty QVariant must be added to indicate to the list view + * that the item must be removed from the layout. + * Do not mess with the order in case you are not sure what + * you are exactly doing. + */ + + // The first icon to show to-do or all day should not be shown + // Append empty data to the icons list + iconData << QVariant(); + + // Check if alarm is enabled for the entry + if (entry.alarm().isNull()) { + // Insert a blank icon. Else the next icon + // will get replaced in this icon's position + iconData << QVariant(); + } else { + iconData << HbIcon(reminderIcon); + } + + // Check if the entry is recurring + if (entry.isRepeating()) { + iconData << HbIcon(repeatIcon); + } else if (!entry.recurrenceId().isNull()) { + // This is an exceptional entry + iconData << HbIcon(exceptionIcon); + } else { + // Insert a blank icon. Else the next icon + // will get replaced in this icon's position + iconData << QVariant(); + } + + HbExtendedLocale locale = HbExtendedLocale::system(); + // Get the start time and format as per the locale + QDateTime startTime = entry.startTime(); + QTime eventStartTime; + + if (CalenDateUtils::beginningOfDay(startTime) + < CalenDateUtils::beginningOfDay(mDate)) { + // event is started previous day, show StarTime as 12:00 am in Agendaview, + eventStartTime.setHMS(00, 00, 00); + } else { + eventStartTime = entry.startTime().time(); + } + QString eventTime = locale.format(eventStartTime, r_qtn_time_usual_with_zero); + + // Get the event end time + QDateTime endTime = entry.endTime(); + QTime eventEndTime; + + if (CalenDateUtils::beginningOfDay(endTime) + > CalenDateUtils::beginningOfDay(mDate)) { + // event has MidNight crossover, show EndTime as 11:59pm in Agendaview, + eventEndTime.setHMS(23, 59, 59); + } else { + eventEndTime = entry.endTime().time(); + } + + if (eventStartTime < eventEndTime) { + // Raise the flag to indicate that the list item + // would wrap to two lines + twoLines = true; + // Append '-' to indicate an end time is present + eventTime.append(singleHyphen); + } else { + // To align the subject properly if the start and endtime are same + eventTime.append(doubleSpace); + } + + // Add the event time to the text list + // This MUST be the first item to be added to the list + textData << eventTime; + + // Get the entry subject + QString subject = entry.summary(); + if (subject.isEmpty() || subject.isNull()) { + // No subject. Add "(No subject)" text + subject.append(hbTrId("txt_calendar_dblist_unnamed")); + } + // Add the subject to the text list + // This MUST be the second item in the list + textData << subject; + + // Check if the entry has location + // TODO: This must change to check for geo-location + // This MUST be the third item in the list + if (entry.location().isEmpty()) { + // Insert a blank icon. Else the next icon + // will get replaced in this icon's position + iconData << QVariant(); + if (twoLines) { + /** + * NOTE: If the primary text is wrapping to two + * lines, then the location must be set as blank + * since the bottom of the list item is anchored to + * the bottom of the secondary text. Else the bottom + * of the list will overlap on the primary text + */ + textData << singleSpace; + } else { + /** + * Else, set the secondary text to empty to indicate + * to the list view to remove the item itself and + * shrink its size to a single line size + */ + textData << QVariant(); + } + } else { + // TODO: Location icon must be shown + // only if valid geo-coordinates are present + if (!entry.geoValue().isNull()){ + iconData << HbIcon(locationIcon); + } + else { + iconData << HbIcon(); + } + textData << entry.location(); + } + // Add the end time to the list item + if (eventStartTime < eventEndTime) { + QString endtime = locale.format(eventEndTime, r_qtn_time_usual_with_zero); + endtime.append(singleSpace); + textData << endtime; + }else { + textData<index(index, 0); + mListModel->setData(listIndex, textData, Qt::DisplayRole); + mListModel->setData(listIndex, iconData, Qt::DecorationRole); + + // Disable item stretching by removing the dynamic property + HbListViewItem *listViewItem = static_cast + (mEventsList->itemByIndex(mListModel->index(index, 0))); + if (listViewItem) { + listViewItem->setProperty(stretchLayout, false); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::addNonTimedEventToList +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::addNonTimedEventToList(int index, AgendaEntry entry) +{ + QVariantList textData; + QVariantList iconData; + + /** + * IMPORTANT NOTE: All the text and icon items must be + * inserted into the variant list in a specific order. + * If not, chaos will set it!!! + * On a more serious note, the mesh layout depends on the + * fact that the icons and text data will be added in a + * particular order. If one of the items go missing, the + * layout might get messed up. Also in case a particular item + * is not required to be added in the middle of the list, an + * empty QVariant must be added to indicate to the list view + * that the item must be removed from the layout. + * Do not mess with the order in case you are not sure what + * you are exactly doing. + */ + + // The first column text has to be empty + textData << QVariant(); + + // Get the entry subject + QString subject = entry.summary(); + if (subject.isEmpty() || subject.isNull()) { + // No subject. Add "(No subject)" text + subject.append(hbTrId("txt_calendar_dblist_unnamed")); + } + // Add the subject to the text list + // This MUST be the second item in the list + textData << subject; + + // Get the entry type + AgendaEntry::Type entryType = entry.type(); + + if (entryType == AgendaEntry::TypeAnniversary) { + // Nothing to do as of now as anniversary events + // cannot be created + // TODO: To be handled in case of sync + } else if (entryType == AgendaEntry::TypeEvent) { + // This is an all day event + // Append the all-day icon + iconData << HbIcon(allDayIcon); + + // Check if alarm is enabled for the entry + if (entry.alarm().isNull()) { + // Insert a blank icon. Else next text item will get shifted to left + iconData << HbIcon(); + } else { + // if entry is not repeating in place of reminder icon put a blank + // icon and move reminder icon to the place of repeating icon + if (!entry.isRepeating()) { + iconData << HbIcon(); + } + iconData << HbIcon(reminderIcon); + } + + // Check if the entry is recurring + if (entry.isRepeating()) { + iconData << HbIcon(repeatIcon); + } else { + // put the blank icon only when both reminder and repeating icons + // are not there + if (entry.alarm().isNull()) { + iconData << HbIcon(); + } + } + + // Append the location + if (!entry.location().isEmpty()) { + textData << entry.location(); + // TODO: Location icon must be shown + // only if valid geo-coordinates are present + if (!entry.geoValue().isNull()){ + iconData << HbIcon(locationIcon); + }else { + iconData << HbIcon(); + } + } else { + textData << QVariant(); + } + // The fourth text item has to be empty + textData << QVariant(); + + } else if (entryType == AgendaEntry::TypeTodo) { + // Append the to-do icon + iconData << HbIcon(toDoIcon); + + // Get the due date + QDateTime dueDate = entry.endTime(); + + // Append the date first + QString dueDateString(hbTrId("txt_calendar_dblist_val_due_on_1")); + QString dueText; + dueText.setNum(dueDate.date().day()); + dueText.append(singleSpace); + + // Append the month name next + HbExtendedLocale locale = HbExtendedLocale::system(); + QString month = locale.monthName(dueDate.date().month()); + dueText.append(month); + dueText.append(singleSpace); + + // Append the year + QString year; + year.setNum(dueDate.date().year()); + dueText.append(year); + + textData << dueDateString.arg(dueText); + + // The fourth text item has to be empty + textData << QVariant(); + + // Check if alarm is enabled for the entry + if (entry.alarm().isNull()) { + // Insert a blank icon. Else next text item will get shifted to left + iconData << HbIcon(); + } else { + // if entry is not repeating in place of reminder icon put a blank + // icon and move reminder icon to the place of repeating icon + if (!entry.isRepeating()) { + iconData << HbIcon(); + } + iconData << HbIcon(reminderIcon); + } + + // Check if the entry is recurring + if (entry.isRepeating()) { + iconData << HbIcon(repeatIcon); + } else { + // Insert the blank icon only when both reminder and repeating icons + // are not there + if (entry.alarm().isNull()) { + iconData << HbIcon(); + } + } + } + + // Get the list model index and set the text and icon data + QModelIndex listIndex = mListModel->index(index, 0); + mListModel->setData(listIndex, textData, Qt::DisplayRole); + mListModel->setData(listIndex, iconData, Qt::DecorationRole); + + // Enable item stretching by adding the dynamic property + HbListViewItem *listViewItem = static_cast + (mEventsList->itemByIndex(mListModel->index(index, 0))); + Qt::Orientation orientation = mServices.MainWindow().orientation(); + // Apply stretch only for landscape orientation + if (listViewItem) { + if (Qt::Horizontal == orientation) { + listViewItem->setProperty(stretchLayout, true); + } else { + listViewItem->setProperty(stretchLayout, false); + } + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::handleListItemStretching +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::handleListItemStretching(Qt::Orientation orientation) +{ + if (mInstanceArray.count() == 0) { + // Nothing much to do. Simply return + return; + } + for(int index = 0; index < mInstanceArray.count() ; index ++) { + AgendaEntry entry = mInstanceArray[index]; + if (!entry.isNull()) { + AgendaEntry::Type eventType = entry.type(); + switch(eventType) { + // Apply the stretching to only to-do's, + // anniversary and all-day event types + case AgendaEntry::TypeTodo: + case AgendaEntry::TypeEvent: + case AgendaEntry::TypeAnniversary: + { + // Get the list view item corresponding to the index + HbListViewItem *listItem = static_cast + (mEventsList->itemByIndex(mListModel->index(index, 0))); + if (listItem) { + if (orientation == Qt::Horizontal) { + // Set a dynamic property to indicate that this list item + // must be stretched in landscape. + // NOTE: Property name MUST match the name specified in + // css file, else wierd things might happen + listItem->setProperty(stretchLayout, true); + } + } + } + break; + default: + { + HbListViewItem *listItem = static_cast + (mEventsList->itemByIndex(mListModel->index(index, 0))); + if (listItem) { + listItem->setProperty(stretchLayout, false); + } + break; + } + } + } + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::getIndexToScrollTo +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +int CalenAgendaViewWidget::getIndexToScrollTo() +{ + int scrollIndex = 0; + TCalenInstanceId instanceId = mServices.Context().instanceId(); + if (instanceId == TCalenInstanceId::nullInstanceId()) { + // If the instance is not set, then scroll to zero index + return scrollIndex; + } + + for (int index = 0 ; index < mInstanceArray.count() ; index++) { + AgendaEntry entry = mInstanceArray[index]; + if (entry.id() == instanceId.mEntryLocalUid) { + // Match found. + scrollIndex = index; + break; + } + } + return scrollIndex; +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::showHideRegionalInformation +// To Show and hide regional plugin label depends upon settings +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::showHideRegionalInformation() +{ + if (mView->pluginEnabled()) { + XQSettingsKey regionalInfo(XQSettingsKey::TargetCentralRepository, + KCRUidCalendar, KCalendarShowRegionalInfo); + + int showRegionalInfo = + mSettingsManager->readItemValue(regionalInfo).toUInt(); + if (showRegionalInfo) { + + if (!mRegionalInfoGroupBox) { + mRegionalInfoGroupBox = new HbGroupBox(); + CalenPluginLabel *regionalInfo = new CalenPluginLabel( + mServices, this); + regionalInfo->setFontSpec(HbFontSpec(HbFontSpec::Primary)); + mRegionalInfoGroupBox->setContentWidget(regionalInfo); + mRegionalPluginLayout->insertItem(1, mRegionalInfoGroupBox); + } + QString *pluginString = mView->pluginText(); + HbLabel *pluginInfoLabel = qobject_cast + (mRegionalInfoGroupBox->contentWidget()); + pluginInfoLabel->setPlainText(*pluginString); + } + } else { + if (mRegionalInfoGroupBox) { + mRegionalPluginLayout->removeItem(mRegionalInfoGroupBox); + delete mRegionalInfoGroupBox; + mRegionalInfoGroupBox = NULL; + } + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::createNewEvent +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::createNewEvent() +{ + // Issue a command to launch editor to create + // a new event + mServices.IssueCommandL(ECalenNewMeeting); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::editEntry +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::editEntry() +{ + // Check if the selected index is valid + if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) { + return; + } + + // Get the entry details first + AgendaEntry entry = mInstanceArray[mSelectedIndex]; + if (AgendaEntry::TypeTodo == entry.type()) { + // Load the notes editor plugin if not loaded. + if (!mNotesPluginLoaded) { + // Launch the to-do editor using notes editor plugin api + QDir dir(NOTES_EDITOR_PLUGIN_PATH); + QString pluginName = dir.absoluteFilePath(NOTES_EDITOR_PLUGIN_NAME); + + // Create NotesEditor plugin loader object. + mNotesEditorPluginLoader = new QPluginLoader(pluginName); + + // Load the plugin + mNotesPluginLoaded = mNotesEditorPluginLoader->load(); + } + + QObject *plugin = qobject_cast ( + mNotesEditorPluginLoader->instance()); + + NotesEditorInterface* interface = + qobject_cast(plugin); + + interface->edit(entry, mServices.agendaInterface()); + + connect( + interface, SIGNAL(editingCompleted(bool)), + this, SLOT(noteEditingCompleted(bool))); + } else { + // Set the context + setContextFromHighlight(entry); + // Issue a command to launch the editor to edit this entry + mServices.IssueCommandL(ECalenEditCurrentEntry); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::viewEntry +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::viewEntry() +{ + // Get the entry details first + AgendaEntry entry = mInstanceArray[mSelectedIndex]; + + // Set the context + setContextFromHighlight(entry); + + // Launch the event viewer. + mServices.IssueCommandL(ECalenEventView); +} + + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::deleteEntry +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::deleteEntry() +{ + // Check if the selected index is valid + if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) { + return; + } + + // Get the entry details + AgendaEntry entry = mInstanceArray[mSelectedIndex]; + // Set the context + setContextFromHighlight(entry); + // Issue the command to delete the entry + mServices.IssueCommandL(ECalenDeleteCurrentEntry); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::markAsDone +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::markAsDone() +{ + // Check if the selected index is valid + if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) { + return; + } + + // Get the entry details + AgendaEntry entry = mInstanceArray[mSelectedIndex]; + + // Check again if the event is of type to-to + if (AgendaEntry::TypeTodo == entry.type()) { + // Set the status of the to-do as completed + entry.setStatus(AgendaEntry::TodoCompleted); + // Update the completed date and time + entry.setCompletedDateTime(mDate); + + // Update the entry in the database + mServices.agendaInterface()->setCompleted(entry, true, mDate); + mServices.IssueCommandL(ECalenStartActiveStep); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::itemLongPressed +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::itemLongPressed(HbAbstractViewItem* listViewItem, + const QPointF& coords) +{ + mLongTapEventFlag = true; + // Update the selection index first + mSelectedIndex = listViewItem->modelIndex().row(); + + if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) { + // Invalid index + return; + } + + AgendaEntry entry = mInstanceArray[mSelectedIndex]; + + // Create new menu. + HbMenu *contextMenu = new HbMenu(); + + // Add the open option + HbAction *openAction = contextMenu->addAction( + hbTrId("txt_common_menu_open")); + + // Check the type of event + if (AgendaEntry::TypeTodo == entry.type()) { + // Add an option to mark the note as complete + HbAction *completeAction = contextMenu->addAction( + hbTrId("txt_calendar_menu_mark_as_done")); + } + + // Add the edit option + HbAction *editAction = contextMenu->addAction( + hbTrId("txt_common_menu_edit")); + + // Add the delete option + HbAction *deleteAction = contextMenu->addAction( + hbTrId("txt_common_menu_delete")); + + contextMenu->setDismissPolicy(HbMenu::TapAnywhere); + + // Show context sensitive menu. + // Param const QPointF& coordinate - is a longpress position. + contextMenu->setPreferredPos(coords); + connect(contextMenu, SIGNAL(aboutToClose()), + this, + SLOT(contextMenuClosed())); + + contextMenu->open(this, SLOT(contextManuTriggered(HbAction *))); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::itemActivated +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::itemActivated(const QModelIndex &index) +{ + // Update the selection index first + mSelectedIndex = index.row(); + + // Check if the selected index is valid + if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) { + return; + } + if( !mLongTapEventFlag ) { + // Open the event for viewing + viewEntry(); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::itemActivated +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::noteEditingCompleted(bool status) +{ + // We need to refresh the list since user + // might have marked the to-do as complete or + // edited it or deleted it. So get the instance + // list again + if (status) { + mServices.IssueCommandL(ECalenStartActiveStep); + } +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::goToToday +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::goToToday() +{ + // First check if we are not already + // showing today's agenda + if (mDate == CalenDateUtils::today()) { + return; + } + + // Set the context for the current day + mServices.Context().setFocusDate(CalenDateUtils::today()); + + mView->refreshViewOnGoToDate(); +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::contextMenuClosed +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::contextMenuClosed() +{ + mLongTapEventFlag = false; +} + +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::contextManuTriggered +// Rest of the details are commented in the header +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::contextManuTriggered(HbAction *action) +{ + if (action->text() == hbTrId("txt_common_menu_open")) { + viewEntry(); + } else if (action->text() == hbTrId("txt_calendar_menu_mark_as_done")) { + markAsDone(); + } else if (action->text() == hbTrId("txt_common_menu_edit")) { + editEntry(); + } else { + if (action->text() == hbTrId("txt_common_menu_delete")) { + deleteEntry(); + } + } +} +// ---------------------------------------------------------------------------- +// CalenAgendaViewWidget::clearListModel +// clears the list model +// ---------------------------------------------------------------------------- +// +void CalenAgendaViewWidget::clearListModel() + { + mListModel->clear(); + } + +// End of file --Don't remove this.