--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbwidgets/widgets/hbdatetimepicker_p.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,1582 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbWidgets module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbdatetimepicker_p.h"
+#include "hbdatetimepicker.h"
+#include "hbstyleoption.h"
+#include "hbfeaturemanager_p.h"
+
+//TODO:remove frameitem dependency
+#include "hbframeitem.h"
+
+#include <QStringListModel>
+#include <QGraphicsLinearLayout>
+#include <QModelIndex>
+#include <QDate>
+#include <QLocale>
+#include <QDebug>
+#include <QStringListModel>
+#include <QPointer>
+
+#define HBDATETIMEPICKER_DEBUG
+
+//////////HbDateTimeParser - Implementaion may change in future.//////////////
+
+static inline int countRepeat(const QString &str, int index, int maxCount)
+{
+ int count = 1;
+ const QChar ch(str.at(index));
+ const int max = qMin(index + maxCount, str.size());
+ while (index + count < max && str.at(index + count) == ch) {
+ ++count;
+ }
+ return count;
+}
+
+static QString unquote(const QString &str)
+{
+ const QChar quote(QLatin1Char('\''));
+ const QChar slash(QLatin1Char('\\'));
+ const QChar zero(QLatin1Char('0'));
+ QString ret;
+ QChar status(zero);
+ const int max = str.size();
+ for (int i=0; i<max; ++i) {
+ if (str.at(i) == quote) {
+ if (status != quote) {
+ status = quote;
+ } else if (!ret.isEmpty() && str.at(i - 1) == slash) {
+ ret[ret.size() - 1] = quote;
+ } else {
+ status = zero;
+ }
+ } else {
+ ret += str.at(i);
+ }
+ }
+ return ret;
+}
+
+static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
+{
+ QString str(string.mid(from, size));
+ if (lastQuote >= from)
+ str = unquote(str);
+ list->append(str);
+}
+
+bool HbDateTimeParser::parseFormat(const QString &format)
+{
+ const QLatin1Char quote('\'');
+ const QLatin1Char slash('\\');
+ const QLatin1Char zero('0');
+
+ if (format == mDisplayFormat && !format.isEmpty()) {
+ return true;
+ }
+
+ QVector<SectionNode> newSectionNodes;
+ Sections newDisplay = 0;
+ QStringList newSeparators;
+ int i, index = 0;
+ int add = 0;
+ QChar status(zero);
+ const int max = format.size();
+ int lastQuote = -1;
+ for (i = 0; i<max; ++i) {
+ if (format.at(i) == quote) {
+ lastQuote = i;
+ ++add;
+ if (status != quote) {
+ status = quote;
+ } else if (format.at(i - 1) != slash) {
+ status = zero;
+ }
+ } else if (status != quote) {
+ const char sect = format.at(i).toLatin1();
+ switch (sect) {
+ case 'H':
+ case 'h':
+ {
+ const Section hour = (sect == 'h') ? Hour12Section : Hour24Section;
+ const SectionNode sn = { hour, i - add, countRepeat(format, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= hour;
+ }
+ break;
+ case 'm':
+ {
+ const SectionNode sn = { MinuteSection, i - add, countRepeat(format, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MinuteSection;
+ }
+ break;
+ case 's':
+ {
+ const SectionNode sn = { SecondSection, i - add, countRepeat(format, i, 2) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= SecondSection;
+ }
+ break;
+
+ case 'z':
+ {
+ const SectionNode sn = { MSecSection, i - add, countRepeat(format, i, 3) < 3 ? 1 : 3 };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MSecSection;
+ }
+ break;
+ case 'A':
+ case 'a':
+ {
+ const bool cap = (sect == 'A');
+ const SectionNode sn = { AmPmSection, i - add, (cap ? 1 : 0) };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ newDisplay |= AmPmSection;
+ if (i + 1 < format.size()
+ && format.at(i+1) == (cap ? QLatin1Char('P') : QLatin1Char('p'))) {
+ ++i;
+ }
+ index = i + 1;
+ }
+ break;
+ case 'y':
+ {
+ const int repeat = countRepeat(format, i, 4);
+ if (repeat >= 2) {
+ const SectionNode sn = { repeat == 4 ? YearSection : YearSection2Digits,
+ i - add, repeat == 4 ? 4 : 2 };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= sn.type;
+ }
+ }
+ break;
+ case 'M':
+ {
+ const SectionNode sn = { MonthSection, i - add, countRepeat(format, i, 4) };
+ newSectionNodes.append(sn);
+ newSeparators.append(unquote(format.mid(index, i - index)));
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= MonthSection;
+ }
+ break;
+ case 'd':
+ {
+ const int repeat = countRepeat(format, i, 4);
+ const SectionNode sn = { repeat >= 3 ? DayOfWeekSection : DaySection, i - add, repeat };
+ newSectionNodes.append(sn);
+ appendSeparator(&newSeparators, format, index, i - index, lastQuote);
+ i += sn.count - 1;
+ index = i + 1;
+ newDisplay |= sn.type;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
+ const int max = newSectionNodes.size();
+ for (int i=0; i<max; ++i) {
+ SectionNode &node = newSectionNodes[i];
+ if (node.type == Hour12Section)
+ node.type = Hour24Section;
+ }
+ }
+
+ if (index < format.size()) {
+ appendSeparator(&newSeparators, format, index, index - max, lastQuote);
+ } else {
+ newSeparators.append(QString());
+ }
+
+ mDisplayFormat = format;
+ mSeparators = newSeparators;
+ mSectionNodes = newSectionNodes;
+ mDisplaySections = newDisplay;
+
+ return true;
+}
+
+int HbDateTimeParser::sectionSize(int sectionIndex) const
+{
+ if (sectionIndex < 0)
+ return 0;
+
+ if (sectionIndex >= mSectionNodes.size()) {
+ qWarning("QDateTimeParser::sectionSize Internal error (%d)", sectionIndex);
+ return -1;
+ }
+ if (sectionIndex == mSectionNodes.size() - 1) {
+ return mDisplayFormat.size() - sectionPos(sectionIndex) - mSeparators.last().size();
+ } else {
+ return sectionPos(sectionIndex + 1) - sectionPos(sectionIndex)
+ - mSeparators.at(sectionIndex + 1).size();
+ }
+}
+
+int HbDateTimeParser::sectionPos(int sectionIndex) const
+{
+ return sectionPos(sectionNode(sectionIndex));
+}
+
+int HbDateTimeParser::sectionPos(const SectionNode &sn) const
+{
+ if (sn.pos == -1) {
+ return -1;
+ }
+
+ return sn.pos;
+}
+
+const HbDateTimeParser::SectionNode &HbDateTimeParser::sectionNode(int sectionIndex) const
+{
+ return mSectionNodes.at(sectionIndex);
+}
+/////////////////////////////////////////////////
+
+
+HbDateTimePickerPrivate::HbDateTimePickerPrivate()
+:HbWidgetPrivate()
+ ,mDayPicker(0)
+ ,mMonthPicker(0)
+ ,mYearPicker(0)
+ ,mHourPicker(0)
+ ,mMinutePicker(0)
+ ,mSecondPicker(0)
+ ,mAmPmPicker(0)
+ ,mDayModel(0)
+ ,mMonthModel(0)
+ ,mYearModel(0)
+ ,mHourModel(0)
+ ,mMinuteModel(0)
+ ,mSecondModel(0)
+ ,mAmPmModel(0)
+ ,mYearOffset(-1)
+ ,mMonthOffset(-1)
+ ,mDayOffset(-1)
+ ,mHourOffset(-1)
+ ,mMinuteOffset(-1)
+ ,mSecondOffset(-1)
+ ,mDateTime(QDateTime::currentDateTime())
+ ,mDateTimeMode(QVariant::Date) //default is date mode
+ ,mLayout(0)
+ //,mFormat() //set the format again in init()
+ //,mDisplaySecions() //is blank by default
+ ,mParser()
+ ,mYearFormat()
+ ,mMonthFormat()
+ ,mDayFormat()
+ ,mHourFormat()
+ ,mMinuteFormat()
+ ,mSecondFormat()
+ ,mIs24HourFormat(false)
+ ,mIsTwoDigitYearFormat(false)
+ ,mBackground(0)
+ ,mFrame(0)
+ ,mContent(0)
+{
+ mMinimumDate = HBDATETIMEPICKER_DATETIME_MIN;
+ mMaximumDate = HBDATETIMEPICKER_DATETIME_MAX;
+ mDateTime = mMinimumDate;
+}
+
+HbDateTimePickerPrivate::~HbDateTimePickerPrivate()
+{
+ QGraphicsLayoutItem *item;
+ foreach(item,mDividers)
+ {
+ mLayout->removeItem(item);
+ delete item;
+ }
+}
+
+/*
+ called only once. while the widget is constructing.
+*/
+
+void HbDateTimePickerPrivate::init(QVariant::Type dateTimeMode)
+{
+ Q_Q(HbDateTimePicker);
+
+ //create base content widget which contains the tumble views
+ mContent=new HbWidget(q);
+ mLayout = new QGraphicsLinearLayout(Qt::Horizontal);
+ mLayout->setSpacing(0);
+ mLayout->setContentsMargins(0,0,0,0);
+ mContent->setLayout(mLayout);
+ q->style()->setItemName(mContent,"content");
+
+ mDateTimeMode = dateTimeMode;
+
+ //read the format from locale
+ mFormat = localeDateTimeFormat(dateTimeMode);
+
+ //parse the format and set the sections in order
+ parseDisplayFormat(mFormat);
+
+ mDividers.clear();
+
+ //create the dividers used in rearrangeTumbleViews
+ createPrimitives();
+
+ //recreate and rearrange depending on the format
+ rearrangeTumbleViews();
+}
+
+/*!
+ \internal
+
+ Getting the format from the local settings.
+*/
+QString HbDateTimePickerPrivate::localeDateTimeFormat(const QVariant::Type &dateTimeMode)
+{
+ if(dateTimeMode == QVariant::Date) {
+ return mLocale.dateFormat(QLocale::ShortFormat);
+ } else if(dateTimeMode == QVariant::Time) {
+ return mLocale.timeFormat(QLocale::ShortFormat);
+ }
+ return mLocale.dateTimeFormat(QLocale::ShortFormat);
+}
+
+bool HbDateTimePickerPrivate::isFormatValid(const QString &newDisplayFormat)
+{
+ if(newDisplayFormat == mFormat) {
+ return false;
+ }
+ return true;
+}
+
+/*
+ this will reset the display sections and re add them in order
+ mentioned in the display format passed. this also sets the mIs24HourFormat var.
+*/
+void HbDateTimePickerPrivate::parseDisplayFormat(const QString &format)
+{
+ if(mParser.parseFormat(format)) {
+ for(int i=0;i<mParser.mSectionNodes.count();++i) {
+ switch(mParser.mSectionNodes[i].type) {
+ case HbDateTimeParser::DaySection:
+ case HbDateTimeParser::DayOfWeekSection:
+ mDayFormat = QString(mParser.mSectionNodes[i].count,'d');
+ break;
+
+ case HbDateTimeParser::MonthSection:
+ mMonthFormat = QString(mParser.mSectionNodes[i].count,'M');
+ break;
+
+ case HbDateTimeParser::YearSection:
+ mIsTwoDigitYearFormat = false;
+ mYearFormat = QString(mParser.mSectionNodes[i].count,'y');
+ break;
+
+ case HbDateTimeParser::YearSection2Digits:
+ mIsTwoDigitYearFormat = true;
+ mYearFormat = QString(mParser.mSectionNodes[i].count,'y');
+ break;
+
+ case HbDateTimeParser::SecondSection:
+ mSecondFormat = QString(mParser.mSectionNodes[i].count,'s');
+ break;
+
+ case HbDateTimeParser::MinuteSection:
+ mMinuteFormat = QString(mParser.mSectionNodes[i].count,'m');
+ break;
+
+ case HbDateTimeParser::Hour12Section:
+ mIs24HourFormat = false;
+ mHourFormat = QString(mParser.mSectionNodes[i].count,'h');
+ break;
+
+ case HbDateTimeParser::Hour24Section:
+ mIs24HourFormat = true;
+ mHourFormat = QString(mParser.mSectionNodes[i].count,'h');
+ break;
+
+ default:
+ break;
+ /*case HbDateTimeParser::DayOfWeekSection: not supported */
+ }
+ }
+ }
+}
+
+/*
+ this is called whenever the setDisplayFormat changes.
+ function deletes all tumbleviews which currently exist and
+ it creates the ones which are required and makes the connections.
+*/
+void HbDateTimePickerPrivate::rearrangeTumbleViews()
+{
+ Q_Q(HbDateTimePicker);
+
+ deleteAndNull(mYearPicker);
+ deleteAndNull(mMonthPicker);
+ deleteAndNull(mDayPicker);
+ deleteAndNull(mHourPicker);
+ deleteAndNull(mMinutePicker);
+ deleteAndNull(mSecondPicker);
+ deleteAndNull(mAmPmPicker);
+
+ deleteAndNull(mYearModel);
+ deleteAndNull(mDayModel);
+ deleteAndNull(mMonthModel);
+ deleteAndNull(mHourModel);
+ deleteAndNull(mMinuteModel);
+ deleteAndNull(mSecondModel);
+ deleteAndNull(mAmPmModel);
+
+ mYearOffset = -1;
+ mMonthOffset = -1;
+ mDayOffset = -1;
+ mHourOffset = -1;
+ mMinuteOffset = -1;
+ mSecondOffset = -1;
+
+ createDividers();
+
+ //divider stuff
+ //TODO: improve the divider addition and removal
+ foreach(QGraphicsItem *item, mDividers) {
+ HbFrameItem *fame = qgraphicsitem_cast<HbFrameItem *>(item);
+ Q_ASSERT(fame); // WRONG USE OF PRIMITIVES - Please fix it
+ mLayout->removeItem(fame);
+ fame->setVisible(false);
+ }
+
+
+ //TODO: improve the divider addition and removal
+ bool hasSeparator = mParser.mSectionNodes.count() > 1;
+
+ for(int i=0;i<mParser.mSectionNodes.count();i++) {
+
+ if(hasSeparator && (mLayout->count()>0)) {
+ //TODO: improve the divider addition and removal
+ HbFrameItem *f=static_cast<HbFrameItem*>(mDividers.at(i - 1));
+ if(f) {
+ f->setVisible(true);
+ }
+ mLayout->addItem(mDividers.at(i - 1));
+ }
+
+ switch(mParser.mSectionNodes[i].type) {
+ case HbDateTimeParser::AmPmSection:
+ mAmPmPicker = new HbTumbleView(q);
+ mAmPmModel = new QStringListModel(q);
+ mAmPmPicker->setModel(mAmPmModel);
+ mLayout->addItem(mAmPmPicker);
+ break;
+ case HbDateTimeParser::DaySection:
+ case HbDateTimeParser::DayOfWeekSection:
+ mDayPicker = new HbTumbleView(q);
+ mDayModel = new QStringListModel(q);
+ mDayPicker->setModel(mDayModel);
+ mLayout->addItem(mDayPicker);
+ break;
+ case HbDateTimeParser::MonthSection:
+ mMonthPicker = new HbTumbleView(q);
+ mMonthModel = new QStringListModel(q);
+ mMonthPicker->setModel(mMonthModel);
+ mLayout->addItem(mMonthPicker);
+ break;
+ case HbDateTimeParser::YearSection:
+ case HbDateTimeParser::YearSection2Digits:
+ mYearPicker = new HbTumbleView(q);
+ mYearModel = new QStringListModel(q);
+ mYearPicker->setModel(mYearModel);
+ mLayout->addItem(mYearPicker);
+ break;
+ case HbDateTimeParser::SecondSection:
+ mSecondPicker = new HbTumbleView(q);
+ mSecondModel = new QStringListModel(q);
+ mSecondPicker->setModel(mSecondModel);
+ mLayout->addItem(mSecondPicker);
+ break;
+ case HbDateTimeParser::MinuteSection:
+ mMinutePicker = new HbTumbleView(q);
+ mMinuteModel = new QStringListModel(q);
+ mMinutePicker->setModel(mMinuteModel);
+ mLayout->addItem(mMinutePicker);
+ break;
+ case HbDateTimeParser::Hour12Section:
+ case HbDateTimeParser::Hour24Section:
+ mHourPicker = new HbTumbleView(q);
+ mHourModel = new QStringListModel(q);
+ mHourPicker->setModel(mHourModel);
+ mLayout->addItem(mHourPicker);
+ break;
+ default:break;
+ }
+ }
+ setRanges();
+ makeConnections();
+ syncVisualDate();
+ //TODO:what to do with current date, should reset ?
+}
+
+void HbDateTimePickerPrivate::makeConnections()
+{
+ Q_Q(HbDateTimePicker);
+ bool b=false;
+ if(mYearPicker) {
+ b=QObject::connect(mYearPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_yearChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mMonthPicker) {
+ b=QObject::connect(mMonthPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_monthChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mDayPicker) {
+ b=QObject::connect(mDayPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_dayChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mHourPicker) {
+ b=QObject::connect(mHourPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_hoursChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mMinutePicker) {
+ b=QObject::connect(mMinutePicker,SIGNAL(itemSelected(int)),q,SLOT(_q_minutesChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mSecondPicker) {
+ b=QObject::connect(mSecondPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_secondsChanged(int)));
+ Q_ASSERT(b);
+ }
+ if(mAmPmPicker) {
+ b=QObject::connect(mAmPmPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_ampmChanged(int)));
+ Q_ASSERT(b);
+ }
+ Q_UNUSED(b);
+}
+void HbDateTimePickerPrivate::removeConnections()
+{
+ Q_Q(HbDateTimePicker);
+ if(mYearPicker) {
+ QObject::disconnect(mYearPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_yearChanged(int)));
+ }
+ if(mMonthPicker) {
+ QObject::disconnect(mMonthPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_monthChanged(int)));
+ }
+ if(mDayPicker) {
+ QObject::disconnect(mDayPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_dayChanged(int)));
+ }
+ if(mHourPicker) {
+ QObject::disconnect(mHourPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_hoursChanged(int)));
+ }
+ if(mMinutePicker) {
+ QObject::disconnect(mMinutePicker,SIGNAL(itemSelected(int)),q,SLOT(_q_minutesChanged(int)));
+ }
+ if(mSecondPicker) {
+ QObject::disconnect(mSecondPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_secondsChanged(int)));
+ }
+ if(mAmPmPicker) {
+ QObject::disconnect(mAmPmPicker,SIGNAL(itemSelected(int)),q,SLOT(_q_ampmChanged(int)));
+ }
+}
+
+
+void HbDateTimePickerPrivate::setRanges()
+{
+ if(mIsTwoDigitYearFormat) {
+ mYearOffset = mMinimumDate.date().year()%100;
+ setYearRange(mMinimumDate.date().year()%100,mMaximumDate.date().year()%100);
+ } else {
+ mYearOffset = mMinimumDate.date().year();
+ setYearRange(mMinimumDate.date().year(),mMaximumDate.date().year());
+ }
+
+ mMonthOffset = 1;
+ setMonthRange(1,12);//default all months
+
+ mDayOffset = 1;
+ setDayRange(1,31);//default all days
+
+ mHourOffset = 0;
+ setHourRange(0,23);
+
+ mMinuteOffset = 0;
+ setMinuteRange(0,59);
+
+ mSecondOffset = 0;
+ setSecondRange(0,59);
+
+ setAmPm();
+}
+
+void HbDateTimePickerPrivate::syncVisualDate()
+{
+ //no matter how good this is written , there always seems to be a gap
+ //between visual and actual selected data. creating syncup with visual.
+
+ int y=1,m=1,d=1,h=0,n=0,s=0;
+
+ if(mYearPicker) {
+ y = mYearOffset+mYearPicker->selected();
+ }
+ if(mMonthPicker) {
+ m = mMonthOffset+mMonthPicker->selected();
+ }
+ if(mDayPicker) {
+ d = mDayOffset +mDayPicker->selected();
+ }
+
+ if(mHourPicker) {
+ h=mHourOffset+mHourPicker->selected();
+ }
+
+ if(mMinutePicker) {
+ n=mMinuteOffset+mMinutePicker->selected();
+ }
+ if(mSecondPicker) {
+ s=mSecondOffset+mSecondPicker->selected();
+ }
+ QDateTime dt(QDate(y,m,d),QTime(h,n,s));
+ if(dt.isValid()) {
+ mDateTime = dt;
+ }
+}
+
+void HbDateTimePickerPrivate::emitDateChange()
+{
+ Q_Q(HbDateTimePicker);
+
+ emit q->dateChanged(mDateTime.date());
+ emit q->dateTimeChanged(mDateTime);
+}
+
+void HbDateTimePickerPrivate::emitTimeChange()
+{
+ Q_Q(HbDateTimePicker);
+
+ emit q->timeChanged(mDateTime.time());
+ emit q->dateTimeChanged(mDateTime);
+
+}
+void HbDateTimePickerPrivate::emitDateTimeChange()
+{
+ Q_Q(HbDateTimePicker);
+
+ emit q->dateChanged(mDateTime.date());
+ emit q->timeChanged(mDateTime.time());
+ emit q->dateTimeChanged(mDateTime);
+
+}
+
+
+void HbDateTimePickerPrivate::setDateTimeRange(const QDateTime &startdt,
+ const QDateTime &enddt)
+{
+ Q_Q(HbDateTimePicker);
+ QDateTime start(startdt);
+ QDateTime end(enddt);
+ if(start.isValid() && end.isValid()) {
+
+ removeConnections();
+
+ //change the date range
+ if(start.date() > end.date()) {
+ end.setDate(start.date());
+ }
+ if(mIsTwoDigitYearFormat) {
+ setYearRange(start.date().year()%100,end.date().year()%100);
+ } else {
+ setYearRange(start.date().year(),end.date().year());
+ }
+
+ //change the time range
+ if(start.time() > end.time()) {
+ end.setTime(start.time());
+ }
+ setHourRange(start.time().hour(),end.time().hour());
+
+ mMinimumDate = start;
+ mMaximumDate = end;
+
+ //scroll to the clamped date
+ bool dirty=false;
+ if(mDateTime < mMinimumDate) {
+ dirty = true;
+ mDateTime = mMinimumDate;
+ } else if(mDateTime > mMaximumDate) {
+ dirty = true;
+ mDateTime = mMaximumDate;
+ }
+ if(dirty) {
+ setDateTime(mDateTime);
+ //force the year change so month range gets set appropriately
+ //TODO:fix after modularization of entire code
+ }
+
+ if(mYearPicker) {
+ _q_yearChanged(mYearPicker->selected());
+ }
+
+ //force the hour change so minute range gets set appropriately
+ if(mHourPicker) {
+ _q_hoursChanged(mHourPicker->selected());
+ }
+
+ //emit the changes
+ emit q->dateChanged(mDateTime.date());
+ emit q->timeChanged(mDateTime.time());
+ emit q->dateTimeChanged(mDateTime);
+
+ makeConnections();
+ }
+}
+void HbDateTimePickerPrivate::setDateTime(const QDateTime &newDate)
+{
+ QDateTime newDateTime(newDate);
+ //TODO: validity and bounds check for selected
+ if(newDateTime.isValid()) {
+
+ //update the mem var
+ if(newDateTime.date() < mMinimumDate.date()) {
+ newDateTime.setDate(mMinimumDate.date());
+ } else if(newDateTime.date() > mMaximumDate.date()) {
+ newDateTime.setDate(mMaximumDate.date());
+ }
+
+ if(newDateTime.time() < mMinimumDate.time()) {
+ newDateTime.setTime(mMinimumDate.time());
+ }else if(newDateTime.time() > mMaximumDate.time()) {
+ newDateTime.setTime(mMaximumDate.time());
+ }
+
+ //set the selections
+ if(mYearPicker) {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setDateTime: yearOffset=" << mYearOffset;
+#endif
+ if(mIsTwoDigitYearFormat) {
+ mYearPicker->setSelected((newDateTime.date().year()%100)-mYearOffset);
+ } else {
+ mYearPicker->setSelected(newDateTime.date().year()-mYearOffset);
+ }
+ }
+ if(mMonthPicker) {
+ mMonthPicker->setSelected(newDateTime.date().month()-mMonthOffset);
+ }
+ if(mDayPicker) {
+ mDayPicker->setSelected(newDateTime.date().day()-mDayOffset);
+ }
+ if(mHourPicker) {
+ mHourPicker->setSelected(newDateTime.time().hour()-mHourOffset);
+ }
+ if(mMinutePicker) {
+ mMinutePicker->setSelected(newDateTime.time().minute()-mMinuteOffset);
+ }
+ if(mSecondPicker) {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setDateTime before: secondOffset=" << mSecondOffset << " time=" << newDateTime.time();
+#endif
+ mSecondPicker->setSelected(newDateTime.time().second()-mSecondOffset);
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setDateTime after: secondOffset=" << mSecondOffset << " time=" << newDateTime.time();
+#endif
+ }
+ mDateTime = newDateTime;
+
+ }
+}
+void HbDateTimePickerPrivate::setMinimumDateTime(const QDateTime &newMinDateTime)
+{
+ setDateTimeRange(newMinDateTime,mMaximumDate);
+}
+void HbDateTimePickerPrivate::setMaximumDateTime(const QDateTime &newMaxDateTime)
+{
+ setDateTimeRange(mMinimumDate,newMaxDateTime);
+}
+
+
+void HbDateTimePickerPrivate::setYearRange(int start,int end)
+{
+ if(!mYearPicker) {
+ return;
+ }
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mYearPicker->selected()-(start-mYearOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setyear range (" << start << "," << end << ")" ;
+#endif
+
+
+
+ resizeModel(mYearModel, mYearOffset,
+ mYearOffset+mYearModel->rowCount()-1, start,
+ end, &HbDateTimePickerPrivate::localeYear);
+
+ mYearOffset = start;
+
+ mYearPicker->setSelected(newIndex);
+}
+
+void HbDateTimePickerPrivate::setMonthRange(int start,int end)
+{
+ if(!mMonthPicker) {
+ return;
+ }
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setMonthRange: " << start << " ," << end;
+#endif
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mMonthPicker->selected()-(start-mMonthOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+ resizeModel(mMonthModel,
+ mMonthOffset,mMonthOffset+mMonthModel->rowCount()-1,
+ start,end,
+ &HbDateTimePickerPrivate::localeMonth);
+ mMonthOffset = start;
+
+ mMonthPicker->setSelected(newIndex);
+
+ //check if current month is valid
+ if(mDateTime.date().month() < start) {
+ mDateTime.setDate(QDate(mDateTime.date().year(),start,mDateTime.date().day()));
+ }
+ else if(mDateTime.date().month() > end) {
+ mDateTime.setDate(QDate(mDateTime.date().year(),end,mDateTime.date().day()));
+ }
+}
+
+
+void HbDateTimePickerPrivate::setDayRange(int start,int end)
+{
+ if(!mDayPicker) {
+ return;
+ }
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setDayRange: " << start << " ," << end;
+#endif
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mDayPicker->selected()-(start-mDayOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+
+ resizeModel(mDayModel,
+ mDayOffset,mDayOffset+mDayModel->rowCount()-1,
+ start,end,
+ &HbDateTimePickerPrivate::localeDay);
+ mDayOffset = start;
+
+ mDayPicker->setSelected(newIndex);
+
+
+ //check if current day is valid
+ if(mDateTime.date().day() < start) {
+ mDateTime.setDate(QDate(mDateTime.date().year(),mDateTime.date().month(),start));
+ }
+ else if(mDateTime.date().day() > end) {
+ mDateTime.setDate(QDate(mDateTime.date().year(),mDateTime.date().month(),end));
+ }
+}
+
+void HbDateTimePickerPrivate::setHourRange(int start,int end)
+{
+
+ if(!mHourPicker) {
+ return;
+ }
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setHourRange: " << start << " ," << end;
+#endif
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mHourPicker->selected()-(start-mHourOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+
+ resizeModel(mHourModel,
+ mHourOffset,mHourOffset+mHourModel->rowCount()-1,
+ start,end,
+ &HbDateTimePickerPrivate::localeHour);
+ mHourOffset = start;
+
+ mHourPicker->setSelected(newIndex);
+
+ //check if hour is valid
+ if(mDateTime.time().hour() < start) {
+ mDateTime.setTime(QTime(start,mDateTime.time().minute(),mDateTime.time().second()));
+ }
+ else if(mDateTime.time().hour() > end) {
+ mDateTime.setTime(QTime(end,mDateTime.time().minute(),mDateTime.time().second()));
+ }
+}
+void HbDateTimePickerPrivate::setMinuteRange(int start,int end)
+{
+
+ if(!mMinutePicker) {
+ return;
+ }
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setMinuteRange: " << start << " ," << end;
+#endif
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mMinutePicker->selected()-(start-mMinuteOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+
+ resizeModel(mMinuteModel,
+ mMinuteOffset,mMinuteOffset+mMinuteModel->rowCount()-1,
+ start,end,
+ &HbDateTimePickerPrivate::localeMinute);
+ mMinuteOffset = start;
+
+ mMinutePicker->setSelected(newIndex);
+
+ //check if minute is valid
+ if(mDateTime.time().minute() < start) {
+ mDateTime.setTime(QTime(mDateTime.time().hour(),start,mDateTime.time().second()));
+ }
+ else if(mDateTime.time().minute() > end) {
+ mDateTime.setTime(QTime(mDateTime.time().hour(),end,mDateTime.time().second()));
+ }
+}
+void HbDateTimePickerPrivate::setSecondRange(int start,int end)
+{
+
+ if(!mSecondPicker) {
+ return;
+ }
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "setSecondRange: " << start << " ," << end;
+#endif
+ //calculate the index it should be after resize
+ //the currentIndex gets reset after the resize and gets set to 0
+ //to work around that issue this is added
+ int newIndex = mSecondPicker->selected()-(start-mSecondOffset);
+ if(newIndex < 0) {
+ newIndex = 0;
+ }
+ if(newIndex > (end-start)) {
+ newIndex = end-start;
+ }
+
+ resizeModel(mSecondModel,
+ mSecondOffset,mSecondOffset+mSecondModel->rowCount()-1,
+ start,end,
+ &HbDateTimePickerPrivate::localeSecond);
+ mSecondOffset = start;
+
+ mSecondPicker->setSelected(newIndex);
+
+ //check if second is valid
+ if(mDateTime.time().second() < start) {
+ mDateTime.setTime(QTime(mDateTime.time().hour(),mDateTime.time().minute(),start));
+ }
+ else if(mDateTime.time().second() > end) {
+ mDateTime.setTime(QTime(mDateTime.time().hour(),mDateTime.time().minute(),end));
+ }
+}
+
+void HbDateTimePickerPrivate::setAmPm()
+{
+ if(!mAmPmPicker) {
+ return;
+ }
+ //TODO: check if range has both am and pm
+ QStringList amList;
+ amList << localeAmPm(true) << localeAmPm(false);
+ mAmPmModel->setStringList(amList);
+}
+
+QString HbDateTimePickerPrivate::localeYear(int year)
+{
+ //TODO:locale and format stuff
+ if(mIsTwoDigitYearFormat) {
+ return mLocale.toString(QDate(1900+year,1,1),mYearFormat);//year 00 is invalid
+ }
+ return mLocale.toString(QDate(year,1,1),mYearFormat);
+}
+
+QString HbDateTimePickerPrivate::localeMonth(int month)
+{
+ return mLocale.toString(QDate(2000,month,1),mMonthFormat);
+
+}
+QString HbDateTimePickerPrivate::localeDay(int day)
+{
+ return mLocale.toString(QDate(2000,1,day),mDayFormat);
+}
+
+QString HbDateTimePickerPrivate::localeHour(int hour)
+{
+ if(mIs24HourFormat) {
+ return mLocale.toString(QTime(hour,0,0),mHourFormat);
+ }
+
+ QString hourStr=mLocale.toString(QTime(hour,0,0),QString("%1:%2").arg(mHourFormat).arg("ap"));
+ QStringList hourAm=hourStr.split(":");
+ if(hourAm.count() > 1) {
+ return hourAm.at(0);
+ }
+ return QString("Format Err");
+}
+
+QString HbDateTimePickerPrivate::localeMinute(int minute)
+{
+ return mLocale.toString(QTime(0,minute,0),mMinuteFormat);
+}
+
+QString HbDateTimePickerPrivate::localeSecond(int second)
+{
+ return mLocale.toString(QTime(0,0,second),mSecondFormat);
+}
+
+QString HbDateTimePickerPrivate::localeAmPm(bool isAm)
+{
+ QString text = isAm ? mLocale.amText() : mLocale.pmText();
+#ifdef HB_TEXT_MEASUREMENT_UTILITY
+ if ( HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) {
+ text.append(QChar(LOC_TEST_START));
+ text.append("qtl_datetimepicker_popup_ampm_sec");
+ text.append(QChar(LOC_TEST_END));
+ }
+#endif
+ return text;
+}
+
+
+/* there are seven different models for seven pickers. insertion and removal
+ to each of the models to resize them its the same logic. but to populate the
+ data need the appropriate locale and format converted data. which is passed
+ as a function pointer instead of creating seven different QStringListModel derived
+ model classes with one interface/virtual fuction specialization.
+*/
+void HbDateTimePickerPrivate::resizeModel(QStringListModel *model,
+ int oldStart, int oldEnd,
+ int newStart, int newEnd,
+ QString (HbDateTimePickerPrivate::*localeFunc)(int))
+{
+ //if row count is zero, then insert from newEnd to newStart
+ if((model->rowCount() == 0) && (newEnd-newStart>=0)) {
+ //initialize condition
+ model->insertRows(0,newEnd-newStart+1);
+ for(int i=0;i<=newEnd-newStart;i++) {
+ QModelIndex index=model->index(i,0);
+ if(index.isValid()) {
+ //model->setData(index,(this->*localeFunc)(i+newStart));//TODO:add a readable typedef
+ QString text = (this->*localeFunc)(i+newStart);
+#ifdef HB_TEXT_MEASUREMENT_UTILITY
+ if ( localeFunc == &HbDateTimePickerPrivate::localeMonth &&
+ HbFeatureManager::instance()->featureStatus( HbFeatureManager::TextMeasurement ) ) {
+ text.append(QChar(LOC_TEST_START));
+ text.append("qtl_datetimepicker_popup_month_sec");
+ text.append(QChar(LOC_TEST_END));
+ }
+#endif
+ model->setData(index,text);//TODO:add a readable typedef
+ }
+ }
+ return;
+ }
+
+ if(newStart < oldStart) {
+ model->insertRows(0,oldStart-newStart);
+ for(int i=0;i<oldStart-newStart;++i) {
+ QModelIndex index=model->index(i,0);
+ if(index.isValid()) {
+ model->setData(index,(this->*localeFunc)(i+newStart));
+ }
+ }
+ }
+ if(newEnd > oldEnd) {
+ int rowCount = model->rowCount();
+ model->insertRows(rowCount,newEnd-oldEnd);
+ for(int i=0;i<newEnd-oldEnd;++i) {
+ QModelIndex index=model->index(rowCount+i,0);
+ if(index.isValid()) {
+ model->setData(index,(this->*localeFunc)(oldEnd+i+1));
+ }
+ }
+ }
+
+ if(newStart > oldStart) {
+ model->removeRows(0,newStart-oldStart);
+ }
+
+ if(oldEnd > newEnd) {
+ model->removeRows((model->rowCount()-(oldEnd-newEnd)),oldEnd-newEnd);
+ }
+}
+
+void HbDateTimePickerPrivate::createPrimitives()
+{
+ Q_Q(HbDateTimePicker);
+ if(!mBackground) {
+ mBackground = q->style()->createPrimitive(HbStyle::P_DateTimePicker_background,q);
+ q->style()->setItemName(mBackground,"background");
+ }
+ if(!mFrame) {
+ mFrame = q->style()->createPrimitive(HbStyle::P_DateTimePicker_frame,q);
+ q->style()->setItemName(mFrame,"frame");
+ }
+ createDividers();
+}
+
+void HbDateTimePickerPrivate::createDividers()
+{
+ Q_Q(HbDateTimePicker);
+
+ if( mParser.mSectionNodes.count() == mDividers.count() ){
+ return;
+ }
+
+ if( mParser.mSectionNodes.count() < mDividers.count() ){
+ for( int i = mParser.mSectionNodes.count() - 1; i > mDividers.count(); i--)
+ {
+ QPointer<QGraphicsWidget> item = mDividers.at(i);
+ mDividers.removeAt(i);
+ delete item;
+ }
+
+ return;
+ }
+ else if( mParser.mSectionNodes.count() > mDividers.count() ){
+
+ for(int i = mDividers.count();i < mParser.mSectionNodes.count(); i++) { //TODO: optimally create when required
+ QGraphicsItem *item=q->style()->createPrimitive(HbStyle::P_DateTimePicker_separator, mContent);
+ Q_ASSERT(item->isWidget());
+ q->style()->setItemName(item,"separator");
+ mDividers.append(static_cast<QGraphicsWidget *>(item));
+ }
+ }
+}
+
+void HbDateTimePickerPrivate::updateDividers()
+{
+ /*Q_Q(HbDateTimePicker);
+ HbStyleOption option;
+ q->initStyleOption(&option);
+ for(int i=0;i<qMin(mDividers.count(),mDividerIndex);i++) {
+ q->style()->updatePrimitive((QGraphicsItem*)mDividers.at(i),HbStyle::P_DateTimePicker_separator,&option);
+ }*/
+
+ //TODO: improve the divider addition and removal
+
+ //using the style update primitive crashes. need to investigate why
+
+}
+
+void HbDateTimePickerPrivate::_q_dayChanged(int index)
+{
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_dayChanged:" << index;
+#endif
+ QDate newDate(mDateTime.date().year(),mDateTime.date().month(),index+mDayOffset);
+ if(newDate.isValid()) {
+ mDateTime.setDate(newDate);
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "dayChange:currentDate:" << mDateTime;
+#endif
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid day change:" << index;
+#endif
+ return;
+ }
+
+ emitDateChange();
+
+ Q_UNUSED(index);
+}
+
+void HbDateTimePickerPrivate::_q_monthChanged(int index)
+{
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_monthChanged:" << index;
+#endif
+ QDate newDate(mDateTime.date());
+ if(mMonthOffset >= 0) {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "month: before:" << newDate << " ,off-ind:" << newDate.month()-mMonthOffset << "-" << index;
+#endif
+ newDate = newDate.addMonths(index+mMonthOffset-newDate.month());
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "month: after:" << newDate;
+#endif
+ }else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "month: before else:" << newDate;
+#endif
+ newDate = newDate.addMonths(index);
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "month: after else:" << newDate;
+#endif
+ }
+ if(newDate.isValid()) {
+ mDateTime.setDate(newDate);
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "monthChange:currentDate:" << mDateTime << " ind:" << index;
+#endif
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid month change:" << index;
+ qDebug() << "got invalid month change:" << mMonthOffset;
+#endif
+ return;
+ }
+
+ //check if day range changed
+ if(mDayPicker) {
+ int start=mDayOffset;
+ int end=mDayOffset+mDayModel->rowCount()-1;
+ if(isMinimumYear() && isMinimumMonth()) {
+ start = mMinimumDate.date().day();
+ } else {
+ start = 1;
+ }
+ if(isMaximumYear() && isMaximumMonth()) {
+ end = mMaximumDate.date().day();
+ } else {
+ end = mDateTime.date().daysInMonth();
+ }
+
+ //set if dayrange changed
+ if((start != mDayOffset)
+ ||(end !=mDayOffset+mDayModel->rowCount()-1)) {
+ setDayRange(start,end);
+ }
+ }
+
+ emitDateChange();
+}
+
+void HbDateTimePickerPrivate::_q_yearChanged(int index)
+{
+ qDebug() << "_q_yearChanged:" << index;
+ //Q_Q(HbDateTimePicker);
+ QDate newDate(mDateTime.date());
+ if(mIsTwoDigitYearFormat) {
+ newDate = newDate.addYears(index+mYearOffset-(newDate.year()%100));
+ }
+ else {
+ newDate = newDate.addYears(index+mYearOffset-newDate.year());
+ }
+ if(newDate.isValid()) {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "yearChange:currentDate before:" << mDateTime << " ind:" << index << " yeOff:" << mYearOffset;
+#endif
+ mDateTime.setDate(newDate);
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "yearChange:currentDate:" << mDateTime << " ind:" << index;
+#endif
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid month change:" << index;
+ qDebug() << "got invalid month change:" << mMonthOffset;
+#endif
+ return;
+ }
+
+ //check if month range changed
+ int start=0,end=0;
+ if(mMonthPicker) {
+ start=mMonthOffset;
+ end=start+mMonthModel->rowCount()-1;
+ if(isMinimumYear()) {
+ start = mMinimumDate.date().month();
+ } else {
+ start = 1;
+ }
+
+ if(isMaximumYear()) {
+ end = mMaximumDate.date().month();
+ } else {
+ end = 12;
+ }
+
+ //set if range changed
+ if((start != mMonthOffset)
+ || (end != mMonthModel->rowCount()-1)) {
+ setMonthRange(start,end);
+ }
+
+ }
+
+ //check if day range changed
+ if(mDayPicker) {
+ int start=mDayOffset;
+ int end=mDayOffset+mDayModel->rowCount()-1;
+ if(isMinimumYear() && isMinimumMonth()) {
+ start = mMinimumDate.date().day();
+ } else {
+ start = 1;
+ }
+ if(isMaximumYear() && isMaximumMonth()) {
+ end = mMaximumDate.date().day();
+ } else {
+ end = mDateTime.date().daysInMonth();
+ }
+
+ //set if dayrange changed
+ if((start != mDayOffset)
+ ||(end !=mDayOffset+mDayModel->rowCount()-1)) {
+ setDayRange(start,end);
+ }
+ }
+
+ emitDateChange();
+
+}
+
+void HbDateTimePickerPrivate::_q_hoursChanged(int index)
+{
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_hoursChanged:" << index;
+#endif
+ QTime newTime(mHourOffset+index,mDateTime.time().minute(),mDateTime.time().second());
+ if(newTime.isValid()) {
+ mDateTime.setTime(newTime);
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid hour change:" << index;
+ qDebug() << "got invalid hour change offset:" << mHourOffset;
+#endif
+ return;
+ }
+
+ //check if minute range changed
+ int start=0,end=0;
+ if(mMinutePicker) {
+ start=mMinuteOffset;
+ end=start+mMinuteModel->rowCount()-1;
+ if(isMinimumHour()) {
+ start = mMinimumDate.time().minute();
+ } else {
+ start = 0;
+ }
+ if(isMaximumHour()) {
+ end = mMaximumDate.time().minute();
+ } else {
+ end = 59;
+ }
+
+ //set if range changed
+ if((start != mMinuteOffset)
+ || (end != start+mMinuteModel->rowCount()-1)) {
+ setMinuteRange(start,end);
+ }
+
+ }
+
+ //check if seconds range changed
+ if(mSecondPicker) {
+ start=mSecondOffset;
+ end=mSecondOffset+mSecondModel->rowCount()-1;
+ if(isMinimumHour() && isMinimumMinute()) {
+ start = mMinimumDate.time().second();
+ } else {
+ start = 0;
+ }
+ if(isMaximumHour() && isMaximumMinute()) {
+ end = mMaximumDate.time().second();
+ } else {
+ end = 59;
+ }
+
+ //set if seconds range changed
+ if((start != mSecondOffset)
+ ||(end !=mSecondOffset+mSecondModel->rowCount()-1)) {
+ setSecondRange(start,end);
+ }
+ }
+
+ //check if am or pm and scroll to respective time
+ if((!mIs24HourFormat) && mAmPmPicker) {
+ if(mAmPmPicker->selected() == 0) {
+ //is AM
+ if(mDateTime.time().hour() > 11) {
+ mAmPmPicker->setSelected(1);
+ }
+ } else if(mAmPmPicker->selected() == 1) {
+ //is PM
+ if(mDateTime.time().hour() < 12) {
+ mAmPmPicker->setSelected(0);
+ }
+ }
+ }
+
+ emitTimeChange();
+}
+
+void HbDateTimePickerPrivate::_q_minutesChanged(int index)
+{
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_minutesChanged:" << index;
+#endif
+ QTime newTime(mDateTime.time().hour(),mMinuteOffset+index,mDateTime.time().second());
+ if(newTime.isValid()) {
+ mDateTime.setTime(newTime);
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid minute change:" << index;
+ qDebug() << "got invalid minute change offset:" << mMinuteOffset;
+#endif
+ return;
+ }
+
+ int start,end;
+ //check if seconds range changed
+ if(mSecondPicker) {
+ start=mSecondOffset;
+ end=mSecondOffset+mSecondModel->rowCount()-1;
+ if(isMinimumHour() && isMinimumMinute()) {
+ start = mMinimumDate.time().second();
+ } else {
+ start = 0;
+ }
+ if(isMaximumHour() && isMaximumMinute()) {
+ end = mMaximumDate.time().second();
+ } else {
+ end = 59;
+ }
+
+ //set if seconds range changed
+ if((start != mSecondOffset)
+ ||(end !=mSecondOffset+mSecondModel->rowCount()-1)) {
+ setSecondRange(start,end);
+ }
+ }
+
+ emitTimeChange();
+}
+
+void HbDateTimePickerPrivate::_q_secondsChanged(int index)
+{
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_secondsChanged:" << index;
+#endif
+ QTime newTime(mDateTime.time().hour(),mDateTime.time().minute(),mSecondOffset+index);
+ if(newTime.isValid()) {
+ mDateTime.setTime(newTime);
+ }
+ else {
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "got invalid second change:" << index;
+ qDebug() << "got invalid second change offset:" << mSecondOffset;
+#endif
+ return;
+ }
+
+
+ emitTimeChange();
+}
+
+void HbDateTimePickerPrivate::_q_ampmChanged(int index)
+{
+
+#ifdef HBDATETIMEPICKER_DEBUG
+ qDebug() << "_q_ampmChanged:" << index;
+#endif
+ if(index == 0) {
+ //AM is chosen
+ QTime newTime(mDateTime.time().hour()-12,mDateTime.time().minute(),mDateTime.time().second());
+ if(newTime.isValid()) {
+ if(newTime >= mMinimumDate.time()) {
+ mDateTime.setTime(newTime);
+ if(mHourPicker) {
+ mHourPicker->setSelected(newTime.hour()-mHourOffset);
+ }
+ emitTimeChange();
+ }else {
+ mAmPmPicker->setSelected(1);//invalid so scrollback
+ }
+
+ }
+ } else if(index == 1) {
+ //PM is chosen
+ QTime newTime(mDateTime.time().hour()+12,mDateTime.time().minute(),mDateTime.time().second());
+ if(newTime.isValid()) {
+ if(newTime <= mMaximumDate.time()) {
+ mDateTime.setTime(newTime);
+ if(mHourPicker) {
+ mHourPicker->setSelected(newTime.hour()-mHourOffset);
+ }
+ emitTimeChange();
+ } else {
+ mAmPmPicker->setSelected(0);//invalid so scrollback
+ }
+ }
+ }
+}