calendarui/views/src/calendayviewwidget.cpp
changeset 45 b6db4fd4947b
parent 23 fd30d51f876b
child 46 ecd7b9840282
equal deleted inserted replaced
23:fd30d51f876b 45:b6db4fd4947b
     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: CalenDayViewWidget implementation
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <QStandardItemModel>
       
    20 #include <QGraphicsSceneEvent>
       
    21 #include <hbi18ndef.h>
       
    22 #include <hbextendedlocale.h>
       
    23 #include <hbgroupbox.h>
       
    24 #include <hbmenu.h>
       
    25 #include <hbaction.h>
       
    26 #include <hbmainwindow.h>
       
    27 #include <hbstyleloader.h>
       
    28 #include <hbdatetimepicker.h>
       
    29 #include <hbdialog.h>
       
    30 #include <xqsettingsmanager.h>
       
    31 #include <agendautil.h>
       
    32 #include <noteseditor.h>
       
    33 
       
    34 // User includes
       
    35 #include "calendayviewwidget.h"
       
    36 #include "calencommon.h"
       
    37 #include "calendayview.h"
       
    38 #include "calendocloader.h"
       
    39 #include "calenservices.h"
       
    40 #include "calencontext.h"
       
    41 #include "calendateutils.h"
       
    42 #include "CalenUid.h"
       
    43 #include "caleneventlistviewitem.h"
       
    44 #include "calenpluginlabel.h"
       
    45 #include "CalendarInternalCRKeys.h"
       
    46 
       
    47 // Constants
       
    48 static const QString singleSpace(" ");
       
    49 static const QString newLine("\n");
       
    50 static const QString customLayout("custom");
       
    51 static const char *stretchLayout("stretchItem");
       
    52 // TODO: Replace with actual image names later
       
    53 static const QString toDoIcon("qtg_small_todo");
       
    54 static const QString reminderIcon("qtg_mono_alarm");
       
    55 static const QString locationIcon("qtg_mono_location");
       
    56 static const QString repeatIcon("qtg_mono_repeat");
       
    57 static const QString allDayIcon(":/qgn_indi_cdr_meeting_layer0.svg");
       
    58 static const QString exceptionIcon(":/qtg_mono_exception.png");
       
    59 static const int singleColumn(1);
       
    60 
       
    61 // ----------------------------------------------------------------------------
       
    62 // CalenDayViewWidget::CalenDayViewWidget
       
    63 // Rest of the details are commented in the header
       
    64 // ----------------------------------------------------------------------------
       
    65 //
       
    66 EXPORT_C CalenDayViewWidget::CalenDayViewWidget(MCalenServices &services,
       
    67                                        CalenDocLoader *docLoader) :
       
    68 mServices(services),
       
    69 mDocLoader(docLoader),
       
    70 mRegionalInfoGroupBox(NULL)
       
    71 {
       
    72     // Construct the list view prototype
       
    73     mListViewPrototype = new CalenEventListViewItem(this);
       
    74     
       
    75     // Create the list model
       
    76     mListModel = new QStandardItemModel(this);
       
    77     
       
    78     // Register the custom docml and css to provide our own style to the list items
       
    79     HbStyleLoader::registerFilePath(":/");
       
    80     
       
    81     //Create the setting manager
       
    82     mSettingsManager = new XQSettingsManager(this);
       
    83 }
       
    84 
       
    85 // ----------------------------------------------------------------------------
       
    86 // CalenDayViewWidget::~CalenDayViewWidget
       
    87 // Rest of the details are commented in the header
       
    88 // ----------------------------------------------------------------------------
       
    89 //    
       
    90 EXPORT_C CalenDayViewWidget::~CalenDayViewWidget()
       
    91 {
       
    92     if (mListViewPrototype) {
       
    93         delete mListViewPrototype;
       
    94         mListViewPrototype = NULL;
       
    95     }
       
    96     if (mListModel) {
       
    97         // Do not delete the model since its owned by the view
       
    98         mListModel->clear();
       
    99     }
       
   100 }
       
   101 
       
   102 // ----------------------------------------------------------------------------
       
   103 // CalenDayViewWidget::setupWidget
       
   104 // Rest of the details are commented in the header
       
   105 // ----------------------------------------------------------------------------
       
   106 //    
       
   107 void CalenDayViewWidget::setupWidget(CalenDayView *view)
       
   108 {
       
   109     // Store the view for future reference
       
   110 	mView = view;
       
   111 	
       
   112 	if (!mDocLoader) {
       
   113 	    // Nothing much can be done. Simply return
       
   114 	    return;
       
   115 	}
       
   116 
       
   117 	// Initialize the child widgets
       
   118 	initChildWidgets();
       
   119 }
       
   120 
       
   121 // ----------------------------------------------------------------------------
       
   122 // CalenDayViewWidget::showWidget
       
   123 // Rest of the details are commented in the header
       
   124 // ----------------------------------------------------------------------------
       
   125 //
       
   126 void CalenDayViewWidget::showWidget()
       
   127 {
       
   128     // Get the date for which this view has been launched
       
   129     mDate = mServices.Context().focusDateAndTimeL();
       
   130         
       
   131     // Set the heading text
       
   132     setHeadingText();
       
   133 
       
   134     // Get the instance list
       
   135     getInstanceList();
       
   136     
       
   137     // Check if regional information needs to be shown
       
   138     // and add it or remove it
       
   139     showHideRegionalInformation();
       
   140 
       
   141     // Load the appropriate section based on the number of events for the day
       
   142     if (0 == mInstanceArray.count()) {
       
   143         // There are no entries for the day
       
   144         // Load and show the empty list section
       
   145         bool loadSuccess = false;
       
   146 
       
   147         // Hide the list which shows the events
       
   148         mEventsList->hide();
       
   149 
       
   150         // Show the empty list text
       
   151         mEmptyListLabel->show();
       
   152 
       
   153         // Get the current device orientation
       
   154         int orientation = mServices.MainWindow().orientation();
       
   155         if (Qt::Vertical == orientation) {
       
   156             mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "emptyList", &loadSuccess);
       
   157         } else {
       
   158             mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "emptyLandscape", &loadSuccess);
       
   159         }
       
   160         if (!loadSuccess) {
       
   161             qFatal("calendayviewwidget.cpp : Unable to load empty list section");
       
   162         }
       
   163     } else {
       
   164         // Hide the empty view label
       
   165         mEmptyListLabel->hide();
       
   166 
       
   167         // Show the events list
       
   168         mEventsList->show();
       
   169 
       
   170         // There are one or more events. Load the non-empty section
       
   171         bool loadSuccess = false;
       
   172         mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "nonEmptyList", &loadSuccess);
       
   173         if (!loadSuccess) {
       
   174             qFatal("calendayviewwidget.cpp : Unable to load non-empty list section");
       
   175         }
       
   176         // Now populate the list with the events
       
   177         populateListWidget();
       
   178     }
       
   179 }
       
   180 
       
   181 // ----------------------------------------------------------------------------
       
   182 // CalenDayViewWidget::orientationChanged
       
   183 // Rest of the details are commented in the header
       
   184 // ----------------------------------------------------------------------------
       
   185 //
       
   186 void CalenDayViewWidget::orientationChanged(Qt::Orientation orientation)
       
   187 {
       
   188     // Load the appropriate section based on the number of events for the day
       
   189     if (0 == mInstanceArray.count()) {
       
   190         // There are no entries for the day
       
   191         // Load and show the empty list section
       
   192         bool loadSuccess = false;
       
   193 
       
   194         // Hide the list which shows the events
       
   195         mEventsList->hide();
       
   196 
       
   197         // Show the empty list text
       
   198         mEmptyListLabel->show();
       
   199 
       
   200         if (Qt::Vertical == orientation) {
       
   201             mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "emptyList", &loadSuccess);
       
   202         } else {
       
   203             mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "emptyLandscape", &loadSuccess);
       
   204         }
       
   205         if (!loadSuccess) {
       
   206             qFatal("calendayviewwidget.cpp : Unable to load empty list section");
       
   207         }
       
   208     } else {
       
   209         // Hide the empty view label
       
   210         mEmptyListLabel->hide();
       
   211 
       
   212         // Show the events list
       
   213         mEventsList->show();
       
   214 
       
   215         // There are one or more events. Load the non-empty section
       
   216         bool loadSuccess = false;
       
   217         mDocLoader->load(CALEN_DAYVIEW_XML_FILE, "nonEmptyList", &loadSuccess);
       
   218         if (!loadSuccess) {
       
   219             qFatal("calendayviewwidget.cpp : Unable to load non-empty list section");
       
   220         }
       
   221         handleListItemStretching(orientation);
       
   222     }
       
   223 }
       
   224 
       
   225 // ----------------------------------------------------------------------------
       
   226 // CalenDayViewWidget::handleLocaleChange
       
   227 // Rest of the details are commented in the header
       
   228 // ----------------------------------------------------------------------------
       
   229 //
       
   230 void CalenDayViewWidget::handleLocaleChange()
       
   231 {
       
   232     if(mListViewPrototype) {
       
   233         HbExtendedLocale locale = HbExtendedLocale::system();
       
   234         HbExtendedLocale::TimeStyle timeStyle = locale.timeStyle();
       
   235         if (HbExtendedLocale::Time12 == timeStyle) {
       
   236             mListViewPrototype->setTimeFormat12Hr(true);
       
   237         } else {
       
   238             mListViewPrototype->setTimeFormat12Hr(false);
       
   239         }
       
   240         
       
   241     }
       
   242 }
       
   243 
       
   244 // ----------------------------------------------------------------------------
       
   245 // CalenDayViewWidget::setContextFromHighlight
       
   246 // Rest of the details are commented in the header
       
   247 // ----------------------------------------------------------------------------
       
   248 //    
       
   249 void CalenDayViewWidget::setContextFromHighlight(AgendaEntry entry)
       
   250 {
       
   251     if (entry.isTimedEntry()) {
       
   252         // Timed entry.
       
   253         QDateTime start = entry.startTime();
       
   254         // start.setDate(mDate.date());
       
   255         mServices.Context().setFocusDateAndTimeAndInstanceL(start,
       
   256                                                             TCalenInstanceId::create(entry),
       
   257                                                             KCalenDayViewUidValue);
       
   258     } else {
       
   259         // Untimed entry.
       
   260         if (CalenDateUtils::onSameDay(TCalenInstanceId::create(entry).mInstanceTime,
       
   261                                       mDate)) {
       
   262             mServices.Context().setInstanceIdL(TCalenInstanceId::create(entry),
       
   263                                                KCalenDayViewUidValue);
       
   264         } else {
       
   265             // Multi-day untimed note (either multi-day day note or weird todo).
       
   266             // Focus on the instance and set the focus time to the highlighted day.
       
   267             mServices.Context().setFocusDateAndTimeAndInstanceL(mDate,
       
   268                                                                 TCalenInstanceId::create(entry),
       
   269                                                                 KCalenDayViewUidValue);
       
   270         }
       
   271     }
       
   272 }
       
   273 
       
   274 // ----------------------------------------------------------------------------
       
   275 // CalenDayViewWidget::initChildWidgets
       
   276 // Rest of the details are commented in the header
       
   277 // ----------------------------------------------------------------------------
       
   278 //
       
   279 void CalenDayViewWidget::initChildWidgets()
       
   280 {
       
   281     // Get the pointer to the events list
       
   282     mEventsList = static_cast<HbListView*> (mDocLoader->findWidget(CALEN_DAYVIEW_LISTWIDGET));
       
   283     if (!mEventsList) {
       
   284         qFatal("calendayviewwidget.cpp : Unable to find the events list");
       
   285     }
       
   286     // NOTE: Layout name MUST be same as the name mentioned in the css
       
   287     mEventsList->setLayoutName(customLayout);
       
   288     
       
   289     // TODO : remove this line after gestures are available
       
   290     mEventsList->installEventFilter(mView);
       
   291 
       
   292     // Connect to the long press and activation signals
       
   293     connect(mEventsList, SIGNAL(longPressed(HbAbstractViewItem*, const QPointF&)),
       
   294             this, SLOT(itemLongPressed(HbAbstractViewItem*, const QPointF&)));
       
   295     connect(mEventsList, SIGNAL(activated(const QModelIndex&)), this,
       
   296             SLOT(itemActivated(const QModelIndex&)));
       
   297     
       
   298     // Get the pointer to label from the loader.
       
   299     mHeadingLabel = qobject_cast<HbGroupBox*> (mDocLoader->findWidget(CALEN_DAYVIEW_HEADING));
       
   300     if (!mHeadingLabel) {
       
   301         qFatal("calendayviewwidget.cpp : Unable to find heading widget");
       
   302     }
       
   303     
       
   304     // Get the pointer to the empty view label
       
   305     mEmptyListLabel = qobject_cast<HbLabel*> (mDocLoader->findWidget("noEventsLabel"));
       
   306     if (!mEmptyListLabel) {
       
   307         qFatal("calendayviewwidget.cpp : Unable to find empty list label");
       
   308     }
       
   309     HbWidget *headingPluginWidget = 
       
   310     		qobject_cast<HbWidget*> (mDocLoader->findWidget(CALEN_DAYVIEW_HEADING_REGIONALPLUGIN_WIDGET));
       
   311     
       
   312     mRegionalPluginLayout = static_cast<QGraphicsLinearLayout*>(headingPluginWidget->layout());
       
   313     
       
   314 }
       
   315 
       
   316 // ----------------------------------------------------------------------------
       
   317 // CalenDayViewWidget::populateListWidget
       
   318 // Rest of the details are commented in the header
       
   319 // ----------------------------------------------------------------------------
       
   320 //    
       
   321 void CalenDayViewWidget::populateListWidget()
       
   322 {
       
   323     // Recycle the list items so that only needed rows
       
   324     // are added or removed
       
   325     if (mInstanceArray.count() == 0) {
       
   326         // Reset the list
       
   327         mEventsList->reset();
       
   328         // Clear the model to ensure it does not have any old items
       
   329         mListModel->clear();
       
   330         return;
       
   331     } else if (mInstanceArray.count() > mListModel->rowCount()) {
       
   332         // There are more events than the number of items
       
   333         // in the list. Add more rows
       
   334         mListModel->insertRows(0, mInstanceArray.count() - mListModel->rowCount());
       
   335     } else if (mInstanceArray.count() < mListModel->rowCount()) {
       
   336         // There are less number of events than the number
       
   337         // of items in the list. Remove the extra rows
       
   338         mListModel->removeRows(0, mListModel->rowCount() - mInstanceArray.count());
       
   339     }
       
   340     mListModel->setColumnCount(singleColumn);
       
   341     
       
   342     // Add all the events to the list
       
   343     for (int index = 0; index < mInstanceArray.count(); index++) {
       
   344         // Get each of the entry details
       
   345         AgendaEntry entry = mInstanceArray[index];
       
   346         // Create a list item for each entry
       
   347         createListItem(index, entry);
       
   348     }
       
   349     // Add the item on to the list widget
       
   350     mEventsList->setModel(mListModel, mListViewPrototype);
       
   351     
       
   352     // Now get the item to scroll to
       
   353     int scrollToIndex = getIndexToScrollTo();
       
   354     if (mListModel->rowCount() > 0) {
       
   355         // Scroll to the index only if index is valid
       
   356         mEventsList->scrollTo(mListModel->index(scrollToIndex, 0));
       
   357     }
       
   358 }
       
   359 
       
   360 // ----------------------------------------------------------------------------
       
   361 // CalenDayViewWidget::getInstanceList
       
   362 // Rest of the details are commented in the header
       
   363 // ----------------------------------------------------------------------------
       
   364 //    
       
   365 void CalenDayViewWidget::getInstanceList()
       
   366 {
       
   367     // Clear the previous instance list
       
   368     mInstanceArray.clear();
       
   369     
       
   370     // Check if the date is valid
       
   371     if (!CalenDateUtils::isValidDay(mDate)) {
       
   372         mDate = CalenDateUtils::today();
       
   373     }
       
   374     
       
   375     // Set the filter flags to fetch all relevant entries
       
   376     AgendaUtil::FilterFlags filter = AgendaUtil::FilterFlags(AgendaUtil::IncludeAnniversaries |
       
   377                                                              AgendaUtil::IncludeAppointments | 
       
   378                                                              AgendaUtil::IncludeEvents |
       
   379                                                              AgendaUtil::IncludeReminders |
       
   380                                                              AgendaUtil::IncludeIncompletedTodos);
       
   381     
       
   382     // Fetch the instance list from the agenda interface
       
   383     mInstanceArray = mServices.agendaInterface()->createEntryIdListForDay(mDate, filter);
       
   384     
       
   385     if (0 == mInstanceArray.count()) {
       
   386         // There are no events to populate
       
   387         // Hide the events list
       
   388         mEventsList->hide();
       
   389         // Show the empty list text
       
   390         mEmptyListLabel->show();
       
   391         return;
       
   392     }
       
   393 }
       
   394 
       
   395 // ----------------------------------------------------------------------------
       
   396 // CalenDayViewWidget::setDateToLabel
       
   397 // Rest of the details are commented in the header
       
   398 // ----------------------------------------------------------------------------
       
   399 //
       
   400 void CalenDayViewWidget::setHeadingText()
       
   401     {
       
   402     // Format the date as per the device locale settings
       
   403 	HbExtendedLocale systemLocale = HbExtendedLocale::system();
       
   404 	
       
   405 	// Get localised name of the day from locale
       
   406 	QString dayString = systemLocale.dayName(mDate.date().dayOfWeek());
       
   407 	// Append a single space
       
   408 	dayString.append(singleSpace);
       
   409 	// Set the heading
       
   410 	// Append the date which is formatted as per the locale
       
   411 	mHeadingLabel->setHeading(hbTrId(
       
   412 				"txt_calendar_subhead_1_2").arg(dayString).arg(
       
   413 				systemLocale.format(mDate.date(), r_qtn_date_usual_with_zero)));
       
   414 }
       
   415 
       
   416 // ----------------------------------------------------------------------------
       
   417 // CalenDayViewWidget::createListItem
       
   418 // Rest of the details are commented in the header
       
   419 // ----------------------------------------------------------------------------
       
   420 //
       
   421 void CalenDayViewWidget::createListItem(int index, AgendaEntry entry)
       
   422 {
       
   423     if (index < 0 || entry.isNull()) {
       
   424         // Not a valid index or entry. Dont do anything
       
   425         return;
       
   426     }
       
   427     // Check if the entry is a timed entry
       
   428     // TODO: Right now, only appointment/meeting type is being handled
       
   429     // Handle other timed entry types like reminder etc
       
   430     if (entry.isTimedEntry()) {
       
   431         // Get the text and icon data for the entry
       
   432         addTimedEventToList(index, entry);
       
   433     } else {
       
   434         addNonTimedEventToList(index, entry);
       
   435     }
       
   436 }
       
   437 
       
   438 // ----------------------------------------------------------------------------
       
   439 // CalenDayViewWidget::addTimedEventToList
       
   440 // Rest of the details are commented in the header
       
   441 // ----------------------------------------------------------------------------
       
   442 //
       
   443 void CalenDayViewWidget::addTimedEventToList(int index, AgendaEntry entry)
       
   444 {
       
   445     // Create text and icon list to set to the model
       
   446     QVariantList textData;
       
   447     QVariantList iconData;
       
   448     bool twoLines = false;
       
   449     
       
   450     /**
       
   451      * IMPORTANT NOTE: All the text and icon items must be
       
   452      * inserted into the variant list in a specific order.
       
   453      * If not, chaos will set it!!!
       
   454      * On a more serious note, the mesh layout depends on the
       
   455      * fact that the icons and text data will be added in a
       
   456      * particular order. If one of the items go missing, the
       
   457      * layout might get messed up. Also in case a particular item
       
   458      * is not required to be added in the middle of the list, an
       
   459      * empty QVariant must be added to indicate to the list view
       
   460      * that the item must be removed from the layout.
       
   461      * Do not mess with the order in case you are not sure what
       
   462      * you are exactly doing.
       
   463      */
       
   464     
       
   465     // The first icon to show to-do or all day should not be shown
       
   466     // Append empty data to the icons list
       
   467     iconData << QVariant();
       
   468 
       
   469     // Check if alarm is enabled for the entry       
       
   470     if (entry.alarm().isNull()) {
       
   471         // Insert a blank icon. Else the next icon
       
   472         // will get replaced in this icon's position
       
   473         iconData << QVariant();
       
   474     } else {
       
   475         iconData << HbIcon(reminderIcon);
       
   476     }
       
   477 
       
   478     // Check if the entry is recurring
       
   479     if (entry.isRepeating()) {
       
   480         iconData << HbIcon(repeatIcon);
       
   481     } else if (!entry.recurrenceId().isNull()) {
       
   482         // This is an exceptional entry
       
   483         iconData << HbIcon(exceptionIcon);
       
   484     } else {
       
   485         // Insert a blank icon. Else the next icon
       
   486         // will get replaced in this icon's position
       
   487         iconData << QVariant();
       
   488     }
       
   489 
       
   490     HbExtendedLocale locale = HbExtendedLocale::system();
       
   491 	// Get the start time and format as per the locale
       
   492 	QDateTime startTime = entry.startTime();
       
   493 	QTime eventStartTime;
       
   494 
       
   495 	if (CalenDateUtils::beginningOfDay(startTime)
       
   496 	        < CalenDateUtils::beginningOfDay(mDate)) {
       
   497 		// event is started previous day, show StarTime as 12:00 am in Agendaview, 
       
   498 		eventStartTime.setHMS(00, 00, 00);
       
   499 	} else {
       
   500 		eventStartTime = entry.startTime().time();
       
   501 	}
       
   502     QString eventTime = locale.format(eventStartTime, r_qtn_time_usual_with_zero);
       
   503 
       
   504 	// Get the event end time
       
   505 	QDateTime endTime = entry.endTime();
       
   506 	QTime eventEndTime;
       
   507 
       
   508 	if (CalenDateUtils::beginningOfDay(endTime)
       
   509 	        > CalenDateUtils::beginningOfDay(mDate)) {
       
   510 		// event has MidNight crossover, show EndTime as 11:59pm in Agendaview, 
       
   511 		eventEndTime.setHMS(23, 59, 59);
       
   512 	} else {
       
   513 		eventEndTime = entry.endTime().time();
       
   514 	}
       
   515 
       
   516     if (eventStartTime < eventEndTime) {
       
   517         // Raise the flag to indicate that the list item
       
   518         // would wrap to two lines
       
   519         twoLines = true;
       
   520         // Append '-' to indicate an end time is present
       
   521         eventTime.append("-");
       
   522         // Append new line to wrap to next line
       
   523         eventTime.append(newLine);
       
   524         // Event is a not a zero duration meeting
       
   525         // Only in this case, append the end time
       
   526         eventTime.append(locale.format(eventEndTime, r_qtn_time_usual_with_zero));
       
   527     } else {
       
   528         // Append new line to wrap to next line
       
   529         eventTime.append(newLine);
       
   530     }
       
   531     // Add the event time to the text list
       
   532     // This MUST be the first item to be added to the list 
       
   533     textData << eventTime;
       
   534 
       
   535     // Get the entry subject
       
   536     QString subject = entry.summary();
       
   537     if (subject.isEmpty() || subject.isNull()) {
       
   538         // No subject. Add "(No subject)" text
       
   539         subject.append(hbTrId("txt_calendar_dblist_unnamed"));
       
   540     }
       
   541     // Add the subject to the text list
       
   542     // This MUST be the second item in the list
       
   543     textData << subject;
       
   544 
       
   545     // Check if the entry has location
       
   546     // TODO: This must change to check for geo-location
       
   547     // This MUST be the third item in the list
       
   548     if (entry.location().isEmpty()) {
       
   549         // Insert a blank icon. Else the next icon
       
   550         // will get replaced in this icon's position
       
   551         iconData << QVariant();
       
   552         if (twoLines) {
       
   553             /**
       
   554              * NOTE: If the primary text is wrapping to two
       
   555              * lines, then the location must be set as blank
       
   556              * since the bottom of the list item is anchored to
       
   557              * the bottom of the secondary text. Else the bottom
       
   558              * of the list will overlap on the primary text
       
   559              */
       
   560             textData << singleSpace;
       
   561         } else {
       
   562             /**
       
   563              * Else, set the secondary text to empty to indicate
       
   564              * to the list view to remove the item itself and 
       
   565              * shrink its size to a single line size
       
   566              */
       
   567             textData << QVariant();
       
   568         }
       
   569     } else {
       
   570         // TODO: Location icon must be shown
       
   571         // only if valid geo-coordinates are present
       
   572         // iconData << HbIcon(locationIcon);
       
   573         textData << entry.location();
       
   574     }
       
   575     
       
   576     // Get the list model index and set the text and icon data
       
   577     QModelIndex listIndex = mListModel->index(index, 0);
       
   578     mListModel->setData(listIndex, textData, Qt::DisplayRole);
       
   579     mListModel->setData(listIndex, iconData, Qt::DecorationRole);
       
   580     
       
   581     // Disable item stretching by removing the dynamic property
       
   582     HbListViewItem *listViewItem = static_cast<HbListViewItem*>
       
   583                                         (mEventsList->itemByIndex(mListModel->index(index, 0)));
       
   584     if (listViewItem) {
       
   585         listViewItem->setProperty(stretchLayout, false);
       
   586     }
       
   587 }
       
   588 
       
   589 // ----------------------------------------------------------------------------
       
   590 // CalenDayViewWidget::addNonTimedEventToList
       
   591 // Rest of the details are commented in the header
       
   592 // ----------------------------------------------------------------------------
       
   593 //
       
   594 void CalenDayViewWidget::addNonTimedEventToList(int index, AgendaEntry entry)
       
   595 {
       
   596     QVariantList textData;
       
   597     QVariantList iconData;
       
   598     
       
   599     /**
       
   600      * IMPORTANT NOTE: All the text and icon items must be
       
   601      * inserted into the variant list in a specific order.
       
   602      * If not, chaos will set it!!!
       
   603      * On a more serious note, the mesh layout depends on the
       
   604      * fact that the icons and text data will be added in a
       
   605      * particular order. If one of the items go missing, the
       
   606      * layout might get messed up. Also in case a particular item
       
   607      * is not required to be added in the middle of the list, an
       
   608      * empty QVariant must be added to indicate to the list view
       
   609      * that the item must be removed from the layout.
       
   610      * Do not mess with the order in case you are not sure what
       
   611      * you are exactly doing.
       
   612      */
       
   613     
       
   614     // The first column text has to be empty
       
   615     textData << QVariant();
       
   616     
       
   617     // Get the entry subject
       
   618     QString subject = entry.summary();
       
   619     if (subject.isEmpty() || subject.isNull()) {
       
   620         // No subject. Add "(No subject)" text
       
   621         subject.append(hbTrId("txt_calendar_dblist_unnamed"));
       
   622     }
       
   623     // Add the subject to the text list
       
   624     // This MUST be the second item in the list
       
   625     textData << subject;
       
   626     
       
   627     // Get the entry type
       
   628     AgendaEntry::Type entryType = entry.type();
       
   629         
       
   630     if (entryType == AgendaEntry::TypeAnniversary) {
       
   631         // Nothing to do as of now as anniversary events
       
   632         // cannot be created
       
   633         // TODO: To be handled in case of sync
       
   634     } else if (entryType == AgendaEntry::TypeEvent) {
       
   635         // This is an all day event
       
   636         // Append the all-day icon
       
   637         iconData << HbIcon(allDayIcon);
       
   638         
       
   639         // Check if alarm is enabled for the entry       
       
   640         if (entry.alarm().isNull()) {
       
   641             // Insert a blank icon. Else the next icon
       
   642             // will get replaced in this icon's position
       
   643             iconData << QVariant();
       
   644         } else {
       
   645             iconData << HbIcon(reminderIcon);
       
   646         }
       
   647 
       
   648         // Check if the entry is recurring
       
   649         if (entry.isRepeating()) {
       
   650             iconData << HbIcon(repeatIcon);
       
   651         } else {
       
   652             // Insert a blank icon. Else the next icon
       
   653             // will get replaced in this icon's position
       
   654             iconData << QVariant();
       
   655         }
       
   656         
       
   657         // Append the location
       
   658         if (!entry.location().isEmpty()) {
       
   659             textData << entry.location();
       
   660             // TODO: Location icon must be shown
       
   661             // only if valid geo-coordinates are present
       
   662             // iconData << HbIcon(locationIcon);
       
   663         } else {
       
   664             textData << singleSpace;
       
   665         }
       
   666         
       
   667     } else if (entryType == AgendaEntry::TypeTodo) {
       
   668         // Append the to-do icon
       
   669         iconData << HbIcon(toDoIcon);
       
   670         
       
   671         // Get the due date
       
   672         QDateTime dueDate = entry.endTime();
       
   673         
       
   674         // Append the date first
       
   675         QString dueDateString(hbTrId("txt_calendar_dblist_val_due_on_1"));
       
   676         QString dueText;
       
   677         dueText.setNum(dueDate.date().day());
       
   678         dueText.append(singleSpace);
       
   679         
       
   680         // Append the month name next
       
   681         HbExtendedLocale locale = HbExtendedLocale::system();
       
   682         QString month = locale.monthName(dueDate.date().month());
       
   683         dueText.append(month);
       
   684         dueText.append(singleSpace);
       
   685         
       
   686         // Append the year
       
   687         QString year;
       
   688         year.setNum(dueDate.date().year());
       
   689         dueText.append(year);
       
   690         
       
   691         textData << dueDateString.arg(dueText);
       
   692         
       
   693         // Check if alarm is enabled for the entry       
       
   694         if (entry.alarm().isNull()) {
       
   695             // Insert a blank icon. Else the next icon
       
   696             // will get replaced in this icon's position
       
   697             iconData << QVariant();
       
   698         } else {
       
   699             iconData << HbIcon(reminderIcon);
       
   700         }
       
   701         
       
   702         // Check if the entry is recurring
       
   703         if (entry.isRepeating()) {
       
   704             iconData << HbIcon(repeatIcon);
       
   705         } else {
       
   706             // Insert a blank icon. Else the next icon
       
   707             // will get replaced in this icon's position
       
   708             iconData << QVariant();
       
   709         }
       
   710     }
       
   711     
       
   712     // Get the list model index and set the text and icon data
       
   713     QModelIndex listIndex = mListModel->index(index, 0);
       
   714     mListModel->setData(listIndex, textData, Qt::DisplayRole);
       
   715     mListModel->setData(listIndex, iconData, Qt::DecorationRole);
       
   716     
       
   717     // Enable item stretching by adding the dynamic property
       
   718     HbListViewItem *listViewItem = static_cast<HbListViewItem*>
       
   719                                         (mEventsList->itemByIndex(mListModel->index(index, 0)));
       
   720     Qt::Orientation orientation = mServices.MainWindow().orientation();
       
   721     // Apply stretch only for landscape orientation
       
   722     if (listViewItem) {
       
   723         if (Qt::Horizontal == orientation) {
       
   724             listViewItem->setProperty(stretchLayout, true);
       
   725         } else {
       
   726             listViewItem->setProperty(stretchLayout, false);
       
   727         }
       
   728     }
       
   729 }
       
   730 
       
   731 // ----------------------------------------------------------------------------
       
   732 // CalenDayViewWidget::handleListItemStretching
       
   733 // Rest of the details are commented in the header
       
   734 // ----------------------------------------------------------------------------
       
   735 // 
       
   736 void CalenDayViewWidget::handleListItemStretching(Qt::Orientation orientation)
       
   737 {
       
   738     if (mInstanceArray.count() == 0) {
       
   739         // Nothing much to do. Simply return
       
   740         return;
       
   741     }
       
   742     for(int index = 0; index < mInstanceArray.count() ; index ++) {
       
   743         AgendaEntry entry = mInstanceArray[index];
       
   744         if (!entry.isNull()) {
       
   745             AgendaEntry::Type eventType = entry.type();
       
   746             switch(eventType) {
       
   747                 // Apply the stretching to only to-do's,
       
   748                 // anniversary and all-day event types
       
   749                 case AgendaEntry::TypeTodo:
       
   750                 case AgendaEntry::TypeEvent:
       
   751                 case AgendaEntry::TypeAnniversary:
       
   752                 {
       
   753                     // Get the list view item corresponding to the index
       
   754                     HbListViewItem *listItem = static_cast<HbListViewItem*>
       
   755                                                 (mEventsList->itemByIndex(mListModel->index(index, 0)));
       
   756                     if (listItem) {
       
   757                         if (orientation == Qt::Horizontal) {
       
   758                             // Set a dynamic property to indicate that this list item
       
   759                             // must be stretched in landscape.
       
   760                             // NOTE: Property name MUST match the name specified in
       
   761                             // css file, else wierd things might happen
       
   762                             listItem->setProperty(stretchLayout, true);
       
   763                         }
       
   764                     }
       
   765                 }
       
   766                     break;
       
   767                 default:
       
   768                 {
       
   769                     HbListViewItem *listItem = static_cast<HbListViewItem*>
       
   770                                                 (mEventsList->itemByIndex(mListModel->index(index, 0)));
       
   771                     if (listItem) {
       
   772                         listItem->setProperty(stretchLayout, false);
       
   773                     }
       
   774                     break;
       
   775                 }
       
   776             }
       
   777         }
       
   778     }
       
   779 }
       
   780 
       
   781 // ----------------------------------------------------------------------------
       
   782 // CalenDayViewWidget::getIndexToScrollTo
       
   783 // Rest of the details are commented in the header
       
   784 // ----------------------------------------------------------------------------
       
   785 //  
       
   786 int CalenDayViewWidget::getIndexToScrollTo()
       
   787 {
       
   788     int scrollIndex = 0;
       
   789     TCalenInstanceId instanceId = mServices.Context().instanceId();
       
   790     if (instanceId == TCalenInstanceId::nullInstanceId()) {
       
   791         // If the instance is not set, then scroll to zero index
       
   792         return scrollIndex;
       
   793     }
       
   794     
       
   795     for (int index = 0 ; index < mInstanceArray.count() ; index++) {
       
   796         AgendaEntry entry = mInstanceArray[index];
       
   797         if (entry.id() == instanceId.mEntryLocalUid) {
       
   798             // Match found.
       
   799             scrollIndex = index;
       
   800             break;
       
   801         }
       
   802     }
       
   803     return scrollIndex;
       
   804 }
       
   805 
       
   806 // ----------------------------------------------------------------------------
       
   807 // CalenDayViewWidget::showHideRegionalInformation
       
   808 // To Show and hide regional plugin label depends upon settings
       
   809 // ----------------------------------------------------------------------------
       
   810 //
       
   811 void CalenDayViewWidget::showHideRegionalInformation()
       
   812 {
       
   813     XQSettingsKey regionalInfo(XQSettingsKey::TargetCentralRepository,
       
   814                                KCRUidCalendar.iUid, KShowRegionalInformation);
       
   815     
       
   816     int showRegionalInfo = mSettingsManager->readItemValue(regionalInfo).toUInt();
       
   817     if (showRegionalInfo) {
       
   818 		
       
   819         if (!mRegionalInfoGroupBox) {
       
   820         	mRegionalInfoGroupBox = new HbGroupBox();
       
   821         	CalenPluginLabel *regionalInfo = new CalenPluginLabel(
       
   822 															mServices, this);
       
   823             mRegionalInfoGroupBox->setContentWidget(regionalInfo);
       
   824             mRegionalPluginLayout->insertItem(1, mRegionalInfoGroupBox);
       
   825         }
       
   826         
       
   827         if (mView->pluginEnabled()) {
       
   828 			QString *pluginString = mView->pluginText();
       
   829 			HbLabel *pluginInfoLabel = qobject_cast <HbLabel *> 
       
   830 									(mRegionalInfoGroupBox->contentWidget());
       
   831 			pluginInfoLabel->setPlainText(*pluginString);
       
   832 		}
       
   833     } else {
       
   834         if (mRegionalInfoGroupBox) {
       
   835         	mRegionalPluginLayout->removeItem(mRegionalInfoGroupBox);
       
   836             delete mRegionalInfoGroupBox;
       
   837             mRegionalInfoGroupBox = NULL;
       
   838         }
       
   839     }
       
   840 }
       
   841 
       
   842 // ----------------------------------------------------------------------------
       
   843 // CalenDayViewWidget::createNewEvent
       
   844 // Rest of the details are commented in the header
       
   845 // ----------------------------------------------------------------------------
       
   846 //    
       
   847 void CalenDayViewWidget::createNewEvent()
       
   848 {
       
   849     // Issue a command to launch editor to create
       
   850     // a new event
       
   851 	mServices.IssueCommandL(ECalenNewMeeting);
       
   852 }
       
   853 
       
   854 // ----------------------------------------------------------------------------
       
   855 // CalenDayViewWidget::editEntry
       
   856 // Rest of the details are commented in the header
       
   857 // ----------------------------------------------------------------------------
       
   858 //    
       
   859 void CalenDayViewWidget::editEntry()
       
   860 {
       
   861     // Check if the selected index is valid
       
   862     if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) {
       
   863         return;
       
   864     }
       
   865     
       
   866     // Get the entry details first
       
   867     AgendaEntry entry = mInstanceArray[mSelectedIndex];
       
   868     if (AgendaEntry::TypeTodo == entry.type()) {
       
   869         // Launch the to-do editor
       
   870         mNotesEditor = new NotesEditor(mView);
       
   871         mNotesEditor->edit(entry);
       
   872         connect(mNotesEditor, SIGNAL(editingCompleted(bool)), this, SLOT(noteEditingCompleted(bool)));
       
   873     } else {
       
   874         // Set the context
       
   875         setContextFromHighlight(entry);
       
   876         // Issue a command to launch the editor to edit this entry
       
   877         mServices.IssueCommandL(ECalenEditCurrentEntry);
       
   878     }
       
   879 }
       
   880 
       
   881 // ----------------------------------------------------------------------------
       
   882 // CalenDayViewWidget::viewEntry
       
   883 // Rest of the details are commented in the header
       
   884 // ----------------------------------------------------------------------------
       
   885 //    
       
   886 void CalenDayViewWidget::viewEntry()
       
   887 {
       
   888     // Get the entry details first
       
   889     AgendaEntry entry = mInstanceArray[mSelectedIndex];
       
   890     
       
   891     // Set the context
       
   892     setContextFromHighlight(entry);
       
   893         
       
   894     // Launch the event viewer.
       
   895     mServices.IssueCommandL(ECalenEventView);
       
   896 }
       
   897 
       
   898 
       
   899 // ----------------------------------------------------------------------------
       
   900 // CalenDayViewWidget::deleteEntry
       
   901 // Rest of the details are commented in the header
       
   902 // ----------------------------------------------------------------------------
       
   903 //    
       
   904 void CalenDayViewWidget::deleteEntry()
       
   905 {
       
   906     // Check if the selected index is valid
       
   907 	if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) {
       
   908 		return;
       
   909 	}
       
   910 	
       
   911 	// Get the entry details
       
   912 	AgendaEntry entry = mInstanceArray[mSelectedIndex];
       
   913 	// Set the context
       
   914 	setContextFromHighlight(entry);
       
   915 	// Issue the command to delete the entry
       
   916 	mServices.IssueCommandL(ECalenDeleteCurrentEntry);
       
   917 }
       
   918 
       
   919 // ----------------------------------------------------------------------------
       
   920 // CalenDayViewWidget::markAsDone
       
   921 // Rest of the details are commented in the header
       
   922 // ----------------------------------------------------------------------------
       
   923 //  
       
   924 void CalenDayViewWidget::markAsDone()
       
   925 {
       
   926     // Check if the selected index is valid
       
   927     if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) {
       
   928         return;
       
   929     }
       
   930     
       
   931     // Get the entry details
       
   932     AgendaEntry entry = mInstanceArray[mSelectedIndex];
       
   933     
       
   934     // Check again if the event is of type to-to
       
   935     if (AgendaEntry::TypeTodo == entry.type()) {
       
   936         // Set the status of the to-do as completed
       
   937         entry.setStatus(AgendaEntry::TodoCompleted);
       
   938         // Update the completed date and time
       
   939         entry.setCompletedDateTime(mDate);
       
   940         
       
   941         // Update the entry in the database
       
   942         AgendaUtil agendaUtil;
       
   943         agendaUtil.setCompleted(entry, true, mDate);
       
   944 
       
   945 		mServices.IssueCommandL(ECalenStartActiveStep);
       
   946     }
       
   947 }
       
   948 
       
   949 // ----------------------------------------------------------------------------
       
   950 // CalenDayViewWidget::itemLongPressed
       
   951 // Rest of the details are commented in the header
       
   952 // ----------------------------------------------------------------------------
       
   953 //    
       
   954 void CalenDayViewWidget::itemLongPressed(HbAbstractViewItem* listViewItem,
       
   955                                          const QPointF& coords)
       
   956 {
       
   957     // Update the selection index first
       
   958     mSelectedIndex = listViewItem->modelIndex().row();
       
   959     
       
   960     if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) {
       
   961         // Invalid index
       
   962         return;
       
   963     }
       
   964 
       
   965     AgendaEntry entry = mInstanceArray[mSelectedIndex];
       
   966     
       
   967     // Create new menu.
       
   968     HbMenu *contextMenu = new HbMenu();
       
   969     
       
   970     // Add the open option
       
   971     HbAction *openAction = contextMenu->addAction(hbTrId("txt_common_menu_open"));
       
   972     connect(openAction, SIGNAL(triggered()), this, SLOT(viewEntry()));
       
   973     
       
   974     // Check the type of event
       
   975     if (AgendaEntry::TypeTodo == entry.type()) {
       
   976         // Add an option to mark the note as complete
       
   977         HbAction *completeAction = contextMenu->addAction(hbTrId("txt_calendar_menu_mark_as_done"));
       
   978         connect(completeAction, SIGNAL(triggered()), this, SLOT(markAsDone()));
       
   979     }
       
   980     
       
   981     // Add the edit option
       
   982     HbAction *editAction = contextMenu->addAction(hbTrId("txt_common_menu_edit"));
       
   983     connect(editAction, SIGNAL(triggered()), this, SLOT(editEntry()));
       
   984     
       
   985     // Add the delete option
       
   986     HbAction *deleteAction = contextMenu->addAction(hbTrId("txt_common_menu_delete"));
       
   987     connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteEntry()));
       
   988     
       
   989     contextMenu->setDismissPolicy(HbMenu::TapAnywhere);
       
   990 
       
   991     // Show context sensitive menu. 
       
   992     // Param const QPointF& coordinate - is a longpress position.
       
   993     contextMenu->exec(coords);
       
   994 }
       
   995 
       
   996 // ----------------------------------------------------------------------------
       
   997 // CalenDayViewWidget::itemActivated
       
   998 // Rest of the details are commented in the header
       
   999 // ----------------------------------------------------------------------------
       
  1000 //    
       
  1001 void CalenDayViewWidget::itemActivated(const QModelIndex &index)
       
  1002 {
       
  1003     // Update the selection index first
       
  1004     mSelectedIndex = index.row();
       
  1005 
       
  1006     // Check if the selected index is valid
       
  1007     if (mSelectedIndex < 0 || mSelectedIndex > mInstanceArray.count()) {
       
  1008         return;
       
  1009     }
       
  1010     
       
  1011     // Open the event for viewing
       
  1012     viewEntry();
       
  1013 }
       
  1014 
       
  1015 // ----------------------------------------------------------------------------
       
  1016 // CalenDayViewWidget::itemActivated
       
  1017 // Rest of the details are commented in the header
       
  1018 // ----------------------------------------------------------------------------
       
  1019 // 
       
  1020 void CalenDayViewWidget::noteEditingCompleted(bool status)
       
  1021 {
       
  1022     Q_UNUSED(status);
       
  1023     // Delete the notes editor instance
       
  1024     mNotesEditor->deleteLater();
       
  1025     
       
  1026     // We need to refresh the list since user
       
  1027     // might have marked the to-do as complete or
       
  1028     // edited it or deleted it. So get the instance
       
  1029     // list again
       
  1030     if (status) {
       
  1031         mServices.IssueCommandL(ECalenStartActiveStep);
       
  1032     }
       
  1033 }
       
  1034 
       
  1035 // ----------------------------------------------------------------------------
       
  1036 // CalenDayViewWidget::goToToday
       
  1037 // Rest of the details are commented in the header
       
  1038 // ----------------------------------------------------------------------------
       
  1039 // 
       
  1040 void CalenDayViewWidget::goToToday()
       
  1041 {
       
  1042     // First check if we are not already
       
  1043     // showing today's agenda
       
  1044     if (mDate == CalenDateUtils::today()) {
       
  1045         return;
       
  1046     }
       
  1047     
       
  1048     // Set the context for the current day
       
  1049     mServices.Context().setFocusDateL(CalenDateUtils::today(), KCalenDayViewUidValue);
       
  1050     
       
  1051     mView->refreshViewOnGoToDate();
       
  1052 }
       
  1053 
       
  1054 // End of file	--Don't remove this.