Bug 2939: Correct initialisation of VA_LIST.
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Definition file for class CalenMonthGrid.
*
*/
// System includes
#include <hbgridview.h>
#include <hbabstractviewitem.h>
#include <hbstyleloader.h>
#include <hbcolorscheme.h>
// User includes
#include "calenmonthgrid.h"
#include "calengriditemprototype.h"
#include "calenmonthdata.h"
#include "calenmonthview.h"
#include "calendateutils.h"
#include "calencommon.h"
// Constants
#define SCROLL_SPEEED 2000
#define GRIDLINE_WIDTH 0.075 //units
/*!
\class CalenMonthGrid
Implements the month grid
*/
/*!
Default constructor.
*/
CalenMonthGrid::CalenMonthGrid(QGraphicsItem *parent):
HbGridView(parent),
mModel(0),
mDirection(invalid),
mIsPanGesture(false),
mIsAtomicScroll(true),
mView(NULL),
mCurrentRow(0),
mIsNonActiveDayFocused(false),
mIgnoreItemActivated(false),
mGridBorderColor(Qt::gray)
{
setScrollDirections(Qt::Vertical);
setRowCount(KNumOfVisibleRows);
setColumnCount(KCalenDaysInWeek);
setLongPressEnabled(false);
setItemRecycling(false);
setSelectionMode(HbGridView::NoSelection);
setUniformItemSizes(true);
setVerticalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff);
setClampingStyle(HbScrollArea::StrictClamping);
setEnabledAnimations(HbAbstractItemView::None);
resetTransform();
// Get the content widget of the scroll area to draw the grid lines
mContentWidget = contentWidget();
// Get the all required colors
// Color of the grid lines
mGridLineColor = HbColorScheme::color("qtc_cal_grid_line");
// Get the localised dates well before
// TODO: Need to update the mLocalisedDates when user changes the
// phone language keeping calendar application in background
HbExtendedLocale locale = HbExtendedLocale::system();
for (int i = 1; i <= 31; i++) {
mLocalisedDates.append(locale.toString(i));
}
// Connect to scrolling finished signal
connect(this, SIGNAL(scrollingEnded()), this,
SLOT(scrollingFinished()));
// Connect to item activated signal
connect(this, SIGNAL(activated(const QModelIndex &)), this,
SLOT(itemActivated(const QModelIndex &)));
}
/*!
Destructor
*/
CalenMonthGrid::~CalenMonthGrid()
{
// Nothing Yet
}
/*!
Stores the view pointer
*/
void CalenMonthGrid::setView(CalenMonthView *view)
{
mView = view;
}
/*!
Updates the model with the proper dates and sets the required user roles
*/
void CalenMonthGrid::updateMonthGridModel(QList<CalenMonthData> &monthDataArray,
int indexToBeScrolled, bool isFirstTime)
{
int loopStart = 0;
int loopEnd = monthDataArray.count();
if (isFirstTime) {
// Create the model with only 42 items as visible to the user
mModel = new QStandardItemModel(KCalenDaysInWeek * KNumOfVisibleRows,
1, this);
loopStart = (mView->rowsInPrevMonth()) * KCalenDaysInWeek;
loopEnd = loopStart + (KCalenDaysInWeek * KNumOfVisibleRows);
} else {
// Block the signals generated by model, this is being done as
// we want to avoid the overload of view listening to signals
mModel->blockSignals(true);
// Check the counts
int dataCount = monthDataArray.count();
int rowCount = mModel->rowCount();
int countDiff = dataCount - rowCount;
if (countDiff < 0) {
// Delete extra rows in the model
mModel->removeRows(dataCount,abs(countDiff));
} else if (countDiff > 0) {
// Add the necessary number of rows
mModel->insertRows(rowCount,countDiff);
}
loopEnd = dataCount;
}
QDateTime currDate = mView->getCurrentDay();
QDateTime currDateTime = CalenDateUtils::beginningOfDay(currDate);
QDateTime activeDay = mView->getActiveDay();
QDateTime activeDateTime = CalenDateUtils::beginningOfDay(activeDay);
QModelIndex currentIndex;
int modelIndex = 0;
for (int i = loopStart; i < loopEnd; i++) {
QDateTime dateTime = monthDataArray[i].Day();
currentIndex = mModel->index(modelIndex++, 0);
// Create the variant list to contain the date to depict a grid item
QVariantList itemData;
// !!!NOTE!!!: Add the data in the order mentioned in the
// CalendarNamespace::DataRole enum. Dont change the order.
itemData << mLocalisedDates.at(dateTime.date().day()-1);
// Check for active day
if (activeDateTime == CalenDateUtils::beginningOfDay(dateTime)) {
mCurrentRow = i;
// Set the focus attribute to true
itemData << true;
} else {
// reset the highlight
itemData << false;
}
// Check for current day
if (currDateTime == CalenDateUtils::beginningOfDay(dateTime)) {
// Set the underline attribute to true
itemData << true;
} else {
itemData << false;
}
// Check for events
if (monthDataArray[i].HasEvents()) {
// Set the event indicator attribute
itemData << true;
} else {
itemData << false;
}
// Add default text color
if (monthDataArray[i].isActive()) {
itemData << true;
} else {
itemData << false;
}
mModel->itemFromIndex(currentIndex)->setData(itemData);
}
if (isFirstTime) {
// Color of the today indicator
QColor todayIndColor = HbColorScheme::color("qtc_cal_month_current_day");
// Color of the active dates
QColor mActiveTextColor =
HbColorScheme::color("qtc_cal_month_active_dates");
// Color of the inactive dates
QColor mInActiveTextColor =
HbColorScheme::color("qtc_cal_month_notactive_dates");
// Create the prototype
CalenGridItemPrototype* gridItemPrototype = new CalenGridItemPrototype(
todayIndColor, mActiveTextColor, mInActiveTextColor, this);
// Set the mode and the prototype
setModel(mModel,gridItemPrototype);
// Register the widgetml and css files
HbStyleLoader::registerFilePath(":/");
// Set the layout name
setLayoutName("calendarCustomGridItem");
} else {
// Since, we have finished setData, Now unblock the signals
mModel->blockSignals(false);
// Since till now, we had blocked signals being generated frm the mode
// view will be unaware of the items that we added. Hence, inform the view
// explicitly in one shot
QModelIndex leftIndex = mModel->index(0, 0);
QModelIndex rightIndex = mModel->index(loopEnd-1, 0);
dataChanged(leftIndex, rightIndex);
// NOTE: To make sure that we always display proper month,
// two calls have been made to scrollTo(), one with top
// visible item and other with bottom visible item
// Calculate the first visible item in the grid
QModelIndex firstVisibleIndex = mModel->index(indexToBeScrolled -
(KNumOfVisibleRows * KCalenDaysInWeek - 1), 0);
scrollTo(firstVisibleIndex);
// Calculate the last visible item in the grid
QModelIndex lastVisibleIndex = mModel->index(indexToBeScrolled, 0);
scrollTo(lastVisibleIndex);
}
mMonthDataArray = monthDataArray;
}
/*!
Updates the view with jprevious month dates when calendar is opened for the
first time to improve the opening time
*/
void CalenMonthGrid::updateMonthGridWithInActiveMonths(
QList<CalenMonthData> &monthDataArray)
{
mMonthDataArray = monthDataArray;
// Prepend the required rows
handlePrependingRows(monthDataArray);
// Append the required rows
handleAppendingRows(monthDataArray);
int rowsInPrevMonth = mView->rowsInPrevMonth();
// Calculate the proper index to be scrolled to
int itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek;
QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
mIsAtomicScroll = true;
scrollTo(indexToBeScrolled);
// Scroll to proper index
itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) *
KCalenDaysInWeek) - 1;
indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
mIsAtomicScroll = true;
scrollTo(indexToBeScrolled);
}
/*!
Updates the view with just event indicators
*/
void CalenMonthGrid::updateMonthGridWithEventIndicators(
QList<CalenMonthData> &monthDataArray)
{
mMonthDataArray = monthDataArray;
for(int i = 0; i < monthDataArray.count(); i++) {
// Check if the day has events
if (monthDataArray[i].HasEvents()) {
QModelIndex itemIndex = mModel->index(i,0);
QVariant itemData = itemIndex.data(Qt::UserRole + 1);
QVariantList list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthEventRole, true);
mModel->itemFromIndex(itemIndex)->setData(list);
}
}
}
/*!
Listens for down gesture
*/
void CalenMonthGrid::downGesture (int value)
{
Q_UNUSED(value)
mDirection = down;
mIsAtomicScroll = false;
setAttribute(Hb::InteractionDisabled);
// pass it to parent
HbScrollArea::downGesture(value);
}
/*!
Listens for Up gesture
*/
void CalenMonthGrid::upGesture (int value)
{
Q_UNUSED(value)
mDirection = up;
mIsAtomicScroll = false;
setAttribute(Hb::InteractionDisabled);
// pass it to parent
HbScrollArea::upGesture(value);
}
/*!
Function to listen mouse press events
*/
void CalenMonthGrid::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
mPressedPos = event->pos();
// Pass it to parent
HbGridView::mousePressEvent(event);
}
/*!
Function to listen mouse release events
*/
void CalenMonthGrid::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
int posDiff = mPressedPos.y() - event->pos().y();
if (posDiff < -50) {
mDirection = down;
} else if (posDiff > 50){
mDirection = up;
}
// Pass it to parent
HbGridView::mouseReleaseEvent(event);
}
/*!
Listens for pan gesture
*/
void CalenMonthGrid::panGesture(const QPointF & delta)
{
setAttribute(Hb::InteractionDisabled);
mIsAtomicScroll = false;
if (!mIsPanGesture) {
mIsPanGesture = true;
mIgnoreItemActivated = true;
mStartPos = mContentWidget->pos();
// Get to know the direction of the gesture
if (delta.y() > 0) {
mDirection = down;
} else {
mDirection = up;
}
}
// Call the parent class to perform the pan gesture
// When scrolling finished, month grid will adjust to show the proper month
HbScrollArea::panGesture(delta);
}
/*!
Gets called when scrolling finishes to update the model
*/
void CalenMonthGrid::scrollingFinished()
{
if (mIsPanGesture) {
handlePanGestureFinished();
} else if(!mIsAtomicScroll) {
QDateTime activeDate = mView->getActiveDay();
if(mDirection == down) { // down gesture
if (!mIsNonActiveDayFocused) {
setActiveDates(activeDate.addMonths(-1).date());
}
prependRows();
} else if (mDirection == up) { //up gesture
if (!mIsNonActiveDayFocused) {
setActiveDates(activeDate.addMonths(1).date());
}
appendRows();
}
mDirection = invalid;
} else {
mIsAtomicScroll = false;
}
mIgnoreItemActivated = false;
setAttribute(Hb::InteractionDisabled, false);
}
/*!
Function to handle completion of pan gesture
*/
void CalenMonthGrid::handlePanGestureFinished()
{
mIsPanGesture = false;
// Get the first item that is visible
QList<HbAbstractViewItem *> list = visibleItems();
HbAbstractViewItem* item = list[0];
QModelIndex modelIndex = item->modelIndex();
// Get the date which is visible at the above row
QDateTime date = mMonthDataArray[modelIndex.row()].Day();
// Check if this date belong to current active month or
// previous month else future month
QDateTime activeMonth = mView->getActiveDay();
QDateTime prevMonth = activeMonth.addMonths(-1);
QDateTime nextMonth = activeMonth.addMonths(1);
int month = date.date().month();
if (month == activeMonth.date().month()) {
// Then pan is completed on current month
// Check if the date is more than half of the current month or it is
// more than or equal to half of the future month
if (date.date().day() > (activeMonth.date().daysInMonth()) / 2 ||
date.addDays(KNumOfVisibleRows*KCalenDaysInWeek).date().day() >=
(prevMonth.date().daysInMonth()) / 2) {
// up gesture to bring the next month
upGesture(SCROLL_SPEEED);
} else {
// we should again show the current month by scrolling downwards
mDirection = down;
mIsAtomicScroll = true;
scrollContentsTo(-mStartPos,500);
}
} else if (month == prevMonth.date().month()) {
// first visible item belongs to previous month
// Check if the date is more than half of the previous month
if (date.date().day() > (prevMonth.date().daysInMonth()) / 2) {
// we should again show the current month by scrolling upwards
mDirection = up;
mIsAtomicScroll = true;
scrollContentsTo(-mStartPos,500);
} else {
// down gesture to show the previous month
downGesture(SCROLL_SPEEED);
}
} else if (month == nextMonth.date().month()) {
// first visible item belongs to next month
// Check if the date is more than half of the next month
if (date.date().day() > (nextMonth.date().daysInMonth()) / 2) {
// up gesture to bring the next month
upGesture(SCROLL_SPEEED);
} else {
// we should again show the current month by scrolling upwards
mDirection = invalid;
scrollContentsTo(-mStartPos,500);
}
}
}
/*!
Called when down gesture is performed. Adds the new previous month details
to the model
*/
void CalenMonthGrid::prependRows()
{
// Before we do anything, set the focus to proper date
// Set it only when non active day was focussed. When inactive day
// was focussed, we need to focus the same day
if (!mIsNonActiveDayFocused) {
setFocusToProperDay();
}
// Block the signals generated by model, this is being done as
// we want to avoid the overload of view listening to signals
mModel->blockSignals(true);
mIsNonActiveDayFocused = false;
int rowsInFutMonthEarlier = mView->rowsInFutMonth();
int rowsInPrevMonthEarlier = mView->rowsInPrevMonth();
// remove the cells in the future month
int deleteFromIndex = (rowsInPrevMonthEarlier + KNumOfVisibleRows) * KCalenDaysInWeek;
int numOfIndices = rowsInFutMonthEarlier * KCalenDaysInWeek;
// Get the updated dates from the view
mView->updateModelWithPrevMonth();
QList<CalenMonthData > monthDataList = mView->monthDataList();
mMonthDataArray = monthDataList;
// Prepend the required rows
handlePrependingRows(monthDataList);
// Since, we have finished setData, Now unblock the signals
mModel->blockSignals(false);
int rowsInPrevMonth = mView->rowsInPrevMonth();
int countToBeAdded = rowsInPrevMonth * KCalenDaysInWeek;
// Since till now, we had blocked signals being generated frm the model
// view will be unaware of the items that we added. Hence, inform the view
// explicitly in one shot
QModelIndex leftIndex = mModel->index(0, 0);
QModelIndex rightIndex = mModel->index(countToBeAdded-1, 0);
dataChanged(leftIndex, rightIndex);
// Now remove the necessary items frm the model
mModel->removeRows(deleteFromIndex+countToBeAdded, numOfIndices);
mIsAtomicScroll = true;
int itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek;
QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
scrollTo(indexToBeScrolled);
// Scroll to proper index
itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) *
KCalenDaysInWeek) - 1;
indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
mIsAtomicScroll = true;
scrollTo(indexToBeScrolled);
// Update the mCurrentRow
mCurrentRow += countToBeAdded;
}
/*!
Helper function that prepends the required rows to the model
*/
void CalenMonthGrid::handlePrependingRows(QList<CalenMonthData > &monthDataList)
{
QDateTime currDate = mView->getCurrentDay();
QDateTime currDateTime = CalenDateUtils::beginningOfDay( currDate );
int rowsInPrevMonth = mView->rowsInPrevMonth();
// Add the new days
int countToBeAdded = rowsInPrevMonth * KCalenDaysInWeek;
mModel->insertRows(0, countToBeAdded);
for (int i = 0; i < countToBeAdded; i++) {
QDateTime dateTime = monthDataList[i].Day();
// Get the localised string for the day
QModelIndex currentIndex = mModel->index(i, 0);
// Create the variant list to contain the date to depict a grid item
QVariantList itemData;
// NOTE: Add the data in the order mentioned in the
// CalendarNamespace::DataRole enum. Dont change the order.
itemData << mLocalisedDates.at(dateTime.date().day()-1);;
// Disable the focus role
itemData << false;
// Check for current day
if (currDateTime == CalenDateUtils::beginningOfDay( dateTime )) {
// Set the underline icon attribute
itemData << true;
} else {
itemData << false;
}
// Update the event indicators
if (monthDataList[i].HasEvents()) {
// Set the event indicator attribute
itemData << true;
} else {
itemData << false;
}
// Add default text color
itemData << false;
// Set the data to model
mModel->itemFromIndex(currentIndex)->setData(itemData);
}
}
/*!
Called when Up gwsture is performed. Adds the new future month details
to the model
*/
void CalenMonthGrid::appendRows()
{
// Before we do anything, set the focus to proper date
// Set it only when non active day was focussed. When inactive day
// was focussed, we need to focus the same day
if (!mIsNonActiveDayFocused) {
setFocusToProperDay();
}
// Block the signals generated by model, this is being done as
// we want to avoid the overload of view listening to signals
mModel->blockSignals(true);
mIsNonActiveDayFocused = false;
int rowsInFutMonth = mView->rowsInFutMonth();
int rowsInPrevMonth = mView->rowsInPrevMonth();
// remove the cells in the previous month
int countToBeDeleted = rowsInPrevMonth * KCalenDaysInWeek;
// Get the updated dates from the view
mView->updateModelWithFutureMonth();
QList<CalenMonthData > monthDataList = mView->monthDataList();
mMonthDataArray = monthDataList;
// Get the model count before we add any rows into the mode
int rowCount = mModel->rowCount();
// Append the required rows
handleAppendingRows(monthDataList);
// Since, we have finished setData, Now unblock the signals
mModel->blockSignals(false);
// Since till now, we had blocked signals being generated frm the mode
// view will be unaware of the items that we added. Hence, inform the view
// explicitly in one shot
QModelIndex leftIndex = mModel->index(rowCount-1, 0);
QModelIndex rightIndex = mModel->index(mModel->rowCount()-1, 0);
dataChanged(leftIndex, rightIndex);
// Update the mCurrentRow
mCurrentRow -= (countToBeDeleted);
for (int i = 0; i < countToBeDeleted; i++) {
mModel->removeRow(0);
}
mIsAtomicScroll = true;
rowsInFutMonth = mView->rowsInFutMonth();
rowsInPrevMonth = mView->rowsInPrevMonth();
// Calculate the proper index to be scrolled to
int itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek;
QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
scrollTo(indexToBeScrolled);
itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) *
KCalenDaysInWeek) - 1;
indexToBeScrolled = mModel->index(itemToBeScrolled, 0);
mIsAtomicScroll = true;
scrollTo(indexToBeScrolled);
}
/*!
Helper function that appends the required rows to the model
*/
void CalenMonthGrid::handleAppendingRows(QList<CalenMonthData > &monthDataList)
{
QDateTime currDate = mView->getCurrentDay();
QDateTime currDateTime = CalenDateUtils::beginningOfDay( currDate );
int rowsInFutMonth = mView->rowsInFutMonth();
int countToBeAdded = rowsInFutMonth * KCalenDaysInWeek;
int lastVisibleIndex = monthDataList.count() - countToBeAdded;
int rowCount = mModel->rowCount();
mModel->insertRows(rowCount, countToBeAdded);
for (int i = 0; i < countToBeAdded; i++) {
QModelIndex currentIndex = mModel->index(rowCount + i, 0);
QDateTime dateTime = monthDataList[lastVisibleIndex + i].Day();
// Create the variant list to contain the date to depict a grid item
QVariantList itemData;
// NOTE: Add the data in the order mentioned in the
// CalendarNamespace::DataRole enum. Dont change the order.
itemData << mLocalisedDates.at(dateTime.date().day()-1);;
// Disable the focus role
itemData << false;
// Check for current day
if (currDateTime == CalenDateUtils::beginningOfDay( dateTime )) {
// Set the underline icon attribute
itemData << true;
} else {
itemData << false;
}
// Update the event indicators
if (monthDataList[lastVisibleIndex + i].HasEvents()) {
// Set the event indicator attribute
itemData << true;
} else {
itemData << false;
}
// Add default text color
itemData << false;
// Set the data to model
mModel->itemFromIndex(currentIndex)->setData(itemData);
}
}
/*!
Slot to handle when a particular grid item is tapped
*/
void CalenMonthGrid::itemActivated(const QModelIndex &index)
{
if (mIgnoreItemActivated) {
mIgnoreItemActivated = false;
return;
}
mIsNonActiveDayFocused = false;
// Check if the same item has been tapped twice
if (mCurrentRow == index.row()) {
// Launch the agenda view
mView->launchDayView();
} else {
// Reset the focus attribute to this item
QModelIndex itemIndex = mModel->index(mCurrentRow,0);
QVariant itemData = itemIndex.data(Qt::UserRole + 1);
QVariantList list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthFocusRole, false);
mModel->itemFromIndex(itemIndex)->setData(list);
// Inform view to update the context and preview panes
mCurrentRow = index.row();
itemIndex = mModel->index(mCurrentRow,0);
itemData = itemIndex.data(Qt::UserRole + 1);
list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthFocusRole,
true);
mModel->itemFromIndex(itemIndex)->setData(list);
// Check if inactive date is tapped
QDateTime activeMonth = mView->getActiveDay();
int month = activeMonth.date().month();
if(month != mMonthDataArray[mCurrentRow].Day().date().month()){
// Set the flag
mIsNonActiveDayFocused = true;
mNonActiveFocusedDay = mMonthDataArray[mCurrentRow].Day();
// Add one month to active month
activeMonth = activeMonth.addMonths(1);
if (activeMonth.date().month() ==
mNonActiveFocusedDay.date().month()) {
mDirection = up;
// up gesture
upGesture(SCROLL_SPEEED);
setActiveDates(activeMonth.date());
} else {
mDirection = down;
// down gesture
downGesture(SCROLL_SPEEED);
setActiveDates(activeMonth.addMonths(-2).date());
}
}
mView->setContextForActiveDay(index.row());
}
}
/*!
Sets the focus to proper day after the flick scrollng
*/
void CalenMonthGrid::setFocusToProperDay()
{
// Calculate the new item to be focussed
QDateTime oldFocussedDate = mView->getActiveDay();
QList<CalenMonthData> monthDataList = mView->monthDataList();
int listCount = monthDataList.count();
int rowsInPrevMonth = mView->rowsInPrevMonth();
QDateTime dateToBeFocussed;
int indexStart = 0;
int indexEnd = listCount - 1;
if (mDirection == up) {
dateToBeFocussed = oldFocussedDate.addMonths(1); // add the month
indexStart = (rowsInPrevMonth + 4) * KCalenDaysInWeek;
} else if (mDirection == down) {
dateToBeFocussed = oldFocussedDate.addMonths(-1); // substract the month
indexEnd = (rowsInPrevMonth + 1) * KCalenDaysInWeek;
}
// Reset the focus attribute to earlier current item
QModelIndex index = mModel->index(mCurrentRow,0);
QVariant itemData = index.data(Qt::UserRole + 1);
QVariantList list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthFocusRole, false);
mModel->itemFromIndex(index)->setData(list);
// Search for this date in the model
for (int i = indexStart; i <= indexEnd; i++) {
if (monthDataList[i].Day().date() == dateToBeFocussed.date()) {
index = mModel->index(i,0);
itemData = index.data(Qt::UserRole + 1);
list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthFocusRole,
true);
mModel->itemFromIndex(index)->setData(list);
mCurrentRow = i;
mView->setContextForActiveDay(i);
break;
}
}
}
/*!
Sets the appropriate text color depending upon the active dates
*/
void CalenMonthGrid::setActiveDates(QDate activeDate)
{
// By default, text color will be set as inactive date color
// set active date color only for the dates that fall in current month
// So, in the whole data array, start from where the current month starts
// and stop the loop where it the current month ends
int start = 0;
int end = mMonthDataArray.count();
// Calculate the start and end values
QDate firstDateInGrid = mView->firstDayOfGrid().date();
// Get the date where active month starts
QDate startOfActiveMonth(activeDate.year(), activeDate.month(),1);
// Number of days frm start of the grid to start of the month
start = firstDateInGrid.daysTo(startOfActiveMonth);
// Get the date where active month ends
QDate endOfActiveMonth = startOfActiveMonth.addDays(
activeDate.daysInMonth());
// Number of days frm start of the grid to end of the month
end = firstDateInGrid.daysTo(endOfActiveMonth);
// Set the active text color
for (int i = start; i < end; i++) {
QModelIndex index = mModel->index(i,0);
QVariant itemData = index.data(Qt::UserRole + 1);
QVariantList list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthTextColorRole, true);
mModel->itemFromIndex(index)->setData(list);
}
// Now set the inactive text color to those which were active before the swipe
if (mDirection == invalid) {
// no need to do anything as other dates will be in inactive dates color
return;
}
if (mDirection == up) {
// Came here as user did up gesture
// Get the activeDate that was set before the swipe
activeDate = activeDate.addMonths(-1);
// Get the date where active month starts
startOfActiveMonth = QDate(activeDate.year(), activeDate.month(),1);
// Number of days frm start of the grid to start of the month
start = firstDateInGrid.daysTo(startOfActiveMonth);
// Get the date where active month ends
QDate endOfActiveMonth = startOfActiveMonth.addDays(activeDate.daysInMonth());
// Number of days frm start of the grid to end of the month
end = firstDateInGrid.daysTo(endOfActiveMonth);
} else if (mDirection == down) {
// Came here as user did down gesture
// Get the activeDate that was set before the swipe
activeDate = activeDate.addMonths(1);
// Get the activeDate that was set before the swipe
startOfActiveMonth = QDate(activeDate.year(), activeDate.month(),1);
// Number of days frm start of the grid to start of the month
start = firstDateInGrid.daysTo(startOfActiveMonth);
// Get the date where active month ends
QDate endOfActiveMonth = startOfActiveMonth.addDays(activeDate.daysInMonth());
// Number of days frm start of the grid to end of the month
end = firstDateInGrid.daysTo(endOfActiveMonth);
}
// Set the inactive text color
for (int i = start; i < end; i++) {
QModelIndex index = mModel->index(i,0);
QVariant itemData = index.data(Qt::UserRole + 1);
QVariantList list = itemData.toList();
list.replace(CalendarNamespace::CalendarMonthTextColorRole, false);
mModel->itemFromIndex(index)->setData(list);
}
}
/*!
To get current foucsed index of monthGrid
*/
int CalenMonthGrid::getCurrentIndex()
{
return mCurrentRow;
}
/*!
To set the focus to Index
*/
void CalenMonthGrid::setCurrentIdex(int index)
{
itemActivated(mModel->index(index, 0));
}
/*!
Function to override the default behavior of hbgridview on orientation change
*/
void CalenMonthGrid::orientationChanged(Qt::Orientation newOrientation)
{
Q_UNUSED(newOrientation)
// We are overriding this function to avoid the default behavior of
// hbgridview on orientation change as it swaps the row and column counts
}
/*!
Paint function to draw grid lines
*/
void CalenMonthGrid::paint(QPainter* painter,
const QStyleOptionGraphicsItem* option,
QWidget* widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setRenderHint(QPainter::NonCosmeticDefaultPen);
// Set the required attributes to the pen
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setWidth(GRIDLINE_WIDTH);
if (mGridLineColor.isValid()) {
pen.setBrush(mGridLineColor);
} else {
pen.setBrush(mGridBorderColor);
}
// Set the pen to the painter
painter->setPen(pen);
// Get the sizes of content widget
qreal contentHeight = mContentWidget->size().height();
qreal contentWidth = mContentWidget->size().width();
qreal rowWidth = 0.0;
int numOfRows = 0;
QPointF startPoint = mContentWidget->pos();
// NOTE!!!: There is a filcker when we blindly draw equally spaced lines
// on complete content widget when scrolling is finished. This happens only
// when content widget size is changed due to the change in total number
// of rows when we append or prepend rows. Hence, to avoid this, we draw
// lines on complete content widget only when it is scrolling.
// That means, as soon as scrolling is finished, we will end up drawing
// only 6 lines that are visible to the user.
if (mDirection == invalid) {
// Start point is left most point on the screen
startPoint = QPointF(0,0);
rowWidth = size().height() / KNumOfVisibleRows;
numOfRows = KNumOfVisibleRows;
} else {
// Get the num of rows
numOfRows = mModel->rowCount() / KCalenDaysInWeek;
// Draw horizontal lines
rowWidth = contentHeight / numOfRows;
}
QPointF endPoint(startPoint.x() + contentWidth,
startPoint.y());
// Create the list of points for which lines have to be drawn
// List should have even number of points so that it draws all the lines
// Painter draws the line for first two points in the list and then second
// line for next two points in the list like that. Hence, list should
// contain even number of points
QVector<QPointF> pointList;
for (int i = 0; i < numOfRows; i++) {
pointList.append(QPointF(startPoint.x(),
startPoint.y() + (i * rowWidth)));
pointList.append(QPointF(endPoint.x(), endPoint.y() + (i * rowWidth)));
}
// Draw vertical lines
qreal colWidth = contentWidth / KCalenDaysInWeek;
endPoint = QPointF(startPoint.x(),
startPoint.y() + contentHeight);
for (int i = 1; i < KCalenDaysInWeek; i++) {
pointList.append(QPointF(startPoint.x() + (i * colWidth),
startPoint.y()));
pointList.append(QPointF(endPoint.x() + (i * colWidth), endPoint.y()));
}
// Draw the lines for the points in the vector list
painter->drawLines(pointList);
}
// End of File