diff --git a/plugins/textshape/dialogs/LanguageTab.cpp b/plugins/textshape/dialogs/LanguageTab.cpp index ec372585236..4d7b753f4d6 100644 --- a/plugins/textshape/dialogs/LanguageTab.cpp +++ b/plugins/textshape/dialogs/LanguageTab.cpp @@ -1,89 +1,89 @@ /* This file is part of the KDE project Copyright (C) 2001, 2002 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LanguageTab.h" #include "KoGlobal.h" #include #include #include #include -LanguageTab::LanguageTab(/*KSpell2::Loader::Ptr loader,*/bool uniqueFormat, QWidget* parent, Qt::WFlags fl) +LanguageTab::LanguageTab(/*KSpell2::Loader::Ptr loader,*/bool uniqueFormat, QWidget* parent, Qt::WindowFlags fl) : QWidget(parent), m_uniqueFormat(uniqueFormat) { widget.setupUi(this); Q_UNUSED(fl); widget.languageListSearchLine->setListWidget(widget.languageList); //TODO use fl const QStringList langNames = KoGlobal::listOfLanguages(); const QStringList langTags = KoGlobal::listOfLanguageTags(); QSet spellCheckLanguages; widget.languageList->addItem(QString("None")); #if 0 //Port it if (loader) spellCheckLanguages = QSet::fromList(loader->languages()); #endif QStringList::ConstIterator itName = langNames.begin(); QStringList::ConstIterator itTag = langTags.begin(); for (; itName != langNames.end() && itTag != langTags.end(); ++itName, ++itTag) { if (spellCheckLanguages.contains(*itTag)) { QListWidgetItem* item = new QListWidgetItem(); item->setText(*itName); item->setIcon(koIcon("tools-check-spelling")); widget.languageList->addItem(item); } else widget.languageList->addItem(*itName); } connect(widget.languageList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SIGNAL(languageChanged())); } LanguageTab::~LanguageTab() { } void LanguageTab::save(KoCharacterStyle* style) const { if (!widget.languageList->currentItem() || widget.languageList->currentItem()->text() == "None") //TODO i18n style->setLanguage(QString()); else style->setLanguage(KoGlobal::tagOfLanguage(widget.languageList->currentItem()->text())); } void LanguageTab::setDisplay(KoCharacterStyle *style) { if (m_uniqueFormat) { const QString& name = KoGlobal::languageFromTag(style->language()); QList items = widget.languageList->findItems(name, Qt::MatchFixedString); if (!items.isEmpty()) { widget.languageList->setCurrentItem(items.first()); widget.languageList->scrollToItem(items.first()); } } } diff --git a/plugins/textshape/dialogs/LanguageTab.h b/plugins/textshape/dialogs/LanguageTab.h index 5c5c7187c79..7e03a95145d 100644 --- a/plugins/textshape/dialogs/LanguageTab.h +++ b/plugins/textshape/dialogs/LanguageTab.h @@ -1,48 +1,48 @@ /* This file is part of the KDE project Copyright (C) 2001,2002,2003,2006 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef __kolanguagetab_h__ #define __kolanguagetab_h__ #include class KoCharacterStyle; class LanguageTab : public QWidget { Q_OBJECT public: - explicit LanguageTab(/*KSpell2::Loader::Ptr loader = KSpell2::Loader::Ptr()*/bool uniqueFormat, QWidget* parent = 0, Qt::WFlags fl = 0); + explicit LanguageTab(/*KSpell2::Loader::Ptr loader = KSpell2::Loader::Ptr()*/bool uniqueFormat, QWidget* parent = 0, Qt::WindowFlags fl = 0); ~LanguageTab(); QString language() const; void setDisplay(KoCharacterStyle *style); void save(KoCharacterStyle *style) const; Q_SIGNALS: void languageChanged(); private: Ui::LanguageTab widget; bool m_uniqueFormat; }; #endif diff --git a/sheets/dialogs/ConditionalDialog.cpp b/sheets/dialogs/ConditionalDialog.cpp index e6dde7dce0a..277d2a34aac 100644 --- a/sheets/dialogs/ConditionalDialog.cpp +++ b/sheets/dialogs/ConditionalDialog.cpp @@ -1,548 +1,548 @@ /* This file is part of the KDE project Copyright (C) 2002-2003 Norbert Andres (C) 2002-2003 Philipp Mueller (C) 2002 John Dailey (C) 1999-2001 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "ConditionalDialog.h" #include "Condition.h" #include "Cell.h" #include "Map.h" #include "ui/Selection.h" #include "Sheet.h" #include "StyleManager.h" #include "ValueConverter.h" #include "ValueParser.h" #include "SheetsDebug.h" // commands #include "commands/ConditionCommand.h" #include #include #include #include #include #include #include using namespace Calligra::Sheets; -ConditionalWidget::ConditionalWidget(QWidget* parent, const char* /*name*/, Qt::WFlags fl) +ConditionalWidget::ConditionalWidget(QWidget* parent, const char* /*name*/, Qt::WindowFlags fl) : QWidget(parent, fl) { QGridLayout * Form1Layout = new QGridLayout(this); QGroupBox * groupBox1_3 = new QGroupBox(this); QGridLayout * groupBox1_3Layout = new QGridLayout(groupBox1_3); groupBox1_3Layout->setAlignment(Qt::AlignTop); QLabel * textLabel1_3 = new QLabel(groupBox1_3); groupBox1_3Layout->addWidget(textLabel1_3, 0, 0); m_condition_3 = new KComboBox(groupBox1_3); groupBox1_3Layout->addWidget(m_condition_3, 0, 1); m_firstValue_3 = new KLineEdit(groupBox1_3); m_firstValue_3->setEnabled(false); groupBox1_3Layout->addWidget(m_firstValue_3, 0, 2); m_secondValue_3 = new KLineEdit(groupBox1_3); m_secondValue_3->setEnabled(false); groupBox1_3Layout->addWidget(m_secondValue_3, 0, 3); m_style_3 = new KComboBox(groupBox1_3); m_style_3->setEnabled(false); groupBox1_3Layout->addWidget(m_style_3, 1, 1); QLabel * textLabel2_3 = new QLabel(groupBox1_3); groupBox1_3Layout->addWidget(textLabel2_3, 1, 0); QSpacerItem * spacer = new QSpacerItem(41, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_3Layout->addItem(spacer, 1, 2); QSpacerItem * spacer_2 = new QSpacerItem(61, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_3Layout->addItem(spacer_2, 1, 3); Form1Layout->addWidget(groupBox1_3, 2, 0); QGroupBox * groupBox1_2 = new QGroupBox(this); QGridLayout * groupBox1_2Layout = new QGridLayout(groupBox1_2); groupBox1_2Layout->setAlignment(Qt::AlignTop); QLabel * textLabel1_2 = new QLabel(groupBox1_2); groupBox1_2Layout->addWidget(textLabel1_2, 0, 0); QLabel * textLabel2_2 = new QLabel(groupBox1_2); groupBox1_2Layout->addWidget(textLabel2_2, 1, 0); m_condition_2 = new KComboBox(groupBox1_2); groupBox1_2Layout->addWidget(m_condition_2, 0, 1); m_style_2 = new KComboBox(groupBox1_2); m_style_2->setEnabled(false); groupBox1_2Layout->addWidget(m_style_2, 1, 1); m_firstValue_2 = new KLineEdit(groupBox1_2); m_firstValue_2->setEnabled(false); groupBox1_2Layout->addWidget(m_firstValue_2, 0, 2); m_secondValue_2 = new KLineEdit(groupBox1_2); m_secondValue_2->setEnabled(false); groupBox1_2Layout->addWidget(m_secondValue_2, 0, 3); QSpacerItem * spacer_3 = new QSpacerItem(41, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_2Layout->addItem(spacer_3, 1, 2); QSpacerItem * spacer_4 = new QSpacerItem(61, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_2Layout->addItem(spacer_4, 1, 3); Form1Layout->addWidget(groupBox1_2, 1, 0); QGroupBox * groupBox1_1 = new QGroupBox(this); QGridLayout * groupBox1_1Layout = new QGridLayout(groupBox1_1); groupBox1_1Layout->setAlignment(Qt::AlignTop); QLabel * textLabel1_1 = new QLabel(groupBox1_1); groupBox1_1Layout->addWidget(textLabel1_1, 0, 0); QLabel * textLabel2_1 = new QLabel(groupBox1_1); groupBox1_1Layout->addWidget(textLabel2_1, 1, 0); m_condition_1 = new KComboBox(groupBox1_1); groupBox1_1Layout->addWidget(m_condition_1, 0, 1); m_style_1 = new KComboBox(groupBox1_1); m_style_1->setEnabled(false); groupBox1_1Layout->addWidget(m_style_1, 1, 1); m_firstValue_1 = new KLineEdit(groupBox1_1); m_firstValue_1->setEnabled(false); groupBox1_1Layout->addWidget(m_firstValue_1, 0, 2); m_secondValue_1 = new KLineEdit(groupBox1_1); m_secondValue_1->setEnabled(false); groupBox1_1Layout->addWidget(m_secondValue_1, 0, 3); QSpacerItem * spacer_5 = new QSpacerItem(41, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_1Layout->addItem(spacer_5, 1, 2); QSpacerItem * spacer_6 = new QSpacerItem(61, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); groupBox1_1Layout->addItem(spacer_6, 1, 3); Form1Layout->addWidget(groupBox1_1, 0, 0); resize(QSize(702, 380).expandedTo(minimumSizeHint())); QStringList list; list += i18n(""); // krazy:exclude=i18ncheckarg list += i18n("equal to"); list += i18n("greater than"); list += i18n("less than"); list += i18n("equal to or greater than"); list += i18n("equal to or less than"); list += i18n("between"); list += i18n("outside range"); list += i18n("different to"); m_condition_1->clear(); m_condition_2->clear(); m_condition_3->clear(); m_condition_1->insertItems(0, list); m_condition_2->insertItems(0, list); m_condition_3->insertItems(0, list); groupBox1_1->setTitle(i18n("First Condition")); groupBox1_2->setTitle(i18n("Second Condition")); groupBox1_3->setTitle(i18n("Third Condition")); textLabel1_1->setText(i18n("Cell is")); textLabel1_2->setText(i18n("Cell is")); textLabel1_3->setText(i18n("Cell is")); textLabel2_1->setText(i18n("Cell style")); textLabel2_2->setText(i18n("Cell style")); textLabel2_3->setText(i18n("Cell style")); connect(m_condition_1, SIGNAL(highlighted(QString)), this, SLOT(slotTextChanged1(QString))); connect(m_condition_2, SIGNAL(highlighted(QString)), this, SLOT(slotTextChanged2(QString))); connect(m_condition_3, SIGNAL(highlighted(QString)), this, SLOT(slotTextChanged3(QString))); } ConditionalWidget::~ConditionalWidget() { } void ConditionalWidget::slotTextChanged1(const QString & text) { if (text == i18n("")) { // krazy:exclude=i18ncheckarg m_firstValue_1->setEnabled(false); m_secondValue_1->setEnabled(false); m_style_1->setEnabled(false); } else { m_condition_2->setEnabled(true); m_style_1->setEnabled(true); if ((text == i18n("between")) || (text == i18n("different from"))) { m_firstValue_1->setEnabled(true); m_secondValue_1->setEnabled(true); } else { m_firstValue_1->setEnabled(true); m_secondValue_1->setEnabled(false); } } } void ConditionalWidget::slotTextChanged2(const QString & text) { if (text == i18n("")) { // krazy:exclude=i18ncheckarg m_firstValue_2->setEnabled(false); m_secondValue_2->setEnabled(false); m_style_2->setEnabled(false); } else { m_condition_3->setEnabled(true); m_style_2->setEnabled(true); if ((text == i18n("between")) || (text == i18n("different from"))) { m_firstValue_2->setEnabled(true); m_secondValue_2->setEnabled(true); } else { m_firstValue_2->setEnabled(true); m_secondValue_2->setEnabled(false); } } } void ConditionalWidget::slotTextChanged3(const QString & text) { if (text == i18n("")) { // krazy:exclude=i18ncheckarg m_firstValue_3->setEnabled(false); m_secondValue_3->setEnabled(false); m_style_3->setEnabled(false); } else { m_style_3->setEnabled(true); if ((text == i18n("between")) || (text == i18n("different from"))) { m_firstValue_3->setEnabled(true); m_secondValue_3->setEnabled(true); } else { m_firstValue_3->setEnabled(true); m_secondValue_3->setEnabled(false); } } } /** * ConditionalDialog * Sets conditional cell formattings. */ ConditionalDialog::ConditionalDialog(QWidget* parent, Selection* selection) : KoDialog(parent), m_selection(selection), m_dlg(new ConditionalWidget(this)) { setButtons(KoDialog::Ok | KoDialog::Cancel); setCaption(i18n("Conditional Styles")); QStringList list(m_selection->activeSheet()->map()->styleManager()->styleNames()); m_dlg->m_style_1->insertItems(0, list); m_dlg->m_style_2->insertItems(0, list); m_dlg->m_style_3->insertItems(0, list); setMainWidget(m_dlg); connect(this, SIGNAL(okClicked()), this, SLOT(slotOk())); init(); } void ConditionalDialog::init() { QLinkedList conditionList; QLinkedList otherList; bool found; int numCondition; QLinkedList::iterator it1; QLinkedList::iterator it2; Sheet* sheet = m_selection->activeSheet(); conditionList = Cell(sheet, m_selection->marker()).conditions().conditionList(); /* this is the list, but only display the conditions common to all selected cells*/ for (int x = m_selection->lastRange().left(); x <= m_selection->lastRange().right(); x++) { for (int y = m_selection->lastRange().top(); y <= m_selection->lastRange().bottom(); y++) { otherList = Cell(sheet, x, y).conditions().conditionList(); it1 = conditionList.begin(); while (it1 != conditionList.end()) { debugSheets << "Here"; found = false; for (it2 = otherList.begin(); !found && it2 != otherList.end(); ++it2) { debugSheets << "Found:" << found; found = ((*it1).value1 == (*it2).value1 && (*it1).value2 == (*it2).value2 && (*it1).cond == (*it2).cond); if (!found) continue; if ((*it1).styleName != (*it2).styleName) found = false; } if (!found) { /* if it's not here, don't display this condition */ it1 = conditionList.erase(it1); } else { ++it1; } } } } debugSheets << "Conditions:" << conditionList.size(); m_dlg->m_condition_2->setEnabled(false); m_dlg->m_condition_3->setEnabled(false); m_dlg->m_style_1->setEnabled(false); m_dlg->m_style_2->setEnabled(false); m_dlg->m_style_3->setEnabled(false); numCondition = 0; for (it1 = conditionList.begin(); numCondition < 3 && it1 != conditionList.end(); ++it1) { init(*it1, numCondition); ++numCondition; } } void ConditionalDialog::init(Conditional const & tmp, int numCondition) { debugSheets << "Adding" << numCondition; KComboBox * cb = 0; KComboBox * sb = 0; KLineEdit * kl1 = 0; KLineEdit * kl2 = 0; QString value; Map *const map = m_selection->activeSheet()->map(); ValueConverter *const converter = map->converter(); switch (numCondition) { case 0: cb = m_dlg->m_condition_1; sb = m_dlg->m_style_1; kl1 = m_dlg->m_firstValue_1; kl2 = m_dlg->m_secondValue_1; break; case 1: cb = m_dlg->m_condition_2; sb = m_dlg->m_style_2; kl1 = m_dlg->m_firstValue_2; kl2 = m_dlg->m_secondValue_2; break; case 2: cb = m_dlg->m_condition_3; sb = m_dlg->m_style_3; kl1 = m_dlg->m_firstValue_3; kl2 = m_dlg->m_secondValue_3; break; default: return; } if (!tmp.styleName.isEmpty()) { sb->setCurrentIndex(sb->findText(tmp.styleName)); sb->setEnabled(true); } switch (tmp.cond) { case Conditional::None : case Conditional::IsTrueFormula: // was unhandled break; case Conditional::Equal : cb->setCurrentIndex(1); break; case Conditional::Superior : cb->setCurrentIndex(2); break; case Conditional::Inferior : cb->setCurrentIndex(3); break; case Conditional::SuperiorEqual : cb->setCurrentIndex(4); break; case Conditional::InferiorEqual : cb->setCurrentIndex(5); break; case Conditional::Between : cb->setCurrentIndex(6); kl2->setText(converter->asString(tmp.value2).asString()); break; case Conditional::Different : cb->setCurrentIndex(7); kl2->setText(converter->asString(tmp.value2).asString()); break; case Conditional::DifferentTo : cb->setCurrentIndex(8); break; } if (tmp.cond != Conditional::None) { kl1->setEnabled(true); kl1->setText(converter->asString(tmp.value1).asString()); } } Conditional::Type ConditionalDialog::typeOfCondition(KComboBox const * const cb) const { Conditional::Type result = Conditional::None; switch (cb->currentIndex()) { case 0 : result = Conditional::None; break; case 1 : result = Conditional::Equal; break; case 2 : result = Conditional::Superior; break; case 3 : result = Conditional::Inferior; break; case 4 : result = Conditional::SuperiorEqual; break; case 5 : result = Conditional::InferiorEqual; break; case 6 : result = Conditional::Between; break; case 7 : result = Conditional::Different; break; case 8 : result = Conditional::DifferentTo; break; default: debugSheets << "Error in list"; break; } return result; } bool ConditionalDialog::checkInputData(KLineEdit const * const edit1, KLineEdit const * const edit2) { bool b1 = false; bool b2 = false; if (!edit2->isEnabled()) return true; edit1->text().toDouble(&b1); edit2->text().toDouble(&b2); if (b1 != b2) { if (b1) KMessageBox::sorry(0, i18n("If the first value is a number, the second value also has to be a number.")); else KMessageBox::sorry(0, i18n("If the first value is a string, the second value also has to be a string.")); return false; } return true; } bool ConditionalDialog::checkInputData() { if (m_dlg->m_firstValue_1->isEnabled() && !checkInputData(m_dlg->m_firstValue_1, m_dlg->m_secondValue_1)) return false; if (m_dlg->m_firstValue_2->isEnabled() && !checkInputData(m_dlg->m_firstValue_2, m_dlg->m_secondValue_2)) return false; if (m_dlg->m_firstValue_3->isEnabled() && !checkInputData(m_dlg->m_firstValue_3, m_dlg->m_secondValue_3)) return false; return true; } bool ConditionalDialog::getCondition(Conditional & newCondition, const KComboBox * cb, const KLineEdit * edit1, const KLineEdit * edit2, const KComboBox * sb) { if (!cb->isEnabled()) return false; newCondition.cond = typeOfCondition(cb); if (newCondition.cond == Conditional::None) return false; Map *const map = m_selection->activeSheet()->map(); ValueParser *const parser = map->parser(); newCondition.value1 = parser->parse(edit1->text()); newCondition.value2 = parser->parse(edit2->text()); newCondition.styleName = sb->currentText(); return true; } void ConditionalDialog::slotOk() { debugSheets << "slotOk"; if (!checkInputData()) return; debugSheets << "Input data is valid"; QLinkedList newList; Conditional newCondition; if (getCondition(newCondition, m_dlg->m_condition_1, m_dlg->m_firstValue_1, m_dlg->m_secondValue_1, m_dlg->m_style_1)) newList.append(newCondition); if (getCondition(newCondition, m_dlg->m_condition_2, m_dlg->m_firstValue_2, m_dlg->m_secondValue_2, m_dlg->m_style_2)) newList.append(newCondition); if (getCondition(newCondition, m_dlg->m_condition_3, m_dlg->m_firstValue_3, m_dlg->m_secondValue_3, m_dlg->m_style_3)) newList.append(newCondition); debugSheets << "Setting conditional list"; ConditionCommand* manipulator = new ConditionCommand(); manipulator->setSheet(m_selection->activeSheet()); manipulator->setConditionList(newList); manipulator->add(*m_selection); manipulator->execute(m_selection->canvas()); accept(); } diff --git a/sheets/dialogs/ConditionalDialog.h b/sheets/dialogs/ConditionalDialog.h index 72d72f82341..60a0a4eae99 100644 --- a/sheets/dialogs/ConditionalDialog.h +++ b/sheets/dialogs/ConditionalDialog.h @@ -1,109 +1,109 @@ /* This file is part of the KDE project Copyright (C) 2002-2003 Norbert Andres (C) 2002-2003 Philipp Mueller (C) 2002 John Dailey (C) 1999-2004 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CALLIGRA_SHEETS_CONDITIONAL_DIALOG #define CALLIGRA_SHEETS_CONDITIONAL_DIALOG #include #include "Condition.h" class KComboBox; class KLineEdit; namespace Calligra { namespace Sheets { class Selection; /** * \ingroup UI * Widget representing a conditional cell style. */ class ConditionalWidget : public QWidget { Q_OBJECT public: - explicit ConditionalWidget(QWidget * parent = 0, const char * name = 0, Qt::WFlags fl = 0); + explicit ConditionalWidget(QWidget * parent = 0, const char * name = 0, Qt::WindowFlags fl = 0); ~ConditionalWidget(); KComboBox * m_condition_1; KComboBox * m_style_1; KLineEdit * m_firstValue_1; KLineEdit * m_secondValue_1; KComboBox * m_condition_2; KComboBox * m_style_2; KLineEdit * m_firstValue_2; KLineEdit * m_secondValue_2; KComboBox * m_condition_3; KComboBox * m_style_3; KLineEdit * m_firstValue_3; KLineEdit * m_secondValue_3; public Q_SLOTS: void slotTextChanged1(const QString &); void slotTextChanged2(const QString &); void slotTextChanged3(const QString &); }; /** * \ingroup UI * Dialog to set conditional cell styles. */ class ConditionalDialog : public KoDialog { Q_OBJECT public: ConditionalDialog(QWidget* parent, Selection* selection); void init(); public Q_SLOTS: void slotOk(); protected: Selection* m_selection; ConditionalWidget * m_dlg; Conditional::Type m_result; private: void init(Conditional const & tmp, int numCondition); Conditional::Type typeOfCondition(KComboBox const * const cb) const; bool checkInputData(KLineEdit const * const edit1, KLineEdit const * const edit2); bool checkInputData(); bool getCondition(Conditional & newCondition, const KComboBox * cb, const KLineEdit * edit1, const KLineEdit * edit2, const KComboBox * sb); }; } // namespace Sheets } // namespace Calligra #endif // CALLIGRA_SHEETS_CONDITIONAL_DIALOG diff --git a/sheets/functions/datetime.cpp b/sheets/functions/datetime.cpp index 8152ed64e86..9f59fe2cf75 100644 --- a/sheets/functions/datetime.cpp +++ b/sheets/functions/datetime.cpp @@ -1,1143 +1,1143 @@ /* This file is part of the KDE project Copyright (C) 1998-2003 The KSpread Team Copyright (C) 2005 Tomas Mecir This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; only version 2 of the License. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // built-in date/time functions #include "DateTimeModule.h" #include "CalculationSettings.h" #include "Function.h" #include "FunctionModuleRegistry.h" #include "functions/helper.h" #include "ValueCalc.h" #include "ValueConverter.h" #include using namespace Calligra::Sheets; // prototypes, sorted Value func_currentDate(valVector args, ValueCalc *calc, FuncExtra *); Value func_currentDateTime(valVector args, ValueCalc *calc, FuncExtra *); Value func_currentTime(valVector args, ValueCalc *calc, FuncExtra *); Value func_date(valVector args, ValueCalc *calc, FuncExtra *); Value func_date2unix(valVector args, ValueCalc *calc, FuncExtra *); Value func_dateDif(valVector args, ValueCalc *calc, FuncExtra *); Value func_datevalue(valVector args, ValueCalc *calc, FuncExtra *); Value func_day(valVector args, ValueCalc *calc, FuncExtra *); Value func_dayname(valVector args, ValueCalc *calc, FuncExtra *); Value func_dayOfYear(valVector args, ValueCalc *calc, FuncExtra *); Value func_days(valVector args, ValueCalc *calc, FuncExtra *); Value func_days360(valVector args, ValueCalc *calc, FuncExtra *); Value func_daysInMonth(valVector args, ValueCalc *calc, FuncExtra *); Value func_daysInYear(valVector args, ValueCalc *calc, FuncExtra *); Value func_easterSunday(valVector args, ValueCalc *calc, FuncExtra *); Value func_edate(valVector args, ValueCalc *calc, FuncExtra *); Value func_eomonth(valVector args, ValueCalc *calc, FuncExtra *); Value func_hour(valVector args, ValueCalc *calc, FuncExtra *); Value func_hours(valVector args, ValueCalc *calc, FuncExtra *); Value func_isLeapYear(valVector args, ValueCalc *calc, FuncExtra *); Value func_isoWeekNum(valVector args, ValueCalc *calc, FuncExtra *); Value func_minute(valVector args, ValueCalc *calc, FuncExtra *); Value func_minutes(valVector args, ValueCalc *calc, FuncExtra *); Value func_month(valVector args, ValueCalc *calc, FuncExtra *); Value func_monthname(valVector args, ValueCalc *calc, FuncExtra *); Value func_months(valVector args, ValueCalc *calc, FuncExtra *); Value func_networkday(valVector args, ValueCalc *calc, FuncExtra *); Value func_second(valVector args, ValueCalc *calc, FuncExtra *); Value func_seconds(valVector args, ValueCalc *calc, FuncExtra *); Value func_time(valVector args, ValueCalc *calc, FuncExtra *); Value func_timevalue(valVector args, ValueCalc *calc, FuncExtra *); Value func_today(valVector args, ValueCalc *calc, FuncExtra *); Value func_unix2date(valVector args, ValueCalc *calc, FuncExtra *); Value func_weekday(valVector args, ValueCalc *calc, FuncExtra *); Value func_weekNum(valVector args, ValueCalc *calc, FuncExtra *); Value func_weeks(valVector args, ValueCalc *calc, FuncExtra *); Value func_weeksInYear(valVector args, ValueCalc *calc, FuncExtra *); Value func_workday(valVector args, ValueCalc *calc, FuncExtra *); Value func_year(valVector args, ValueCalc *calc, FuncExtra *); Value func_yearFrac(valVector args, ValueCalc *calc, FuncExtra *); Value func_years(valVector args, ValueCalc *calc, FuncExtra *); CALLIGRA_SHEETS_EXPORT_FUNCTION_MODULE("kspreaddatetimemodule.json", DateTimeModule) DateTimeModule::DateTimeModule(QObject* parent, const QVariantList&) : FunctionModule(parent) { Function *f; f = new Function("CURRENTDATE", func_currentDate); f->setParamCount(0); add(f); f = new Function("CURRENTDATETIME", func_currentDateTime); f->setParamCount(0); add(f); f = new Function("CURRENTTIME", func_currentTime); f->setParamCount(0); add(f); f = new Function("DATE", func_date); f->setParamCount(3); add(f); f = new Function("DATE2UNIX", func_date2unix); f->setParamCount(1); add(f); f = new Function("DATEDIF", func_dateDif); f->setParamCount(3); add(f); f = new Function("DATEVALUE", func_datevalue); add(f); f = new Function("DAY", func_day); add(f); f = new Function("DAYNAME", func_dayname); add(f); f = new Function("DAYOFYEAR", func_dayOfYear); f->setParamCount(3); add(f); f = new Function("DAYS", func_days); f->setParamCount(2); add(f); f = new Function("DAYS360", func_days360); f->setParamCount(2, 3); add(f); f = new Function("DAYSINMONTH", func_daysInMonth); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDAYSINMONTH"); f->setParamCount(2); add(f); f = new Function("DAYSINYEAR", func_daysInYear); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDAYSINYEAR"); add(f); f = new Function("EASTERSUNDAY", func_easterSunday); add(f); f = new Function("EDATE", func_edate); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEDATE"); f->setParamCount(2); add(f); f = new Function("EOMONTH", func_eomonth); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETEOMONTH"); f->setParamCount(2); add(f); f = new Function("HOUR", func_hour); f->setParamCount(0, 1); add(f); f = new Function("HOURS", func_hour); // same as HOUR f->setParamCount(0, 1); add(f); f = new Function("ISLEAPYEAR", func_isLeapYear); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETISLEAPYEAR"); add(f); f = new Function("ISOWEEKNUM", func_isoWeekNum); f->setParamCount(1, 2); add(f); f = new Function("MINUTE", func_minute); f->setParamCount(0, 1); add(f); f = new Function("MINUTES", func_minute); // same as MINUTE f->setParamCount(0, 1); add(f); f = new Function("MONTH", func_month); add(f); f = new Function("MONTHNAME", func_monthname); add(f); f = new Function("MONTHS", func_months); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFMONTHS"); f->setParamCount(3); add(f); f = new Function("NETWORKDAY", func_networkday); //f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETNETWORKDAYS"); f->setParamCount(2, 3); f->setAcceptArray(); add(f); f = new Function("NOW", func_currentDateTime); f->setParamCount(0); add(f); f = new Function("SECOND", func_second); f->setParamCount(0, 1); add(f); f = new Function("SECONDS", func_second); // same as SECOND f->setParamCount(0, 1); add(f); f = new Function("TIME", func_time); f->setParamCount(3); add(f); f = new Function("TIMEVALUE", func_timevalue); add(f); f = new Function("TODAY", func_currentDate); f->setParamCount(0); add(f); f = new Function("UNIX2DATE", func_unix2date); f->setParamCount(1); add(f); f = new Function("WEEKDAY", func_weekday); f->setParamCount(1, 2); add(f); f = new Function("WEEKNUM", func_weekNum); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWEEKNUM"); f->setParamCount(1, 2); add(f); f = new Function("WEEKS", func_weeks); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFWEEKS"); f->setParamCount(3); add(f); f = new Function("WEEKSINYEAR", func_weeksInYear); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETWEEKSINYEAR"); add(f); f = new Function("WORKDAY", func_workday); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETWORKDAY"); f->setParamCount(2, 3); f->setAcceptArray(); add(f); f = new Function("YEAR", func_year); add(f); f = new Function("YEARFRAC", func_yearFrac); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETYEARFRAC"); f->setParamCount(2, 3); add(f); f = new Function("YEARS", func_years); f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETDIFFYEARS"); f->setParamCount(3); add(f); } QString DateTimeModule::descriptionFileName() const { return QString("datetime.xml"); } // Function: EDATE Value func_edate(valVector args, ValueCalc *calc, FuncExtra *) { QDate date = calc->conv()->asDate(args[0]).asDate(calc->settings()); int months = calc->conv()->asInteger(args[1]).asInteger(); date = calc->settings()->locale()->calendar()->addMonths(date, months); if (!date.isValid()) return Value::errorVALUE(); return Value(date, calc->settings()); } // Function: EOMONTH Value func_eomonth(valVector args, ValueCalc *calc, FuncExtra *) { // add months to date using EDATE Value modDate = func_edate(args, calc, 0); if (modDate.isError()) return modDate; // modDate is currently in Date format QDate date = modDate.asDate(calc->settings()); - date.setYMD(date.year(), date.month(), date.daysInMonth()); + date.setDate(date.year(), date.month(), date.daysInMonth()); return Value(date, calc->settings()); } // internal helper function static int func_days360_helper(const QDate& _date1, const QDate& _date2, bool european) { int day1, day2; int month1, month2; int year1, year2; QDate date1(_date1); QDate date2(_date2); if (date1.daysTo(date2) < 0) { QDate tmp(date1); date1 = date2; date2 = tmp; } day1 = date1.day(); day2 = date2.day(); month1 = date1.month(); month2 = date2.month(); year1 = date1.year(); year2 = date2.year(); if (european) { if (day1 == 31) day1 = 30; if (day2 == 31) day2 = 30; } else { // thanks to the Gnumeric developers for this... if (month1 == 2 && month2 == 2 && date1.daysInMonth() == day1 && date2.daysInMonth() == day2) day2 = 30; if (month1 == 2 && date1.daysInMonth() == day1) day1 = 30; if (day2 == 31 && day1 >= 30) day2 = 30; if (day1 == 31) day1 = 30; } return ((year2 - year1) * 12 + (month2 - month1)) * 30 + (day2 - day1); } // Function: DAYS360 // algorithm adapted from gnumeric Value func_days360(valVector args, ValueCalc *calc, FuncExtra *) { QDate date1 = calc->conv()->asDate(args[0]).asDate(calc->settings()); QDate date2 = calc->conv()->asDate(args[1]).asDate(calc->settings()); bool european = false; if (args.count() == 3) european = calc->conv()->asBoolean(args[2]).asBoolean(); return Value(func_days360_helper(date1, date2, european)); } // Function: YEAR Value func_year(valVector args, ValueCalc *calc, FuncExtra *) { Value v = calc->conv()->asDate(args[0]); if (v.isError()) return v; QDate date = v.asDate(calc->settings()); return Value(date.year()); } // Function: MONTH Value func_month(valVector args, ValueCalc *calc, FuncExtra *) { Value v = calc->conv()->asDate(args[0]); if (v.isError()) return v; QDate date = v.asDate(calc->settings()); return Value(date.month()); } // Function: DAY Value func_day(valVector args, ValueCalc *calc, FuncExtra *) { Value v = calc->conv()->asDate(args[0]); if (v.isError()) return v; QDate date = v.asDate(calc->settings()); return Value(date.day()); } // Function: HOUR Value func_hour(valVector args, ValueCalc *calc, FuncExtra *) { QTime time; if (args.count() == 1) { Value v = calc->conv()->asTime(args[0]); if (v.isError()) return v; time = v.asTime(); } else time = QTime::currentTime(); return Value(time.hour()); } // Function: MINUTE Value func_minute(valVector args, ValueCalc *calc, FuncExtra *) { QTime time; if (args.count() == 1) { Value v = calc->conv()->asTime(args[0]); if (v.isError()) return v; time = v.asTime(); } else time = QTime::currentTime(); return Value(time.minute()); } // Function: SECOND Value func_second(valVector args, ValueCalc *calc, FuncExtra *) { QTime time; if (args.count() == 1) { Value v = calc->conv()->asTime(args[0]); if (v.isError()) return v; time = v.asTime(); } else time = QTime::currentTime(); return Value(time.second() + qRound(time.msec() * 0.001)); } // Function: WEEKDAY Value func_weekday(valVector args, ValueCalc *calc, FuncExtra *) { Value v(calc->conv()->asDate(args[0])); if (v.isError()) return v; QDate date = v.asDate(calc->settings()); int method = 1; if (args.count() == 2) method = calc->conv()->asInteger(args[1]).asInteger(); if (method < 1 || method > 3) return Value::errorVALUE(); int result = date.dayOfWeek(); if (method == 3) --result; else if (method == 1) { ++result; if (result > 7) result = result % 7; } return Value(result); } // Function: DATEVALUE // same result would be obtained by applying number format on a date value Value func_datevalue(valVector args, ValueCalc *calc, FuncExtra *) { if (args[0].isString()) { Value v = calc->conv()->asDate(args[0]); if (! v.isError()) return calc->conv()->asFloat(v); } return Value::errorVALUE(); } // Function: timevalue // same result would be obtained by applying number format on a time value Value func_timevalue(valVector args, ValueCalc *calc, FuncExtra *) { if (args[0].isString()) { Value v = calc->conv()->asTime(args[0]); if (! v.isError()) return calc->conv()->asFloat(v); } return Value::errorVALUE(); } // Function: YEARS Value func_years(valVector args, ValueCalc *calc, FuncExtra *) { QDate date1 = calc->conv()->asDate(args[0]).asDate(calc->settings()); QDate date2 = calc->conv()->asDate(args[1]).asDate(calc->settings()); if (!date1.isValid() || !date2.isValid()) return Value::errorVALUE(); int type = calc->conv()->asInteger(args[2]).asInteger(); if (type == 0) { // max. possible years between both dates int years = date2.year() - date1.year(); if (date2.month() < date1.month()) --years; else if ((date2.month() == date1.month()) && (date2.day() < date1.day())) --years; return Value(years); } // type is non-zero now // the number of full years in between, starting on 1/1/XXXX if (date1.year() == date2.year()) return Value(0); if ((date1.month() != 1) || (date1.day() != 1)) - date1.setYMD(date1.year() + 1, 1, 1); - date2.setYMD(date2.year(), 1, 1); + date1.setDate(date1.year() + 1, 1, 1); + date2.setDate(date2.year(), 1, 1); return Value(date2.year() - date1.year()); } // Function: MONTHS Value func_months(valVector args, ValueCalc *calc, FuncExtra *) { QDate date1 = calc->conv()->asDate(args[0]).asDate(calc->settings()); QDate date2 = calc->conv()->asDate(args[1]).asDate(calc->settings()); if (!date1.isValid() || !date2.isValid()) return Value::errorVALUE(); int type = calc->conv()->asInteger(args[2]).asInteger(); if (type == 0) { int months = (date2.year() - date1.year()) * 12; months += date2.month() - date1.month(); if (date2.day() < date1.day()) if (date2.day() != date2.daysInMonth()) --months; return Value(months); } // type is now non-zero // the number of full months in between, starting on 1/XX/XXXX if (date1.month() == 12) - date1.setYMD(date1.year() + 1, 1, 1); + date1.setDate(date1.year() + 1, 1, 1); else - date1.setYMD(date1.year(), date1.month() + 1, 1); - date2.setYMD(date2.year(), date2.month(), 1); + date1.setDate(date1.year(), date1.month() + 1, 1); + date2.setDate(date2.year(), date2.month(), 1); int months = (date2.year() - date1.year()) * 12; months += date2.month() - date1.month(); return Value(months); } // Function: WEEKS Value func_weeks(valVector args, ValueCalc *calc, FuncExtra *) { QDate date1 = calc->conv()->asDate(args[0]).asDate(calc->settings()); QDate date2 = calc->conv()->asDate(args[1]).asDate(calc->settings()); if (!date1.isValid() || !date2.isValid()) return Value::errorVALUE(); int type = calc->conv()->asInteger(args[2]).asInteger(); int days = date1.daysTo(date2); if (type == 0) // just the number of full weeks between return Value((int)(days / 7)); // the number of full weeks between starting on mondays int weekStartDay = calc->settings()->locale()->weekStartDay(); int dow1 = date1.dayOfWeek(); int dow2 = date2.dayOfWeek(); days -= (7 + (weekStartDay % 7) - dow1); days -= ((dow2 - weekStartDay) % 7); return Value((int)(days / 7)); } // Function: DAYS Value func_days(valVector args, ValueCalc *calc, FuncExtra *) { QDate date1 = calc->conv()->asDate(args[0]).asDate(calc->settings()); QDate date2 = calc->conv()->asDate(args[1]).asDate(calc->settings()); if (!date1.isValid() || !date2.isValid()) return Value::errorVALUE(); return Value(date2.daysTo(date1)); } // Function: DATE Value func_date(valVector args, ValueCalc *calc, FuncExtra *) { int y = calc->conv()->asInteger(args[0]).asInteger(); int m = calc->conv()->asInteger(args[1]).asInteger(); int d = calc->conv()->asInteger(args[2]).asInteger(); if (m == 0 || d == 0) return Value::errorVALUE(); // month or day zero is not allowed else { QDate tmpDate(y, 1, 1); tmpDate = tmpDate.addMonths(m - 1); tmpDate = tmpDate.addDays(d - 1); //debugSheetsFormula <<"func_date:: date =" << tmpDate; return Value(tmpDate, calc->settings()); } } // Function: DAY Value func_dayname(valVector args, ValueCalc *calc, FuncExtra *) { int number = calc->conv()->asInteger(args[0]).asInteger(); QString weekName = calc->settings()->locale()->calendar()->weekDayName(number); if (weekName.isNull()) return Value::errorVALUE(); return Value(weekName); } // Function: MONTHNAME Value func_monthname(valVector args, ValueCalc *calc, FuncExtra *) { int number = calc->conv()->asInteger(args[0]).asInteger(); QString monthName = calc->settings()->locale()->calendar()->monthName(number, QDate::currentDate().year()); if (monthName.isNull()) return Value::errorVALUE(); return Value(monthName); } // Function: TIME Value func_time(valVector args, ValueCalc *calc, FuncExtra *) { int h = calc->conv()->asInteger(args[0]).asInteger(); int m = calc->conv()->asInteger(args[1]).asInteger(); int s = calc->conv()->asInteger(args[2]).asInteger(); QTime res(0, 0); res = res.addSecs(60 * 60 * h); res = res.addSecs(60 * m); res = res.addSecs(s); return Value(res); } // Function: CURRENTDATE Value func_currentDate(valVector, ValueCalc * calc, FuncExtra *) { return Value(QDate::currentDate(), calc->settings()); } // Function: CURRENTTIME Value func_currentTime(valVector, ValueCalc * calc, FuncExtra *) { return Value(QTime::currentTime()); } // Function: CURRENTDATETIME Value func_currentDateTime(valVector, ValueCalc * calc, FuncExtra *) { return Value(QDateTime::currentDateTime(), calc->settings()); } // Function: DAYOFYEAR Value func_dayOfYear(valVector args, ValueCalc *calc, FuncExtra *) { Value date = func_date(args, calc, 0); if (date.isError()) return date; return Value(date.asDate(calc->settings()).dayOfYear()); } // Function: DAYSINMONTH Value func_daysInMonth(valVector args, ValueCalc *calc, FuncExtra *) { int y = calc->conv()->asInteger(args[0]).asInteger(); int m = calc->conv()->asInteger(args[1]).asInteger(); QDate date(y, m, 1); return Value(date.daysInMonth()); } // Function: ISLEAPYEAR Value func_isLeapYear(valVector args, ValueCalc *calc, FuncExtra *) { int y = calc->conv()->asInteger(args[0]).asInteger(); return Value(QDate::isLeapYear(y)); } // Function: DAYSINYEAR Value func_daysInYear(valVector args, ValueCalc *calc, FuncExtra *) { int y = calc->conv()->asInteger(args[0]).asInteger(); return Value(QDate::isLeapYear(y) ? 366 : 365); } // Function: WEEKSINYEAR Value func_weeksInYear(valVector args, ValueCalc *calc, FuncExtra *) { int y = calc->conv()->asInteger(args[0]).asInteger(); QDate date(y, 12, 31); // last day of the year int yearNumber; int weekNumber = date.weekNumber(&yearNumber); // day assigned to first week of next year? if (yearNumber != y) { // take weekday the week before then date = date.addDays(-7); weekNumber = date.weekNumber(); } return Value(weekNumber); } // Function: EASTERSUNDAY Value func_easterSunday(valVector args, ValueCalc *calc, FuncExtra *) { int nDay, nMonth; int nYear = calc->conv()->asInteger(args[0]).asInteger(); // (Tomas) the person who wrote this should be hanged :> int B, C, D, E, F, G, H, I, K, L, M, N, O; N = nYear % 19; B = int(nYear / 100); C = nYear % 100; D = int(B / 4); E = B % 4; F = int((B + 8) / 25); G = int((B - F + 1) / 3); H = (19 * N + B - D - G + 15) % 30; I = int(C / 4); K = C % 4; L = (32 + 2 * E + 2 * I - H - K) % 7; M = int((N + 11 * H + 22 * L) / 451); O = H + L - 7 * M + 114; nDay = O % 31 + 1; nMonth = int(O / 31); return Value(QDate(nYear, nMonth, nDay), calc->settings()); } // Function: ISOWEEKNUM // // method startday name of day // default: 1 1 sunday // 2 0 monday // Value func_isoWeekNum(valVector args, ValueCalc *calc, FuncExtra *) { QDate date = calc->conv()->asDate(args[0]).asDate(calc->settings()); if (!date.isValid()) return Value::errorVALUE(); int method = 2; // default method = 2 if (args.count() > 1) method = calc->conv()->asInteger(args[1]).asInteger(); if (method < 1 || method > 2) return Value::errorVALUE(); int startday = 1; if (method != 1) startday = 0; int weeknum; int day; // current date int day4; // 4th of jan. int day0; // offset to 4th of jan. // date to find day = date.toJulianDay(); // 4th of jan. of current year day4 = QDate(date.year(), 1, 4).toJulianDay(); // difference in days to the 4th of jan including correction of startday day0 = QDate::fromJulianDay(day4 - 1 + startday).dayOfWeek(); // do we need to count from last year? if (day < day4 - day0) { // recalculate day4 and day0 day4 = QDate(date.year() - 1, 1, 4).toJulianDay(); // 4th of jan. last year day0 = QDate::fromJulianDay(day4 - 1 + startday).dayOfWeek(); } // calc weeeknum weeknum = (day - (day4 - day0)) / 7 + 1; // if weeknum is greater 51, we have to do some extra checks if (weeknum >= 52) { day4 = QDate(date.year() + 1, 1, 4).toJulianDay(); // 4th of jan. next year day0 = QDate::fromJulianDay(day4 - 1 + startday).dayOfWeek(); if (day >= day4 - day0) { // recalculate weeknum weeknum = (day - (day4 - day0)) / 7 + 1; } } return Value(weeknum); } // Function: WEEKNUM // // method startday name of day // default: 1 0 sunday // 2 -1 monday // // weeknum = (startday + 7 + dayOfWeek of New Year + difference in days) / 7 // Value func_weekNum(valVector args, ValueCalc *calc, FuncExtra *) { Value v(calc->conv()->asDate(args[0])); if (v.isError()) return v; QDate date = v.asDate(calc->settings()); if (!date.isValid()) return Value::errorVALUE(); int method = 1; if (args.count() > 1) method = calc->conv()->asInteger(args[1]).asInteger(); if (method < 1 || method > 2) return Value::errorVALUE(); QDate date1(date.year(), 1, 1); int days = date1.daysTo(date); int startday = 0; if (method == 2) startday = -1; int res = (int)((startday + 7 + date1.dayOfWeek() + days) / 7); if (date1.dayOfWeek() == 7 && method == 1) res--; //debugSheetsFormula <<"weeknum = [startday(" << startday <<") + base(7) + New Year(" << date1.dayOfWeek() <<") + days(" << days <<")] / 7 =" << res; return Value(res); } // Function: DATEDIF // // interval difference | type description // --------------------|---------------------------------- // default: m | months // d | days // y | complete years // ym | months excluding years // yd | days excluding years // md | days excluding months and years // Value func_dateDif(valVector args, ValueCalc *calc, FuncExtra *) { Value v1(calc->conv()->asDate(args[0])); if (v1.isError()) return v1; QDate date1 = v1.asDate(calc->settings()); if (!date1.isValid()) return Value::errorVALUE(); Value v2(calc->conv()->asDate(args[1])); if (v2.isError()) return v2; QDate date2 = v2.asDate(calc->settings()); if (!date2.isValid()) return Value::errorVALUE(); // check if interval is valid QString interval = calc->conv()->asString(args[2]).asString(); if (!(interval == "m" || interval == "d" || interval == "y" || interval == "ym" || interval == "yd" || interval == "md")) return Value::errorVALUE(); // local vars int y, m, d; int sign = 1; // default int res = 0; QDate Temp1, Temp2; //QDate date0(1899,12,30); // referenceDate QDate date0 = calc->settings()->referenceDate(); if (date2 < date1) { // exchange values and set sign Temp1 = date1; date1 = date2; date2 = Temp1; sign = -1; } // // calculate // // Temp1 = DateSerial(Year(Date2), Month(Date1), Day(Date1)) Temp1.setDate(date2.year(), date1.month(), date1.day()); // Y = Year(Date2) - Year(Date1) + (Temp1 > Date2) y = date2.year() - date1.year() + (date0.daysTo(Temp1) > date0.daysTo(date2) ? -1 : 0); // M = Month(Date2) - Month(Date1) - (12 * (Temp1 > Date2)) m = date2.month() - date1.month() - (12 * (Temp1 > date2 ? -1 : 0)); // D = Day(Date2) - Day(Date1) d = date2.day() - date1.day(); if (d < 0) { // M = M - 1 m--; // D = Day(DateSerial(Year(date2), Month(date2), 0)) + D Temp2.setDate(date2.year(), date2.month() - 1, 1); d = Temp2.daysInMonth() + d; } // // output // if (interval == "y") { // year res = y * sign; } else if (interval == "m") { // month res = (12 * y + m) * sign; } else if (interval == "d") { // days int days = date0.daysTo(date2) - date0.daysTo(date1); res = days * sign; } else if (interval == "ym") { // month excl. years res = m * sign; } else if (interval == "yd") { // days excl. years QDate Temp3(date2.year(), date1.month(), date1.day()); int days = date0.daysTo(date2) - date0.daysTo(Temp3); res = days * sign; } else if (interval == "md") { // days excl. month and years res = d * sign; } return Value(res); } // Function: YEARFRAC // // | basis | description day-count // -----------|--------|-------------------------------------------------------- // default: | 0 | US (NASD) system. 30 days/month, 360 days/year (30/360) // | 1 | Actual/actual (Euro), also known as AFB // | 2 | Actual/360 // | 3 | Actual/365 // | 4 | European 30/360 // Value func_yearFrac(valVector args, ValueCalc *calc, FuncExtra *) { Value v1(calc->conv()->asDate(args[0])); if (v1.isError()) return v1; QDate date1 = v1.asDate(calc->settings()); if (!date1.isValid()) return Value::errorVALUE(); Value v2(calc->conv()->asDate(args[1])); if (v2.isError()) return v2; QDate date2 = v2.asDate(calc->settings()); if (!date2.isValid()) return Value::errorVALUE(); // check if basis is valid int basis = 0; if (args.count() > 2) basis = calc->conv()->asInteger(args[2]).asInteger(); if (basis < 0 || basis > 4) return Value::errorVALUE(); QDate date0 = calc->settings()->referenceDate(); // referenceDate return Value(yearFrac(date0, date1, date2, basis)); } // Function: WORKDAY // // - negative days count backwards // - if holidays is not an array it is only added to days (neg. are not allowed) // Value func_workday(valVector args, ValueCalc *calc, FuncExtra *e) { Value v(calc->conv()->asDate(args[0])); if (v.isError()) return v; QDate startdate = v.asDate(calc->settings()); if (!startdate.isValid()) return Value::errorVALUE(); // // vars // int days = calc->conv()->asInteger(args[1]).asInteger(); QDate date0 = calc->settings()->referenceDate(); // referenceDate QDate enddate = startdate; // enddate valVector holidays; // stores holidays int sign = 1; // sign 1 = forward, -1 = backward if (days < 0) { // change sign and set count to ccw days = days * -1; sign = -1; } // // check for holidays // if (args.count() > 2) { if (args[2].type() == Value::Array) { // parameter is array unsigned int row1, col1, rows, cols; row1 = e->ranges[2].row1; col1 = e->ranges[2].col1; rows = e->ranges[2].row2 - row1 + 1; cols = e->ranges[2].col2 - col1 + 1; Value holiargs = args[2]; for (unsigned r = 0; r < rows; ++r) { for (unsigned c = 0; c < cols; ++c) { // only append if element is a valid date if (!holiargs.element(c + col1, r + row1).isEmpty()) { Value v(calc->conv()->asDate(holiargs.element(c + col1, r + row1))); if (v.isError()) return Value::errorVALUE(); if (v.asDate(calc->settings()).isValid()) holidays.append(v); } } // cols } // rows } else { // no array parameter if (args[2].isString()) { // isString Value v(calc->conv()->asDate(args[2])); if (v.isError()) return Value::errorVALUE(); if (v.asDate(calc->settings()).isValid()) holidays.append(v); } else { // isNumber int hdays = calc->conv()->asInteger(args[2]).asInteger(); if (hdays < 0) return Value::errorVALUE(); days = days + hdays; } } } // // count days // while (days) { // exclude weekends and holidays do { enddate = enddate.addDays(1 * sign); } while (enddate.dayOfWeek() > 5 || holidays.contains(Value(date0.daysTo(enddate)))); days--; } return Value(enddate, calc->settings()); } // Function: NETWORKDAY // // - if holidays is not an array it is only added to days (neg. are not allowed) // Value func_networkday(valVector args, ValueCalc *calc, FuncExtra *e) { Value v1(calc->conv()->asDate(args[0])); if (v1.isError()) return v1; QDate startdate = v1.asDate(calc->settings()); Value v2(calc->conv()->asDate(args[1])); if (v2.isError()) return v2; QDate enddate = v2.asDate(calc->settings()); if (!startdate.isValid() || !enddate.isValid()) return Value::errorVALUE(); int days = 0; // workdays QDate date0 = calc->settings()->referenceDate(); // referenceDate valVector holidays; // stores holidays int sign = 1; // sign 1 = forward, -1 = backward if (enddate < startdate) { // change sign and set count to ccw sign = -1; } // // check for holidays // if (args.count() > 2) { if (args[2].type() == Value::Array) { // parameter is array unsigned int row1, col1, rows, cols; row1 = e->ranges[2].row1; col1 = e->ranges[2].col1; rows = e->ranges[2].row2 - row1 + 1; cols = e->ranges[2].col2 - col1 + 1; Value holiargs = args[2]; for (unsigned r = 0; r < rows; ++r) { for (unsigned c = 0; c < cols; ++c) { // only append if element is a valid date if (!holiargs.element(c + col1, r + row1).isEmpty()) { Value v(calc->conv()->asDate(holiargs.element(c + col1, r + row1))); if (v.isError()) return Value::errorVALUE(); if (v.asDate(calc->settings()).isValid()) holidays.append(v); } } // cols } // rows } else { // no array parameter if (args[2].isString()) { Value v(calc->conv()->asDate(args[2])); if (v.isError()) return Value::errorVALUE(); if (v.asDate(calc->settings()).isValid()) holidays.append(v); } else { // isNumber int hdays = calc->conv()->asInteger(args[2]).asInteger(); if (hdays < 0) return Value::errorVALUE(); days = days - hdays; } } } // // count days // while (startdate != enddate) { if (startdate.dayOfWeek() > 5 || holidays.contains(Value(date0.daysTo(startdate)))) { startdate = startdate.addDays(1 * sign); continue; } startdate = startdate.addDays(1 * sign); days++; } return Value(days); } // Function: DATE2UNIX // // Gnumeric docs says 01/01/2000 = 946656000 // TODO: // - create FormatType mm/dd/yyyy hh:mm:ss // - add method tryParseDateTime Value func_unix2date(valVector args, ValueCalc *calc, FuncExtra *) { const Value v(calc->conv()->asInteger(args[0])); if (v.isError()) return v; QDateTime datetime; datetime.setTimeSpec(Qt::UTC); datetime.setTime_t(v.asInteger()); return Value(datetime, calc->settings()); } // Function: UNIX2DATE Value func_date2unix(valVector args, ValueCalc *calc, FuncExtra *) { const Value v(calc->conv()->asDateTime(args[0])); if (v.isError()) return v; const QDateTime datetime(v.asDateTime(calc->settings())); return Value(static_cast(datetime.toTime_t())); } #include "datetime.moc"