/* * Copyright (c) 2007 Sean C. Rhea (srhea@srhea.net) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "TimeUtils.h" #include #include #include #include QString time_to_string(double secs) { QString result; unsigned rounded = static_cast(round(secs)); bool needs_colon = false; if (rounded >= 3600) { result += QString("%1").arg(rounded / 3600); rounded %= 3600; needs_colon = true; } if (needs_colon) result += ":"; result += QString("%1").arg(rounded / 60, 2, 10, QLatin1Char('0')); rounded %= 60; result += ":"; result += QString("%1").arg(rounded, 2, 10, QLatin1Char('0')); return result; } double str_to_interval(QString s) { QRegExp rx("(\\d+\\s*h)?\\s*(\\d{1,2}\\s*m)?\\s*(\\d{1,2})(\\.\\d+)?\\s*s"); rx.indexIn(s); QString hour = rx.cap(1); QString min = rx.cap(2); QString sec = rx.cap(3) + rx.cap(4); hour.chop(1); min.chop(1); return 3600.0 * hour.toUInt() + 60.0 * min.toUInt() + sec.toDouble(); } QString interval_to_str(double secs) { if (secs < 60.0) return QString("%1s").arg(secs, 0, 'f', 2, QLatin1Char('0')); QString result; unsigned rounded = static_cast(round(secs)); bool needs_colon = false; if (rounded >= 3600) { result += QString("%1h").arg(rounded / 3600); rounded %= 3600; needs_colon = true; } if (needs_colon || rounded >= 60) { if (needs_colon) result += " "; result += QString("%1m").arg(rounded / 60, 2, 10, QLatin1Char('0')); rounded %= 60; needs_colon = true; } if (needs_colon) result += " "; result += QString("%1s").arg(rounded, 2, 10, QLatin1Char('0')); return result; } QDateTime convertToLocalTime(QString timestamp) { //check if the last character is Z designating the timezone to be UTC if (timestamp[timestamp.size()-1].toLower()=='z') { QDateTime datetime = QDateTime::fromString(timestamp, Qt::ISODate); datetime.setTimeSpec(Qt::UTC); datetime=datetime.toLocalTime(); return datetime; } //otherwise assume the timestamp is already in local time and simply convert it //something to add here would be a handler for explicitly set timezones //ex: 2002-05-30T09:30:10+06:00 //see http://www.w3schools.com/Schema/schema_dtypes_date.asp //for more on this date format else { return QDateTime::fromString(timestamp); } } DateRange::DateRange(QDate from, QDate to, QString name) : QObject() { this->from=from; this->to=to; this->name=name; } DateRange::DateRange(const DateRange &other) : QObject() { from=other.from; to=other.to; name=other.name; } DateRange& DateRange::operator=(const DateRange &other) { from=other.from; to=other.to; name=other.name; emit changed(from, to); return *this; } DateSettingsEdit::DateSettingsEdit(QWidget *parent) : parent(parent), active(true) { setContentsMargins(0,0,0,0); QFormLayout *mainLayout = new QFormLayout(this); mainLayout->setContentsMargins(0,0,0,0); mainLayout->setSpacing(0); QFont sameFont; #ifdef Q_OS_MAC sameFont.setPointSize(sameFont.pointSize() + 2); #endif radioSelected = new QRadioButton(tr("Current selection"), this); radioSelected->setChecked(true); radioSelected->setFont(sameFont); QHBoxLayout *selected = new QHBoxLayout; // use same layout mechanism as custom so they align selected->addWidget(radioSelected); selected->addStretch(); mainLayout->addRow(selected); radioToday = new QRadioButton(tr("Current selection thru today"), this); radioToday->setChecked(false); radioToday->setFont(sameFont); QHBoxLayout *today = new QHBoxLayout; // use same layout mechanism as custom so they align today->addWidget(radioToday); today->addStretch(); mainLayout->addRow(today); radioFrom = new QRadioButton(tr("From"), this); radioFrom->setChecked(false); radioFrom->setFont(sameFont); startDateEdit = new QDateEdit(this); startDateEdit->setDate(QDate::currentDate().addMonths(-3)); QHBoxLayout *from = new QHBoxLayout; from->addWidget(radioFrom); from->addWidget(startDateEdit); from->addWidget(new QLabel(tr("to today"))); from->addStretch(); mainLayout->addRow(from); radioCustom = new QRadioButton(tr("Between"), this); radioCustom->setFont(sameFont); radioCustom->setChecked(false); fromDateEdit = new QDateEdit(this); toDateEdit = new QDateEdit(this); QHBoxLayout *custom = new QHBoxLayout; custom->addWidget(radioCustom); custom->addWidget(fromDateEdit); custom->addWidget(new QLabel(tr("and"))); custom->addWidget(toDateEdit); custom->addStretch(); mainLayout->addRow(custom); radioLast = new QRadioButton(tr("Last"), this); radioLast->setFont(sameFont); radioLast->setChecked(false); lastn = new QDoubleSpinBox(this); lastn->setSingleStep(1.0); lastn->setDecimals(0); lastn->setMinimum(0); lastn->setMaximum(999); lastn->setValue(7); lastnx = new QComboBox(this); lastnx->addItem(tr("days")); lastnx->addItem(tr("weeks")); lastnx->addItem(tr("months")); lastnx->addItem(tr("years")); lastnx->setCurrentIndex(0); QHBoxLayout *last = new QHBoxLayout; last->addWidget(radioLast); last->addWidget(lastn); last->addWidget(lastnx); last->addStretch(); mainLayout->addRow(last); // switched between one or other connect(radioSelected, SIGNAL(toggled(bool)), this, SLOT(setDateSettings())); connect(radioToday, SIGNAL(toggled(bool)), this, SLOT(setDateSettings())); connect(radioCustom, SIGNAL(toggled(bool)), this, SLOT(setDateSettings())); connect(radioLast, SIGNAL(toggled(bool)), this, SLOT(setDateSettings())); connect(radioFrom, SIGNAL(toggled(bool)), this, SLOT(setDateSettings())); connect(fromDateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(setDateSettings())); connect(toDateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(setDateSettings())); connect(startDateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(setDateSettings())); connect(lastn, SIGNAL(valueChanged(double)), this, SLOT(setDateSettings())); connect(lastnx, SIGNAL(currentIndexChanged(int)), this, SLOT(setDateSettings())); } void DateSettingsEdit::setDateSettings() { if (active) return; // first lets disable everything active = true; fromDateEdit->setEnabled(false); toDateEdit->setEnabled(false); startDateEdit->setEnabled(false); lastn->setEnabled(false); lastnx->setEnabled(false); // the date selection types have changed if (radioSelected->isChecked()) { // current selection emit useStandardRange(); } else if (radioCustom->isChecked()) { // between x and y fromDateEdit->setEnabled(true); toDateEdit->setEnabled(true); // set date range using custom values emit useCustomRange(DateRange(fromDateEdit->date(), toDateEdit->date())); } else if (radioToday->isChecked()) { // current selected thru to today emit useThruToday(); } else if (radioLast->isChecked()) { // last n 'weeks etc' lastn->setEnabled(true); lastnx->setEnabled(true); QDate from; QDate today = QDate::currentDate(); // calculate range up to today... switch(lastnx->currentIndex()) { case 0 : // days from = today.addDays(lastn->value() * -1); break; case 1 : // weeks from = today.addDays(lastn->value() * -7); break; case 2 : // months from = today.addMonths(lastn->value() * -1); break; case 3 : // years from = today.addYears(lastn->value() * -1); break; } emit useCustomRange(DateRange(from, today)); } else if (radioFrom->isChecked()) { // from date - today startDateEdit->setEnabled(true); emit useCustomRange(DateRange(startDateEdit->date(), QDate::currentDate())); } active = false; } int DateSettingsEdit::mode() { if (radioSelected->isChecked()) return 0; if (radioFrom->isChecked()) return 1; if (radioCustom->isChecked()) return 2; if (radioLast->isChecked()) return 3; if (radioToday->isChecked()) return 4; return 0; // keep compiler happy } void DateSettingsEdit::setMode(int x) { active = true; radioSelected->setChecked(false); radioFrom->setChecked(false); radioCustom->setChecked(false); radioLast->setChecked(false); radioToday->setChecked(false); active = false; switch(x) { case 0: radioSelected->setChecked(true); break; case 1: radioFrom->setChecked(true); break; case 2: radioCustom->setChecked(true); break; case 3: radioLast->setChecked(true); break; case 4: radioToday->setChecked(true); break; } }