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