diff -r fd30d51f876b -r b6db4fd4947b calendarui/views/src/calenmonthgrid.cpp --- a/calendarui/views/src/calenmonthgrid.cpp Mon May 03 12:30:32 2010 +0300 +++ b/calendarui/views/src/calenmonthgrid.cpp Mon Jun 28 15:22:02 2010 +0530 @@ -16,14 +16,13 @@ */ // System includes -#include -#include -#include -#include #include #include #include #include +#include +#include +#include // User includes #include "calenmonthgrid.h" @@ -32,10 +31,13 @@ #include "calenmonthview.h" #include "calendateutils.h" #include "calencommon.h" +#include "calenconstants.h" // Constants -#define SCROLL_SPEEED 1000 +#define SCROLL_SPEEED 3000 #define GRIDLINE_WIDTH 0.075 //units +#define MAX_PAN_DIRECTION_THRESHOLD 50 +#define MIN_PAN_DIRECTION_THRESHOLD 20 /*! \class CalenMonthGrid @@ -53,7 +55,7 @@ mIsPanGesture(false), mIsAtomicScroll(true), mView(NULL), - mCurrentRow(0), + mCurrentRow(-100), mIsNonActiveDayFocused(false), mIgnoreItemActivated(false), mGridBorderColor(Qt::gray) @@ -66,33 +68,30 @@ setSelectionMode(HbGridView::NoSelection); setUniformItemSizes(true); setVerticalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff); - setClampingStyle(HbScrollArea::StrictClamping ); + setClampingStyle(HbScrollArea::StrictClamping); + setEnabledAnimations(HbAbstractItemView::None); + setFrictionEnabled(false); + setFlag(QGraphicsItem::ItemHasNoContents, false); + resetTransform(); // Get the content widget of the scroll area to draw the grid lines mContentWidget = contentWidget(); - // Get the color of the grid lines + // Get the all required colors + // Color of the grid lines mGridLineColor = HbColorScheme::color("qtc_cal_grid_line"); - // Create the prototype - CalenGridItemPrototype* gridItemPrototype = new CalenGridItemPrototype(this); - // Create the model - mModel = new QStandardItemModel(14*KCalenDaysInWeek, 1, this); - // Set the mode and the prototype - setModel(mModel,gridItemPrototype); + // 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)); + } - // Register the widgetml and css files - HbStyleLoader::registerFilePath(":/"); - - // Set the layout name - setLayoutName("calendarCustomGridItem"); - + // 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 &))); } /*! @@ -100,6 +99,7 @@ */ CalenMonthGrid::~CalenMonthGrid() { + // Nothing Yet } /*! @@ -114,55 +114,66 @@ Updates the model with the proper dates and sets the required user roles */ void CalenMonthGrid::updateMonthGridModel(QList &monthDataArray, - int indexToBeScrolled) + int indexToBeScrolled, bool isFirstTime) { - // 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); + 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; - - // Get the default text color to be set - QColor textColor = HbColorScheme::color("qtc_cal_month_notactive_dates"); - HbExtendedLocale locale = HbExtendedLocale::system(); - for (int i = 0; i < dataCount; i++) { + int modelIndex = 0; + for (int i = loopStart; i < loopEnd; i++) { QDateTime dateTime = monthDataArray[i].Day(); - currentIndex = mModel->index(i, 0); - // Get the localised string for the day - QString date = locale.toString(dateTime.date().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 + // !!!NOTE!!!: Add the data in the order mentioned in the // CalendarNamespace::DataRole enum. Dont change the order. - itemData << date; + itemData << mLocalisedDates.at(dateTime.date().day()-1); // Check for active day if (activeDateTime == CalenDateUtils::beginningOfDay(dateTime)) { - mCurrentRow = currentIndex.row(); - // Set the focus icon - itemData << QString("qtg_fr_cal_focused_day_ind"); + mCurrentRow = i; + // Set the focus attribute to true + itemData << true; } else { // reset the highlight - itemData << QString(""); + itemData << false; } // Check for current day if (currDateTime == CalenDateUtils::beginningOfDay(dateTime)) { - // Set the underline icon + // Set the underline attribute to true itemData << true; } else { itemData << false; @@ -170,61 +181,166 @@ // Check for events if (monthDataArray[i].HasEvents()) { - // Set the underline icon - itemData << QString("qtg_graf_cal_event_ind"); + // Set the event indicator attribute + itemData << true; } else { - itemData << QString(""); + itemData << false; } // Add default text color - itemData << textColor; + 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; - - // Get the active month - QDateTime activeDate = mView->getActiveDay(); - // Set the text color properly - setActiveDates(activeDate.date()); - - // 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); } /*! - Listens for down gesture + Updates the view with jprevious month dates when calendar is opened for the + first time to improve the opening time */ -void CalenMonthGrid::downGesture (int value) -{ - Q_UNUSED(value) - mDirection = down; - // Before we start scrolling, setthe active text color to previous month - QDateTime activeDate = mView->getActiveDay(); - setActiveDates(activeDate.addMonths(-1).date()); - HbScrollArea::downGesture(SCROLL_SPEEED); +void CalenMonthGrid::updateMonthGridWithInActiveMonths( + QList &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); + + // Update the sart position of the content widget + mStartPos = mContentWidget->pos(); + + // Now connect to the signal which gets emitted when any item on the grid + // is tapped. + connect(this, SIGNAL(activated(const QModelIndex &)), this, + SLOT(itemActivated(const QModelIndex &))); } /*! - Listens for Up gesture + Updates the view with just event indicators */ -void CalenMonthGrid::upGesture (int value) +void CalenMonthGrid::updateMonthGridWithEventIndicators( + QList &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); + } + } +} + +/*! + Scrolls the content dowmwards + */ +void CalenMonthGrid::downGesture() { - Q_UNUSED(value) - mDirection = up; - // Before we start scrolling, setthe active text color to future month - QDateTime activeDate = mView->getActiveDay(); - setActiveDates(activeDate.addMonths(1).date()); - HbScrollArea::upGesture(SCROLL_SPEEED); + // Make sure that content widget is properly placed + if (mIsNonActiveDayFocused) { + mIsAtomicScroll = true; + int itemToBeScrolled = mView->rowsInPrevMonth() * KCalenDaysInWeek; + QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + scrollTo(indexToBeScrolled); + } + mDirection = down; + mIsAtomicScroll = false; + setAttribute(Hb::InteractionDisabled); + QPointF targetPos(0.0, 0.0); + scrollContentsTo(targetPos,500); +} + +/*! + Scrolls the content upwards + */ +void CalenMonthGrid::upGesture() +{ + // Make sure that content widget is properly placed + if (mIsNonActiveDayFocused) { + mIsAtomicScroll = true; + int itemToBeScrolled = mView->rowsInPrevMonth() * KCalenDaysInWeek; + itemToBeScrolled += KNumOfVisibleRows * KCalenDaysInWeek; + QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + scrollTo(indexToBeScrolled); + } + mDirection = up; + mIsAtomicScroll = false; + setAttribute(Hb::InteractionDisabled); + QPointF targetPos(0.0, mStartPos.y() - size().height()); + scrollContentsTo(-targetPos,500); + } /*! @@ -232,7 +348,6 @@ */ void CalenMonthGrid::mousePressEvent(QGraphicsSceneMouseEvent* event) { - mPressedPos = event->pos(); // Pass it to parent HbGridView::mousePressEvent(event); } @@ -242,43 +357,88 @@ */ 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 grid view if pan gesture is not in progress else pass it to + // scrollarea. Problem here is, if we pass to gridview when panning, then + // its emitting item activated signal simply becasue of which focus item + // is getting changed when you finish the pan / shake + if (!mIsPanGesture) { + HbGridView::mouseReleaseEvent(event); + } else { + HbScrollArea::mouseReleaseEvent(event); } - // Pass it to parent - HbGridView::mouseReleaseEvent(event); } /*! - Listens for pan gesture + Function to list for all the gesture events */ -void CalenMonthGrid::panGesture(const QPointF & delta) +void CalenMonthGrid::gestureEvent(QGestureEvent *event) { - if (!mIsPanGesture) { - mIsPanGesture = true; - mIgnoreItemActivated = true; - - // Get to know the direction of the gesture - if (delta.y() > 0) { - mDirection = down; - } else { - mDirection = up; - } - } else { // This case is when user changes the direction while panning - // without lifting the finger - // Check if direction has changed - if (((delta.y() > 0) && (mDirection == up)) - || ((delta.y() < 0) && (mDirection == down))) { - // Direction has changed, ignore this pan - return; - } - } - // Call the parent class to perform the pan gesture - // When scrolling finished, month grid will adjust to show the proper month - HbScrollArea::panGesture(delta); + if(HbPanGesture *gesture = qobject_cast(event->gesture(Qt::PanGesture))) { + if (gesture->state() == Qt::GestureStarted) { + setAttribute(Hb::InteractionDisabled); + mIsAtomicScroll = false; + if (!mIsPanGesture) { + mDirection = invalid; + mStartPos = mContentWidget->pos(); + // TODO: This work aroung till framework provides an api + // to know the direciton of the pan, until then we need + // calculate the direction explicitly + // Get to know the direction of the gesture + // Use our defined threshold temporarily till scrollarea + // frm orbit side is made clever enough not to scroll in other direction + // apart frm the registered scroll direction + QPointF delta = gesture->delta(); + if (abs(delta.x()) > MAX_PAN_DIRECTION_THRESHOLD) { + // Now see if y coord diff has crossed threshold + if (delta.y() > MAX_PAN_DIRECTION_THRESHOLD) { + mIsPanGesture = true; + mIgnoreItemActivated = true; + mDirection = down; + } else if (delta.y() < -MAX_PAN_DIRECTION_THRESHOLD){ + mIsPanGesture = true; + mIgnoreItemActivated = true; + mDirection = up; + } else { + event->accept(Qt::PanGesture); + return; + } + } else if (abs(delta.x()) < MAX_PAN_DIRECTION_THRESHOLD) { + if (delta.y() > MIN_PAN_DIRECTION_THRESHOLD) { + mIsPanGesture = true; + mIgnoreItemActivated = true; + mDirection = down; + } else if (delta.y() < -MIN_PAN_DIRECTION_THRESHOLD){ + mIsPanGesture = true; + mIgnoreItemActivated = true; + mDirection = up; + }else { + event->accept(Qt::PanGesture); + return; + } + } + } + } + } else if(HbSwipeGesture *gesture = qobject_cast(event->gesture(Qt::SwipeGesture))) { + if (gesture->state() == Qt::GestureStarted) { + setAttribute(Hb::InteractionDisabled); + mIsAtomicScroll = false; + mDirection = invalid; + if (gesture->sceneVerticalDirection() == QSwipeGesture::Down) { + mDirection = down; + } else if (gesture->sceneVerticalDirection() == QSwipeGesture::Up) { + mDirection = up; + } else { + event->accept(Qt::SwipeGesture); + return; + } + } + } + + if (mDirection!= invalid) { + // Call the parent class to perform the pan gesture + // When scrolling finished, month grid will adjust to show the proper month + HbScrollArea::gestureEvent(event); + } } /*! @@ -286,42 +446,100 @@ */ void CalenMonthGrid::scrollingFinished() { - if (mIsPanGesture) { - mIsPanGesture = false; - if (mDirection == up) { - // Make a request for upgesture - upGesture(SCROLL_SPEEED); - return; // return immediately - } else if (mDirection == down) { - // Make a request for upgesture - downGesture(SCROLL_SPEEED); - return; // return immediately + 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(); } - } else if(!mIsAtomicScroll) { - // 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(); - } - // To improve the performance, lets start the timer for 10 ms, - // return immediately and do the other things after that - QTimer::singleShot(10, this, SLOT(timerExpired())); + mDirection = invalid; } else { mIsAtomicScroll = false; + mDirection = invalid; } mIgnoreItemActivated = false; + setAttribute(Hb::InteractionDisabled, false); } -void CalenMonthGrid::timerExpired() +/*! + Function to handle completion of pan gesture + */ +void CalenMonthGrid::handlePanGestureFinished() { - if(mDirection == down) { // down gesture - prependRows(); - } else if (mDirection == up) { //up gesture - appendRows(); + mIsPanGesture = false; + // Get the first item that is visible + QList 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(); + } else { + // we should again show the current month by scrolling downwards + mDirection = down; + mIsAtomicScroll = true; + setAttribute(Hb::InteractionDisabled); + 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; + setAttribute(Hb::InteractionDisabled); + scrollContentsTo(-mStartPos,500); + } else { + // down gesture to show the previous month + downGesture(); + } + } else if (month == prevMonth.addMonths(-1).date().month()) { + // first visible date belong to previous to previous month + // hence, scroll down to bring the previous month + downGesture(); + } 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(); + } else { + // we should again show the current month by scrolling upwards + mDirection = invalid; + setAttribute(Hb::InteractionDisabled); + scrollContentsTo(-mStartPos,500); + } + } else if (month == nextMonth.addMonths(1).date().month()) { + // first visible date belongs to next to next month + // hence, scroll up to show the next month + upGesture(); } - mDirection = invalid; } /*! @@ -330,43 +548,84 @@ */ 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; - QDateTime currDate = mView->getCurrentDay(); - QDateTime currDateTime = CalenDateUtils::beginningOfDay( currDate ); + 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 monthDataList = mView->monthDataList(); mMonthDataArray = monthDataList; - int listCount = monthDataList.count(); - // Get the updated rows to be inserted - int rowsInPrevMonth = mView->rowsInPrevMonth(); - int rowsInFutMonth = mView->rowsInFutMonth(); + + // Prepend the required rows + handlePrependingRows(monthDataList); + + // Since, we have finished setData, Now unblock the signals + mModel->blockSignals(false); - // remove the cells in the future month - int deleteFromIndex = (rowsInPrevMonthEarlier + KNumOfVisibleRows) * KCalenDaysInWeek; - int numOfIndices = rowsInFutMonthEarlier * KCalenDaysInWeek; - int count = mModel->rowCount(); + 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); - count = mModel->rowCount(); + // Scroll to proper index + itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) * + KCalenDaysInWeek) - 1; + indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + mIsAtomicScroll = true; + scrollTo(indexToBeScrolled); + // Update the mCurrentRow + mCurrentRow += countToBeAdded; + // Update the sart position of the content widget + mStartPos = mContentWidget->pos(); +} + +/*! + Helper function that prepends the required rows to the model + */ +void CalenMonthGrid::handlePrependingRows(QList &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); - count = mModel->rowCount(); - - // Get the default text color to be set - QColor textColor = HbColorScheme::color("qtc_cal_month_notactive_dates"); - HbExtendedLocale locale = HbExtendedLocale::system(); for (int i = 0; i < countToBeAdded; i++) { QDateTime dateTime = monthDataList[i].Day(); // Get the localised string for the day - QString date = locale.toString(dateTime.date().day()); QModelIndex currentIndex = mModel->index(i, 0); // Create the variant list to contain the date to depict a grid item @@ -374,14 +633,14 @@ // NOTE: Add the data in the order mentioned in the // CalendarNamespace::DataRole enum. Dont change the order. - itemData << date; + itemData << mLocalisedDates.at(dateTime.date().day()-1);; - // Diable the focus role - itemData << QString(""); + // Disable the focus role + itemData << false; // Check for current day if (currDateTime == CalenDateUtils::beginningOfDay( dateTime )) { - // Set the underline icon + // Set the underline icon attribute itemData << true; } else { itemData << false; @@ -389,39 +648,18 @@ // Update the event indicators if (monthDataList[i].HasEvents()) { - // Set the event indicator icon - itemData << QString("qtg_graf_cal_event_ind"); + // Set the event indicator attribute + itemData << true; } else { - itemData << QString(""); + itemData << false; } // Add default text color - - itemData << textColor; + itemData << false; // Set the data to model mModel->itemFromIndex(currentIndex)->setData(itemData); } - - // Update the mCurrentRow - mCurrentRow += countToBeAdded; - // Scroll to proper index - int itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) * - KCalenDaysInWeek) - 1; - QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0); - QMap data; - data = mModel->itemData(indexToBeScrolled); - QVariant value = data.value(Qt::DisplayRole); - int date = value.toInt(); - mIsAtomicScroll = true; - scrollTo(indexToBeScrolled); - - // Now remove the necessary items frm the model - mModel->removeRows(deleteFromIndex+countToBeAdded, numOfIndices); - mIsAtomicScroll = true; - itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek; - indexToBeScrolled = mModel->index(itemToBeScrolled, 0); - scrollTo(indexToBeScrolled); } /*! @@ -430,9 +668,19 @@ */ 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; - QDateTime currDate = mView->getCurrentDay(); - QDateTime currDateTime = CalenDateUtils::beginningOfDay( currDate ); + int rowsInFutMonth = mView->rowsInFutMonth(); int rowsInPrevMonth = mView->rowsInPrevMonth(); // remove the cells in the previous month @@ -442,40 +690,80 @@ mView->updateModelWithFutureMonth(); QList monthDataList = mView->monthDataList(); mMonthDataArray = monthDataList; - // Get the updated rows to be inserted + + // 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(); - rowsInFutMonth = mView->rowsInFutMonth(); + + // 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); + + // Update the sart position of the content widget + mStartPos = mContentWidget->pos(); +} + +/*! + Helper function that appends the required rows to the model + */ +void CalenMonthGrid::handleAppendingRows(QList &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); - // Get the default text color to be set - QColor textColor = HbColorScheme::color("qtc_cal_month_notactive_dates"); for (int i = 0; i < countToBeAdded; i++) { - QMap data; QModelIndex currentIndex = mModel->index(rowCount + i, 0); QDateTime dateTime = monthDataList[lastVisibleIndex + i].Day(); - HbExtendedLocale locale = HbExtendedLocale::system(); - // Get the localised string for the day - QString date = locale.toString(dateTime.date().day()); - data.insert(CalendarNamespace::CalendarMonthDayRole, date); // 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 << date; + itemData << mLocalisedDates.at(dateTime.date().day()-1);; // Disable the focus role - itemData << QString(""); + itemData << false; // Check for current day if (currDateTime == CalenDateUtils::beginningOfDay( dateTime )) { - // Set the underline icon + // Set the underline icon attribute itemData << true; } else { itemData << false; @@ -483,30 +771,18 @@ // Update the event indicators if (monthDataList[lastVisibleIndex + i].HasEvents()) { - // Set the underline icon - itemData << QString("qtg_graf_cal_event_ind"); + // Set the event indicator attribute + itemData << true; } else { - itemData << QString(""); + itemData << false; } // Add default text color - itemData << textColor; + itemData << false; // Set the data to model mModel->itemFromIndex(currentIndex)->setData(itemData); } - - // Update the mCurrentRow - mCurrentRow -= (countToBeDeleted); - for (int i = 0; i < countToBeDeleted; i++) { - mModel->removeRow(0); - } - mIsAtomicScroll = true; - - // Calculate the proper index to be scrolled to - int itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek; - QModelIndex indexToBeScrolled = mModel->index(itemToBeScrolled, 0); - scrollTo(indexToBeScrolled); } /*! @@ -521,14 +797,18 @@ mIsNonActiveDayFocused = false; // Check if the same item has been tapped twice if (mCurrentRow == index.row()) { - // Launch the agenda view + // Launch the Day view mView->launchDayView(); } else { // Reset the focus attribute to this item QModelIndex itemIndex = mModel->index(mCurrentRow,0); + if(itemIndex.row() < 0 || itemIndex.row() >= mModel->rowCount() || + itemIndex.column() < 0 || itemIndex.column() > mModel->columnCount()) { + return; + } QVariant itemData = itemIndex.data(Qt::UserRole + 1); QVariantList list = itemData.toList(); - list.replace(CalendarNamespace::CalendarMonthFocusRole, QString("")); + list.replace(CalendarNamespace::CalendarMonthFocusRole, false); mModel->itemFromIndex(itemIndex)->setData(list); // Inform view to update the context and preview panes @@ -537,7 +817,7 @@ itemData = itemIndex.data(Qt::UserRole + 1); list = itemData.toList(); list.replace(CalendarNamespace::CalendarMonthFocusRole, - QString("qtg_fr_cal_focused_day_ind")); + true); mModel->itemFromIndex(itemIndex)->setData(list); // Check if inactive date is tapped QDateTime activeMonth = mView->getActiveDay(); @@ -547,17 +827,19 @@ mIsNonActiveDayFocused = true; mNonActiveFocusedDay = mMonthDataArray[mCurrentRow].Day(); - // Get the current active month - QDateTime activeMonth = mView->getActiveDay(); - // Add one month to it + // Add one month to active month activeMonth = activeMonth.addMonths(1); if (activeMonth.date().month() == mNonActiveFocusedDay.date().month()) { + mDirection = up; // up gesture - upGesture(SCROLL_SPEEED); + upGesture(); + setActiveDates(activeMonth.date()); } else { + mDirection = down; // down gesture - downGesture(SCROLL_SPEEED); + downGesture(); + setActiveDates(activeMonth.addMonths(-2).date()); } } mView->setContextForActiveDay(index.row()); @@ -588,7 +870,7 @@ QModelIndex index = mModel->index(mCurrentRow,0); QVariant itemData = index.data(Qt::UserRole + 1); QVariantList list = itemData.toList(); - list.replace(CalendarNamespace::CalendarMonthFocusRole, QString("")); + list.replace(CalendarNamespace::CalendarMonthFocusRole, false); mModel->itemFromIndex(index)->setData(list); // Search for this date in the model @@ -598,7 +880,7 @@ itemData = index.data(Qt::UserRole + 1); list = itemData.toList(); list.replace(CalendarNamespace::CalendarMonthFocusRole, - QString("qtg_fr_cal_focused_day_ind")); + true); mModel->itemFromIndex(index)->setData(list); mCurrentRow = i; mView->setContextForActiveDay(i); @@ -635,15 +917,12 @@ end = firstDateInGrid.daysTo(endOfActiveMonth); // Set the active text color - QColor textColor = HbColorScheme::color("qtc_cal_month_active_dates"); - if (textColor.isValid()) { - 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, textColor); - mModel->itemFromIndex(index)->setData(list); - } + 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 @@ -683,15 +962,12 @@ } // Set the inactive text color - textColor = HbColorScheme::color("qtc_cal_month_notactive_dates"); - if (textColor.isValid()) { - 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, textColor); - mModel->itemFromIndex(index)->setData(list); - } + 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); } } @@ -719,6 +995,29 @@ 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 + // Calculate the proper index to be scrolled to + int rowsInPrevMonth; + int itemToBeScrolled; + QModelIndex indexToBeScrolled; + if (newOrientation == Qt::Horizontal) { + rowsInPrevMonth = mView->rowsInPrevMonth(); + itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek; + indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + mIsAtomicScroll = true; + scrollTo(indexToBeScrolled); + } else { + rowsInPrevMonth = mView->rowsInPrevMonth(); + itemToBeScrolled = rowsInPrevMonth * KCalenDaysInWeek; + indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + mIsAtomicScroll = true; + scrollTo(indexToBeScrolled); + + itemToBeScrolled = ((rowsInPrevMonth + KNumOfVisibleRows) * + KCalenDaysInWeek) - 1; + indexToBeScrolled = mModel->index(itemToBeScrolled, 0); + mIsAtomicScroll = true; + scrollTo(indexToBeScrolled); + } } /*! @@ -730,29 +1029,51 @@ { Q_UNUSED(option); Q_UNUSED(widget); + painter->setRenderHint(QPainter::NonCosmeticDefaultPen); // Set the required attributes to the pen QPen pen; + HbDeviceProfile deviceProf; + qreal unitValue = deviceProf.unitValue(); + qreal widthInPixels = GRIDLINE_WIDTH * unitValue; pen.setStyle(Qt::SolidLine); - pen.setWidth(GRIDLINE_WIDTH); + pen.setWidth(widthInPixels); if (mGridLineColor.isValid()) { pen.setBrush(mGridLineColor); } else { pen.setBrush(mGridBorderColor); } - // Set the pen to the painter + //store the old pen first + QPen oldPen = painter->pen(); + // Set the new 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(); - // Get the num of rows - int numOfRows = mModel->rowCount() / KCalenDaysInWeek; - // Draw horizontal lines - qreal rowWidth = contentHeight / numOfRows; + // 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 startPoint = mContentWidget->pos(); QPointF endPoint(startPoint.x() + contentWidth, startPoint.y()); @@ -780,6 +1101,8 @@ // Draw the lines for the points in the vector list painter->drawLines(pointList); + // Set the old pen back + painter->setPen(oldPen); } // End of File