/*************************************************************************** * Copyright (C) 2006, 2007 by Niklas Knutsson * * nq@altern.org * * * * 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., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "overtimechart.h" #include "budget.h" #include "account.h" #include "transaction.h" #include "recurrence.h" #include "eqonomizemonthselector.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct chart_month_info { double value; double count; QDate date; }; extern int months_between_dates(const QDate &date1, const QDate &date2); extern QDate addMonths(const QDate &date, int nmonths); OverTimeChart::OverTimeChart(Budget *budg, QWidget *parent, bool extra_parameters) : QWidget(parent), budget(budg), b_extra(extra_parameters) { setWFlags(getWFlags() | Qt::WDestructiveClose); const KCalendarSystem *calSys = KGlobal::locale()->calendar(); QVBoxLayout *layout = new QVBoxLayout(this, 6, 6); KButtonBox *buttons = new KButtonBox(this); buttons->addStretch(1); saveButton = buttons->addButton(KStdGuiItem::saveAs()); printButton = buttons->addButton(KStdGuiItem::print()); buttons->layout(); layout->addWidget(buttons); canvas = NULL; view = new QCanvasView(this); layout->addWidget(view); KConfig *config = kapp->config(); config->setGroup("Over Time Chart"); QGroupBox *settingsGroup = new QGroupBox(1, Qt::Horizontal, i18n("Options"), this); QWidget *settingsWidget = new QWidget(settingsGroup); QGridLayout *settingsLayout = new QGridLayout(settingsWidget, 3, 2, 0, 6); QLabel *sourceLabel = new QLabel(i18n("Source:"), settingsWidget); settingsLayout->addWidget(sourceLabel, 2, 0); QHBoxLayout *choicesLayout = new QHBoxLayout(); settingsLayout->addLayout(choicesLayout, 2, 1); QGridLayout *choicesLayout_extra = NULL; if(b_extra) { sourceLabel->setAlignment(Qt::AlignAuto | Qt::AlignTop); choicesLayout_extra = new QGridLayout(choicesLayout, 2, 2); } sourceCombo = new KComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->insertItem(i18n("Incomes and Expenses")); sourceCombo->insertItem(i18n("Profits")); sourceCombo->insertItem(i18n("Expenses")); sourceCombo->insertItem(i18n("Incomes")); if(b_extra) choicesLayout_extra->addWidget(sourceCombo, 0, 0); else choicesLayout->addWidget(sourceCombo); categoryCombo = new KComboBox(settingsWidget); categoryCombo->setEditable(false); categoryCombo->insertItem(i18n("All Categories Combined")); categoryCombo->setEnabled(false); if(b_extra) choicesLayout_extra->addWidget(categoryCombo, 0, 1); else choicesLayout->addWidget(categoryCombo); descriptionCombo = new KComboBox(settingsWidget); descriptionCombo->setEditable(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); descriptionCombo->setEnabled(false); if(b_extra) choicesLayout_extra->addWidget(descriptionCombo, 1, 0); else choicesLayout->addWidget(descriptionCombo); payeeCombo = NULL; if(b_extra) { payeeCombo = new KComboBox(settingsWidget); payeeCombo->setEditable(false); payeeCombo->insertItem(i18n("All Payees/Payers Combined")); payeeCombo->setEnabled(false); choicesLayout_extra->addWidget(payeeCombo, 1, 1); choicesLayout->addStretch(1); } current_account = NULL; current_source = 0; settingsLayout->addWidget(new QLabel(i18n("Start date:"), settingsWidget), 0, 0); QHBoxLayout *monthLayout = new QHBoxLayout(); settingsLayout->addLayout(monthLayout, 0, 1); startDateEdit = new EqonomizeMonthSelector(settingsWidget); Transaction *trans = budget->transactions.first(); while(trans) { if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { start_date = trans->date(); if(calSys->day(start_date) > 1) { start_date = addMonths(start_date, 1); calSys->setYMD(start_date, calSys->year(start_date), calSys->month(start_date), 1); } break; } trans = budget->transactions.next(); } if(start_date.isNull() || start_date > QDate::currentDate()) start_date = QDate::currentDate(); if(calSys->month(start_date) == calSys->month(QDate::currentDate()) && calSys->year(start_date) == calSys->year(QDate::currentDate())) { start_date = addMonths(start_date, -1); calSys->setYMD(start_date, calSys->year(start_date), calSys->month(start_date), 1); } startDateEdit->setDate(start_date); monthLayout->addWidget(startDateEdit); monthLayout->addWidget(new QLabel(i18n("End date:"), settingsWidget)); endDateEdit = new EqonomizeMonthSelector(settingsWidget); end_date = calSys->addDays(QDate::currentDate(), -1); if(calSys->day(end_date) < calSys->daysInMonth(end_date)) { end_date = addMonths(end_date, -1); calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); } if(end_date <= start_date || (calSys->month(start_date) == calSys->month(end_date) && calSys->year(start_date) == calSys->year(end_date))) { end_date = QDate::currentDate(); calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); } endDateEdit->setDate(end_date); monthLayout->addWidget(endDateEdit); monthLayout->addStretch(1); settingsLayout->addWidget(new QLabel(i18n("Value:"), settingsWidget), 1, 0); QHBoxLayout *enabledLayout = new QHBoxLayout(); settingsLayout->addLayout(enabledLayout, 1, 1); valueGroup = new QButtonGroup(); valueButton = new QRadioButton(i18n("Monthly total"), settingsWidget); valueButton->setChecked(config->readBoolEntry("valueSelected", true)); valueGroup->insert(valueButton); enabledLayout->addWidget(valueButton); dailyButton = new QRadioButton(i18n("Daily average"), settingsWidget); dailyButton->setChecked(config->readBoolEntry("dailyAverageSelected", false)); valueGroup->insert(dailyButton); enabledLayout->addWidget(dailyButton); countButton = new QRadioButton(i18n("Quantity"), settingsWidget); countButton->setChecked(config->readBoolEntry("transactionCountSelected", false)); valueGroup->insert(countButton); enabledLayout->addWidget(countButton); perButton = new QRadioButton(i18n("Average value"), settingsWidget); perButton->setChecked(config->readBoolEntry("valuePerTransactionSelected", false)); valueGroup->insert(perButton); enabledLayout->addWidget(perButton); enabledLayout->addStretch(1); layout->addWidget(settingsGroup); connect(startDateEdit, SIGNAL(monthChanged(const QDate&)), this, SLOT(startMonthChanged(const QDate&))); connect(startDateEdit, SIGNAL(yearChanged(const QDate&)), this, SLOT(startYearChanged(const QDate&))); connect(endDateEdit, SIGNAL(monthChanged(const QDate&)), this, SLOT(endMonthChanged(const QDate&))); connect(endDateEdit, SIGNAL(yearChanged(const QDate&)), this, SLOT(endYearChanged(const QDate&))); connect(valueButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(dailyButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(countButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(perButton, SIGNAL(toggled(bool)), this, SLOT(valueTypeToggled(bool))); connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(categoryCombo, SIGNAL(activated(int)), this, SLOT(categoryChanged(int))); connect(descriptionCombo, SIGNAL(activated(int)), this, SLOT(descriptionChanged(int))); if(b_extra) connect(payeeCombo, SIGNAL(activated(int)), this, SLOT(payeeChanged(int))); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); } OverTimeChart::~OverTimeChart() { delete valueGroup; } void OverTimeChart::valueTypeToggled(bool b) { if(b) updateDisplay(); } void OverTimeChart::payeeChanged(int index) { current_payee = ""; bool b_income = (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); int d_index = descriptionCombo->currentItem(); if(index == 0) { if(d_index == 1) current_source = b_income ? 7 : 8; else if(d_index == 0) current_source = b_income ? 5 : 6; else current_source = b_income ? 9 : 10; } else if(index == 1) { if(d_index == 1) { descriptionCombo->blockSignals(true); descriptionCombo->setCurrentItem(0); descriptionCombo->blockSignals(false); d_index = 0; } if(d_index == 0) current_source = b_income ? 11 : 12; else current_source = b_income ? 13 : 14; } else { if(!has_empty_payee || index < payeeCombo->count() - 1) current_payee = payeeCombo->text(index); if(d_index == 1) current_source = b_income ? 17 : 18; else if(d_index == 0) current_source = b_income ? 15 : 16; else current_source = b_income ? 19 : 20; } updateDisplay(); } void OverTimeChart::descriptionChanged(int index) { current_description = ""; bool b_income = (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); int p_index = 0; if(b_extra) p_index = payeeCombo->currentItem(); if(index == 0) { if(p_index == 1) current_source = b_income ? 11 : 12; else if(p_index == 0) current_source = b_income ? 5 : 6; else current_source = b_income ? 15 : 16; } else if(index == 1) { if(p_index == 1) { payeeCombo->blockSignals(true); payeeCombo->setCurrentItem(0); payeeCombo->blockSignals(false); p_index = 0; } if(p_index == 0) current_source = b_income ? 7 : 8; else current_source = b_income ? 17 : 18; } else { if(!has_empty_description || index < descriptionCombo->count() - 1) current_description = descriptionCombo->text(index); if(p_index == 1) current_source = b_income ? 13 : 14; else if(p_index == 0) current_source = b_income ? 9 : 10; else current_source = b_income ? 19 : 20; } updateDisplay(); } void OverTimeChart::categoryChanged(int index) { bool b_income = (sourceCombo->currentItem() == 3); descriptionCombo->blockSignals(true); int d_index = descriptionCombo->currentItem(); descriptionCombo->clear(); descriptionCombo->insertItem(i18n("All Descriptions Combined")); int p_index = 0; current_description = ""; current_payee = ""; if(b_extra) { p_index = payeeCombo->currentItem(); payeeCombo->blockSignals(true); payeeCombo->clear(); if(b_income) payeeCombo->insertItem(i18n("All Payers Combined")); else payeeCombo->insertItem(i18n("All Payees Combined")); } current_account = NULL; if(index == 0) { if(b_income) { current_source = 1; } else { current_source = 2; } descriptionCombo->setEnabled(false); if(b_extra) payeeCombo->setEnabled(false); } else if(index == 1) { if(b_income) { current_source = 3; } else { current_source = 4; } descriptionCombo->setEnabled(false); if(b_extra) payeeCombo->setEnabled(false); } else { descriptionCombo->insertItem(i18n("All Descriptions Split")); if(d_index == 1) descriptionCombo->setCurrentItem(1); if(b_extra) { if(b_income) payeeCombo->insertItem(i18n("All Payers Split")); else payeeCombo->insertItem(i18n("All Payees Split")); if(p_index == 1 && d_index != 1) payeeCombo->setCurrentItem(1); } if(!b_income) { int i = categoryCombo->currentItem() - 2; if(i < (int) budget->expensesAccounts.count()) { current_account = budget->expensesAccounts.at(i); } if(d_index == 1) current_source = 8; else if(p_index == 1) current_source = 12; else current_source = 6; } else { int i = categoryCombo->currentItem() - 2; if(i < (int) budget->incomesAccounts.count()) { current_account = budget->incomesAccounts.at(i); } if(d_index == 1) current_source = 7; else if(p_index == 1) current_source = 11; else current_source = 5; } has_empty_description = false; has_empty_payee = false; QMap descriptions, payees; Transaction *trans = budget->transactions.first(); while(trans) { if((trans->fromAccount() == current_account || trans->toAccount() == current_account)) { if(trans->description().isEmpty()) has_empty_description = true; else descriptions[trans->description()] = true; if(b_extra) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { if(((Expense*) trans)->payee().isEmpty()) has_empty_payee = true; else payees[((Expense*) trans)->payee()] = true; } else if(trans->type() == TRANSACTION_TYPE_INCOME) { if(((Income*) trans)->payer().isEmpty()) has_empty_payee = true; else payees[((Income*) trans)->payer()] = true; } } } trans = budget->transactions.next(); } QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { descriptionCombo->insertItem(it.key()); } if(has_empty_description) descriptionCombo->insertItem(i18n("No description")); descriptionCombo->setEnabled(true); if(b_extra) { QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { payeeCombo->insertItem(it2.key()); } if(has_empty_payee) { if(b_income) payeeCombo->insertItem(i18n("No payer")); else payeeCombo->insertItem(i18n("No payee")); } payeeCombo->setEnabled(true); } } descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); updateDisplay(); } void OverTimeChart::sourceChanged(int index) { categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(b_extra) payeeCombo->blockSignals(true); int c_index = 1; if(categoryCombo->count() > 1 && categoryCombo->currentItem() == 0) c_index = 0; categoryCombo->clear(); descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); if(b_extra) { payeeCombo->clear(); payeeCombo->setEnabled(false); if(index == 2) payeeCombo->insertItem(i18n("All Payers Combined")); else if(index == 1) payeeCombo->insertItem(i18n("All Payees Combined")); else payeeCombo->insertItem(i18n("All Payees/Payers Combined")); } current_description = ""; current_payee = ""; current_account = NULL; categoryCombo->insertItem(i18n("All Categories Combined")); if(index == 3) { categoryCombo->insertItem(i18n("All Categories Split")); categoryCombo->setCurrentItem(c_index); Account *account = budget->incomesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); account = budget->incomesAccounts.next(); } categoryCombo->setEnabled(true); current_source = 3; } else if(index == 2) { categoryCombo->insertItem(i18n("All Categories Split")); categoryCombo->setCurrentItem(c_index); Account *account = budget->expensesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); account = budget->expensesAccounts.next(); } categoryCombo->setEnabled(true); current_source = 4; } else if(index == 1) { categoryCombo->setEnabled(false); current_source = -1; if(countButton->isChecked() || perButton->isChecked()) { valueButton->blockSignals(true); countButton->blockSignals(true); perButton->blockSignals(true); valueButton->setChecked(true); countButton->setChecked(false); perButton->setChecked(false); valueButton->blockSignals(false); countButton->blockSignals(false); perButton->blockSignals(false); } } else { categoryCombo->setEnabled(false); current_source = 0; } countButton->setEnabled(index != 1); perButton->setEnabled(index != 1); categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); updateDisplay(); } void OverTimeChart::startYearChanged(const QDate &date) { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); bool error = false; if(!date.isValid()) { KMessageBox::error(this, i18n("Invalid date.")); error = true; } /*if(!error && date > QDate::currentDate()) { if(calSys->year(date) == calSys->year(QDate::currentDate())) { start_date = QDate::currentDate(); calSys->setYMD(start_date, calSys->year(start_date), calSys->month(start_date), 1); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); updateDisplay(); return; } else { KMessageBox::error(this, i18n("Future dates are not allowed.")); error = true; } }*/ if(!error && date > end_date) { end_date = date; calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } if(error) { startDateEdit->focusYear(); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); return; } start_date = date; updateDisplay(); } void OverTimeChart::startMonthChanged(const QDate &date) { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); bool error = false; if(!date.isValid()) { KMessageBox::error(this, i18n("Invalid date.")); error = true; } /*if(!error && date > QDate::currentDate()) { KMessageBox::error(this, i18n("Future dates are not allowed.")); error = true; }*/ if(!error && date > end_date) { end_date = date; calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); } if(error) { startDateEdit->focusMonth(); startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); return; } start_date = date; updateDisplay(); } void OverTimeChart::endYearChanged(const QDate &date) { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); bool error = false; if(!date.isValid()) { KMessageBox::error(this, i18n("Invalid date.")); error = true; } /*if(!error && date > QDate::currentDate()) { if(calSys->year(date) == calSys->year(QDate::currentDate())) { end_date = QDate::currentDate(); calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), 1); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); updateDisplay(); return; } else { KMessageBox::error(this, i18n("Future dates are not allowed.")); error = true; } }*/ if(!error && date < start_date) { start_date = date; startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } if(error) { endDateEdit->focusYear(); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); return; } end_date = date; calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); updateDisplay(); } void OverTimeChart::endMonthChanged(const QDate &date) { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); bool error = false; if(!date.isValid()) { KMessageBox::error(this, i18n("Invalid date.")); error = true; } /*if(!error && date > QDate::currentDate()) { KMessageBox::error(this, i18n("Future dates are not allowed.")); error = true; }*/ if(!error && date < start_date) { start_date = date; startDateEdit->blockSignals(true); startDateEdit->setDate(start_date); startDateEdit->blockSignals(false); } if(error) { endDateEdit->focusMonth(); endDateEdit->blockSignals(true); endDateEdit->setDate(end_date); endDateEdit->blockSignals(false); return; } end_date = date; calSys->setYMD(end_date, calSys->year(end_date), calSys->month(end_date), calSys->daysInMonth(end_date)); updateDisplay(); } void OverTimeChart::saveConfig() { KConfig *config = kapp->config(); ((KDialogBase*) parent())->saveDialogSize(*config, "Over Time Chart"); config->setGroup("Over Time Chart"); config->writeEntry("valueSelected", valueButton->isChecked()); config->writeEntry("dailyAverageSelected", dailyButton->isChecked()); config->writeEntry("transactionCountSelected", countButton->isChecked()); config->writeEntry("valuePerTransactionSelected", perButton->isChecked()); } void OverTimeChart::save() { if(!canvas) return; KFileDialog *dialog = new KFileDialog(QString::null, QString::null, this, NULL, true); QStringList filter; filter << "image/png"; if(QImageIO::outputFormats().contains("GIF")) { filter << "image/gif"; } if(QImageIO::outputFormats().contains("JPEG")) { filter << "image/jpeg"; } filter << "image/x-bmp"; filter << "image/x-xbm"; filter << "image/x-xpm"; filter << "image/x-portable-pixmap"; dialog->setMimeFilter(filter, "image/png"); dialog->setOperationMode(KFileDialog::Saving); dialog->setMode(KFile::File); if(dialog->exec() != QDialog::Accepted) {dialog->deleteLater(); return;} KURL url = dialog->selectedURL(); QString current_filter = dialog->currentFilter(); dialog->deleteLater(); if(url.isEmpty() && url.isValid()) return; if(url.isLocalFile()) { if(QFile::exists(url.path())) { if(KMessageBox::warningYesNo(this, i18n("The selected file already exists. Would you like to overwrite the old copy?")) != KMessageBox::Yes) return; } QFileInfo info(url.path()); if(info.isDir()) { KMessageBox::error(this, i18n("You selected a directory!")); return; } KSaveFile ofile(url.path(), 0660); if(ofile.status()) { ofile.abort(); KMessageBox::error(this, i18n("Couldn't open file for writing.")); return; } QPixmap pixmap(min_width, min_height); QPainter p(&pixmap); canvas->drawArea(QRect(0, 0, min_width, min_height), &p); if(current_filter == "image/png") {pixmap.save(ofile.file(), "PNG");} else if(current_filter == "image/x-bmp") {pixmap.save(ofile.file(), "BMP");} else if(current_filter == "image/x-xbm") {pixmap.save(ofile.file(), "XBM");} else if(current_filter == "image/x-xpm") {pixmap.save(ofile.file(), "XPM");} else if(current_filter == "image/x-portable-pixmap") {pixmap.save(ofile.file(), "PPM");} else if(current_filter == "image/gif") {pixmap.save(ofile.file(), "GIF");} else if(current_filter == "image/jpeg") {pixmap.save(ofile.file(), "JPEG");} if(ofile.status()) { ofile.abort(); KMessageBox::error(this, i18n("Error while writing file; file was not saved.")); return; } ofile.close(); if(ofile.status()) { KMessageBox::error(this, i18n("Error after saving file; data may not have been saved.")); return; } return; } KTempFile tf; tf.setAutoDelete(true); QPixmap pixmap(min_width, min_height); QPainter p(&pixmap); canvas->drawArea(QRect(0, 0, min_width, min_height), &p); if(current_filter == "image/png") {pixmap.save(tf.file(), "PNG");} else if(current_filter == "image/x-bmp") {pixmap.save(tf.file(), "BMP");} else if(current_filter == "image/x-xbm") {pixmap.save(tf.file(), "XBM");} else if(current_filter == "image/x-xpm") {pixmap.save(tf.file(), "XPM");} else if(current_filter == "image/x-portable-pixmap") {pixmap.save(tf.file(), "PPM");} else if(current_filter == "image/gif") {pixmap.save(tf.file(), "GIF");} else if(current_filter == "image/jpeg") {pixmap.save(tf.file(), "JPEG");} KIO::NetAccess::upload(tf.name(), url, this); } void OverTimeChart::print() { if(!canvas) return; KPrinter pr; if(pr.setup(this)) { QPainter p(&pr); canvas->drawArea(QRect(0, 0, min_width, min_height), &p); } } QColor getColor2(int index) { switch(index % 11) { case 0: {return Qt::red;} case 1: {return Qt::blue;} case 2: {return Qt::cyan;} case 3: {return Qt::magenta;} case 4: {return Qt::green;} case 5: {return Qt::darkRed;} case 6: {return Qt::darkGreen;} case 7: {return Qt::darkBlue;} case 8: {return Qt::darkCyan;} case 9: {return Qt::darkMagenta;} case 10: {return Qt::darkYellow;} default: {return Qt::gray;} } } QPen getPen(int index) { QPen pen; pen.setWidth(2); switch(index / 11) { case 0: {pen.setStyle(Qt::SolidLine); break;} case 1: {pen.setStyle(Qt::DashLine); break;} case 3: {pen.setStyle(Qt::DashDotLine); break;} case 4: {pen.setStyle(Qt::DashDotDotLine); break;} default: {} } pen.setColor(getColor2(index)); return pen; } void OverTimeChart::updateDisplay() { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); QValueVector monthly_incomes, monthly_expenses; QMap > monthly_cats; QMap mi_c; QMap > monthly_desc; QMap mi_d; chart_month_info *mi_e = NULL, *mi_i = NULL; chart_month_info **mi = NULL; QValueVector *monthly_values = NULL; QMap scheduled_cats; QMap scheduled_cat_counts; QMap scheduled_desc; QMap scheduled_desc_counts; bool isfirst_i = true, isfirst_e = true; QMap isfirst_c; QMap isfirst_d; bool *isfirst = NULL; int type = valueGroup->selectedId(); if(current_source == 3 || current_source < 2) { Account *account = budget->incomesAccounts.first(); while(account) { monthly_cats[account] = QValueVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; account = budget->incomesAccounts.next(); } } if(current_source == 4 || current_source < 3) { Account *account = budget->expensesAccounts.first(); while(account) { monthly_cats[account] = QValueVector(); mi_c[account] = NULL; isfirst_c[account] = true; scheduled_cats[account] = 0.0; scheduled_cat_counts[account] = 0.0; account = budget->expensesAccounts.next(); } } else if(current_source == 7 || current_source == 8 || current_source == 17 || current_source == 18) { if(has_empty_description) descriptionCombo->changeItem("", descriptionCombo->count() - 1); for(int i = 2; i < descriptionCombo->count(); i++) { QString str = descriptionCombo->text(i); monthly_desc[str] = QValueVector(); mi_d[str] = NULL; isfirst_d[str] = true; scheduled_desc[str] = 0.0; scheduled_desc_counts[str] = 0.0; } } else if(current_source == 11 || current_source == 12 || current_source == 13 || current_source == 14) { if(has_empty_payee) payeeCombo->changeItem("", payeeCombo->count() - 1); for(int i = 2; i < payeeCombo->count(); i++) { QString str = payeeCombo->text(i); monthly_desc[str] = QValueVector(); mi_d[str] = NULL; isfirst_d[str] = true; scheduled_desc[str] = 0.0; scheduled_desc_counts[str] = 0.0; } } QDate first_date = start_date; QDate last_date = end_date; double maxvalue = 1.0; double minvalue = 0.0; double maxcount = 1.0; bool started = false; Transaction *trans = budget->transactions.first(); while(trans && trans->date() <= last_date) { bool include = false; int sign = 1; if(!started && trans->date() >= first_date) started = true; if(started) { switch(current_source) { case -1: {} case 0: {} case 1: {} case 2: {} case 3: {} case 4: { if(current_source != 2 && current_source != 4 && trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = 1; include = true; } else if(current_source != 1 && current_source != 3 && trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } else if(current_source != 2 && current_source != 4 && trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = -1; include = true; } else if(current_source != 1 && current_source != 3 && trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = 1; include = true; } break; } case 5: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = -1; include = true; } break; } case 6: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = -1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 7: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = 1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = -1; include = true; } break; } case 8: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = -1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = 1; include = true; } break; } case 9: { if(trans->fromAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } else if(trans->toAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = -1; include = true; } break; } case 10: { if(trans->fromAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = -1; include = true; } else if(trans->toAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 11: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account) { monthly_values = &monthly_desc[income->payer()]; mi = &mi_d[income->payer()]; isfirst = &isfirst_d[income->payer()]; sign = 1; include = true; } break; } case 12: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account) { monthly_values = &monthly_desc[expense->payee()]; mi = &mi_d[expense->payee()]; isfirst = &isfirst_d[expense->payee()]; sign = 1; include = true; } break; } case 13: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->description() == current_description) { monthly_values = &monthly_desc[income->payer()]; mi = &mi_d[income->payer()]; isfirst = &isfirst_d[income->payer()]; sign = 1; include = true; } break; } case 14: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->description() == current_description) { monthly_values = &monthly_desc[expense->payee()]; mi = &mi_d[expense->payee()]; isfirst = &isfirst_d[expense->payee()]; sign = 1; include = true; } break; } case 15: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->payer() == current_payee) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } break; } case 16: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->payee() == current_payee) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 17: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->payer() == current_payee) { monthly_values = &monthly_desc[income->description()]; mi = &mi_d[income->description()]; isfirst = &isfirst_d[income->description()]; sign = 1; include = true; } break; } case 18: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->payee() == current_payee) { monthly_values = &monthly_desc[expense->description()]; mi = &mi_d[expense->description()]; isfirst = &isfirst_d[expense->description()]; sign = 1; include = true; } break; } case 19: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->description() == current_description && income->payer() == current_payee) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } break; } case 20: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->description() == current_description && expense->payee() == current_payee) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } } } if(include) { if(!(*mi) || trans->date() > (*mi)->date) { QDate newdate, olddate; calSys->setYMD(newdate, calSys->year(trans->date()), calSys->month(trans->date()), calSys->daysInMonth(trans->date())); if(*mi) { olddate = addMonths((*mi)->date, 1); calSys->setYMD(olddate, calSys->year(olddate), calSys->month(olddate), calSys->daysInMonth(olddate)); (*isfirst) = false; } else { calSys->setYMD(olddate, calSys->year(first_date), calSys->month(first_date), calSys->daysInMonth(first_date)); (*isfirst) = true; } while(olddate < newdate) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = olddate; olddate = addMonths(olddate, 1); calSys->setYMD(olddate, calSys->year(olddate), calSys->month(olddate), calSys->daysInMonth(olddate)); (*isfirst) = false; } monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = trans->value() * sign; (*mi)->count = trans->quantity(); (*mi)->date = newdate; } else { (*mi)->value += trans->value() * sign; (*mi)->count += trans->quantity(); } } trans = budget->transactions.next(); } int source_org = 0; switch(current_source) { case -1: {source_org = 0; break;} case 0: {source_org = 0; break;} case 1: {source_org = 3; break;} case 2: {source_org = 4; break;} case 3: {source_org = 3; break;} case 4: {source_org = 4; break;} case 5: {source_org = 1; break;} case 6: {source_org = 2; break;} case 7: {source_org = 7; break;} case 8: {source_org = 7; break;} case 9: {source_org = 1; break;} case 10: {source_org = 2; break;} case 11: {source_org = 11; break;} case 12: {source_org = 11; break;} case 13: {source_org = 11; break;} case 14: {source_org = 11; break;} case 15: {source_org = 1; break;} case 16: {source_org = 2; break;} case 17: {source_org = 7; break;} case 18: {source_org = 7; break;} case 19: {source_org = 1; break;} case 20: {source_org = 2; break;} } Account *account = NULL; int desc_i = 2; int desc_nr = 0; bool at_expenses = false; if(source_org == 7) desc_nr = descriptionCombo->count(); else if(source_org == 11) desc_nr = payeeCombo->count(); else if(source_org == 0) {account = budget->incomesAccounts.first(); if(!account) {at_expenses = true; account = budget->expensesAccounts.first();}} else if(source_org == 3) account = budget->incomesAccounts.first(); else if(source_org == 4) account = budget->expensesAccounts.first(); else if(source_org == 2) {mi = &mi_e; monthly_values = &monthly_expenses; isfirst = &isfirst_e;} else if(source_org == 1) {mi = &mi_i; monthly_values = &monthly_incomes; isfirst = &isfirst_i;} while(source_org == 1 || source_org == 2 || account || ((source_org == 7 || source_org == 11) && desc_i < desc_nr)) { if(source_org == 3 || source_org == 4 || source_org == 0) {mi = &mi_c[account]; monthly_values = &monthly_cats[account]; isfirst = &isfirst_c[account];} else if(source_org == 7) {mi = &mi_d[descriptionCombo->text(desc_i)]; monthly_values = &monthly_desc[descriptionCombo->text(desc_i)]; isfirst = &isfirst_d[descriptionCombo->text(desc_i)];} else if(source_org == 11) {mi = &mi_d[payeeCombo->text(desc_i)]; monthly_values = &monthly_desc[payeeCombo->text(desc_i)]; isfirst = &isfirst_d[payeeCombo->text(desc_i)];} if(!(*mi)) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; calSys->setYMD((*mi)->date, calSys->year(first_date), calSys->month(first_date), calSys->daysInMonth(first_date)); (*isfirst) = true; } while((*mi)->date < last_date) { QDate newdate = addMonths((*mi)->date, 1); calSys->setYMD(newdate, calSys->year(newdate), calSys->month(newdate), calSys->daysInMonth(newdate)); monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; (*isfirst) = false; } if(source_org == 7 || source_org == 11) desc_i++; else if(source_org == 3) account = budget->incomesAccounts.next(); else if(source_org == 4) account = budget->expensesAccounts.next(); else if(source_org == 0) { if(!at_expenses) { account = budget->incomesAccounts.next(); if(!account) { at_expenses = true; account = budget->expensesAccounts.first(); } } else { account = budget->expensesAccounts.next(); } } else break; } ScheduledTransaction *strans = budget->scheduledTransactions.first(); while(strans && strans->firstOccurrence() <= last_date) { trans = strans->transaction(); bool include = false; int sign = 1; switch(current_source) { case -1: {} case 0: {} case 1: {} case 2: {} case 3: {} case 4: { if(current_source != 2 && current_source != 4 && trans->fromAccount()->type() == ACCOUNT_TYPE_INCOMES) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = 1; include = true; } else if(current_source != 1 && current_source != 3 && trans->fromAccount()->type() == ACCOUNT_TYPE_EXPENSES) { monthly_values = &monthly_cats[trans->fromAccount()]; mi = &mi_c[trans->fromAccount()]; isfirst = &isfirst_c[trans->fromAccount()]; sign = -1; include = true; } else if(current_source != 2 && current_source != 4 && trans->toAccount()->type() == ACCOUNT_TYPE_INCOMES) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = -1; include = true; } else if(current_source != 1 && current_source != 3 && trans->toAccount()->type() == ACCOUNT_TYPE_EXPENSES) { monthly_values = &monthly_cats[trans->toAccount()]; mi = &mi_c[trans->toAccount()]; isfirst = &isfirst_c[trans->toAccount()]; sign = 1; include = true; } break; } case 5: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = -1; include = true; } break; } case 6: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = -1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 7: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = 1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = -1; include = true; } break; } case 8: { if(trans->fromAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = -1; include = true; } else if(trans->toAccount() == current_account) { monthly_values = &monthly_desc[trans->description()]; mi = &mi_d[trans->description()]; isfirst = &isfirst_d[trans->description()]; sign = 1; include = true; } break; } case 9: { if(trans->fromAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } else if(trans->toAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = -1; include = true; } break; } case 10: { if(trans->fromAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = -1; include = true; } else if(trans->toAccount() == current_account && trans->description() == current_description) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 11: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account) { monthly_values = &monthly_desc[income->payer()]; mi = &mi_d[income->payer()]; isfirst = &isfirst_d[income->payer()]; sign = 1; include = true; } break; } case 12: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account) { monthly_values = &monthly_desc[expense->payee()]; mi = &mi_d[expense->payee()]; isfirst = &isfirst_d[expense->payee()]; sign = 1; include = true; } break; } case 13: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->description() == current_description) { monthly_values = &monthly_desc[income->payer()]; mi = &mi_d[income->payer()]; isfirst = &isfirst_d[income->payer()]; sign = 1; include = true; } break; } case 14: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->description() == current_description) { monthly_values = &monthly_desc[expense->payee()]; mi = &mi_d[expense->payee()]; isfirst = &isfirst_d[expense->payee()]; sign = 1; include = true; } break; } case 15: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->payer() == current_payee) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } break; } case 16: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->payee() == current_payee) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } case 17: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->payer() == current_payee) { monthly_values = &monthly_desc[income->description()]; mi = &mi_d[income->description()]; isfirst = &isfirst_d[income->description()]; sign = 1; include = true; } break; } case 18: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->payee() == current_payee) { monthly_values = &monthly_desc[expense->description()]; mi = &mi_d[expense->description()]; isfirst = &isfirst_d[expense->description()]; sign = 1; include = true; } break; } case 19: { if(trans->type() != TRANSACTION_TYPE_INCOME) break; Income *income = (Income*) trans; if(income->category() == current_account && income->description() == current_description && income->payer() == current_payee) { monthly_values = &monthly_incomes; mi = &mi_i; isfirst = &isfirst_i; sign = 1; include = true; } break; } case 20: { if(trans->type() != TRANSACTION_TYPE_EXPENSE) break; Expense *expense = (Expense*) trans; if(expense->category() == current_account && expense->description() == current_description && expense->payee() == current_payee) { monthly_values = &monthly_expenses; mi = &mi_e; isfirst = &isfirst_e; sign = 1; include = true; } break; } } if(include) { QDate transdate = strans->firstOccurrence(); QValueVector::iterator cmi_it = monthly_values->begin(); do { if(transdate >= first_date) { while(cmi_it->date < transdate) { ++cmi_it; } (*mi) = cmi_it; (*mi)->value += trans->value() * sign; (*mi)->count += trans->quantity(); } if(strans->recurrence()) { transdate = strans->recurrence()->nextOccurrence(transdate); } else { break; } } while(transdate <= last_date); } strans = budget->scheduledTransactions.next(); } account = current_account; desc_i = 2; desc_nr = 0; int imonth = calSys->month(QDate::currentDate()); if(calSys->day(QDate::currentDate()) == calSys->daysInMonth(QDate::currentDate())) { imonth++; } at_expenses = false; if(source_org == 7) {desc_nr = descriptionCombo->count(); account = NULL;} else if(source_org == 11) {desc_nr = payeeCombo->count(); account = NULL;} else if(source_org == 0) {account = budget->incomesAccounts.first(); if(!account) {at_expenses = true; account = budget->expensesAccounts.first();}} else if(source_org == 3) account = budget->incomesAccounts.first(); else if(source_org == 4) account = budget->expensesAccounts.first(); else if(source_org == 2) {mi = &mi_e; monthly_values = &monthly_expenses; isfirst = &isfirst_e;} else if(source_org == 1) {mi = &mi_i; monthly_values = &monthly_incomes; isfirst = &isfirst_i;} while(source_org == 1 || source_org == 2 || account || ((source_org == 7 || source_org == 11) && desc_i < desc_nr)) { if(source_org == 3 || source_org == 4 || source_org == 0) {mi = &mi_c[account]; monthly_values = &monthly_cats[account]; isfirst = &isfirst_c[account];} else if(source_org == 7) {mi = &mi_d[descriptionCombo->text(desc_i)]; monthly_values = &monthly_desc[descriptionCombo->text(desc_i)]; isfirst = &isfirst_d[descriptionCombo->text(desc_i)];} else if(source_org == 11) {mi = &mi_d[payeeCombo->text(desc_i)]; monthly_values = &monthly_desc[payeeCombo->text(desc_i)]; isfirst = &isfirst_d[payeeCombo->text(desc_i)];} (*mi) = &monthly_values->front(); QValueVector::iterator cmi_it = monthly_values->begin(); bool in_future = false; while(cmi_it != monthly_values->end()) { (*mi) = cmi_it; if(account && type < 2 && current_source < 7) { if(!in_future && calSys->month((*mi)->date) >= imonth) { in_future = true; } if(in_future && account->type() != ACCOUNT_TYPE_ASSETS) { double d_budget = ((CategoryAccount*) account)->monthlyBudget(calSys->year((*mi)->date), calSys->month((*mi)->date), false); if(d_budget >= 0.0 && d_budget > (*mi)->value) { (*mi)->value = d_budget; } } } switch(type) { case 1: { if((*mi)->date >= last_date) { (*mi)->value /= ((*isfirst) ? (first_date.daysTo(last_date) + 1) : calSys->day(last_date)); } else { (*mi)->value /= ((*isfirst) ? (first_date.daysTo((*mi)->date) + 1) : calSys->daysInMonth((*mi)->date)); } break; } case 2: {(*mi)->value = (*mi)->count; break;} case 3: {if((*mi)->count > 0.0) (*mi)->value /= (*mi)->count; else (*mi)->value = 0.0; break;} } if((*mi)->value > maxvalue) maxvalue = (*mi)->value; else if((*mi)->value < minvalue) minvalue = (*mi)->value; if((*mi)->count > maxcount) maxcount = (*mi)->count; ++cmi_it; } if(source_org == 7 || source_org == 11) desc_i++; else if(source_org == 3) account = budget->incomesAccounts.next(); else if(source_org == 4) account = budget->expensesAccounts.next(); else if(source_org == 0) { if(!at_expenses) { account = budget->incomesAccounts.next(); if(!account) { at_expenses = true; account = budget->expensesAccounts.first(); } } else { account = budget->expensesAccounts.next(); } } else break; } bool second_run = false; if(current_source < 3) { maxvalue = 0.0; minvalue = 0.0; maxcount = 0.0; } while(current_source < 3) { if(current_source == -1 || current_source == 1 || second_run) monthly_values = &monthly_incomes; else monthly_values = &monthly_expenses; if(!second_run || current_source != -1) { monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; calSys->setYMD((*mi)->date, calSys->year(first_date), calSys->month(first_date), calSys->daysInMonth(first_date)); while((*mi)->date < last_date) { QDate newdate = addMonths((*mi)->date, 1); calSys->setYMD(newdate, calSys->year(newdate), calSys->month(newdate), calSys->daysInMonth(newdate)); monthly_values->append(chart_month_info()); (*mi) = &monthly_values->back(); (*mi)->value = 0.0; (*mi)->count = 0.0; (*mi)->date = newdate; } } if(current_source == 1 || second_run) account = budget->incomesAccounts.first(); else account = budget->expensesAccounts.first(); while(account) { QValueVector::iterator cmi_it = monthly_values->begin(); QValueVector::iterator cmi_itc = monthly_cats[account].begin(); while(cmi_it != monthly_values->end() && cmi_itc != monthly_cats[account].end()) { (*mi) = cmi_it; if(!second_run && current_source == -1) (*mi)->value -= cmi_itc->value; else (*mi)->value += cmi_itc->value; (*mi)->count += cmi_itc->count; ++cmi_it; ++cmi_itc; } if(current_source == 1 || second_run) account = budget->incomesAccounts.next(); else account = budget->expensesAccounts.next(); } if(current_source != -1 || second_run) { QValueVector::iterator cmi_it = monthly_values->begin(); while(cmi_it != monthly_values->end()) { (*mi) = cmi_it; if((*mi)->value > maxvalue) maxvalue = (*mi)->value; else if((*mi)->value < minvalue) minvalue = (*mi)->value; if((*mi)->count > maxcount) maxcount = (*mi)->count; ++cmi_it; } } if(current_source > 0 || second_run) break; second_run = true; } switch(current_source) { case -1: {source_org = 1; break;} case 0: {source_org = 0; break;} case 1: {source_org = 1; break;} case 2: {source_org = 2; break;} default: {} } QCanvas *oldcanvas = canvas; canvas = new QCanvas(this); canvas->setBackgroundColor(Qt::white); QFont legend_font = font(); QFontMetrics fm(legend_font); int fh = fm.height(); int years = calSys->year(last_date) - calSys->year(first_date); int months = months_between_dates(first_date, last_date) + 1; if(type == 2) { int intmax = (int) ceil(maxcount); if(intmax % 5 > 0) maxvalue = ((intmax / 5) + 1) * 5; else maxvalue = intmax; } else { if(-minvalue > maxvalue) maxvalue = -minvalue; double maxvalue_exp = round(log10(maxvalue)) - 1.0; if(maxvalue_exp <= 0.0) { maxvalue /= 2.0; maxvalue = ceil(maxvalue) * 2.0; } else { maxvalue /= pow(10, maxvalue_exp); maxvalue = ceil(maxvalue) * pow(10, maxvalue_exp); } if(minvalue < 0.0) minvalue = -maxvalue; } int n = 0; QDate monthdate = first_date; QDate curmonth = end_date; while(monthdate <= curmonth) { monthdate = addMonths(monthdate, 1); n++; } int linelength = (int) ceil(600.0 / n); int chart_height = 400; int margin = 30 + fh; int chart_y = margin + 15; int axis_width = 11; int axis_height = 11 + fh; int chart_width = linelength * n; int y_lines = 5; if(minvalue < 0.0) y_lines = 4; int max_axis_value_width = 0; for(int i = 0; i <= y_lines; i++) { int w; if(type == 2 || maxvalue - minvalue >= 50.0) w = fm.width(KGlobal::locale()->formatLong((int) round(maxvalue - (((maxvalue - minvalue) * i) / y_lines)))); else w = fm.width(KGlobal::locale()->formatNumber((maxvalue - (((maxvalue - minvalue) * i) / y_lines)))); if(w > max_axis_value_width) max_axis_value_width = w; } axis_width += max_axis_value_width; QCanvasText *axis_text = NULL; if(type == 2) axis_text = new QCanvasText(i18n("Quantity"), legend_font, canvas); else if(current_source == 0) axis_text = new QCanvasText(i18n("Value (%1)").arg(KGlobal::locale()->currencySymbol()), legend_font, canvas); else if(current_source == -1) axis_text = new QCanvasText(i18n("Profit (%1)").arg(KGlobal::locale()->currencySymbol()), legend_font, canvas); else if(current_source % 2 == 1) axis_text = new QCanvasText(i18n("Income (%1)").arg(KGlobal::locale()->currencySymbol()), legend_font, canvas); else axis_text = new QCanvasText(i18n("Cost (%1)").arg(KGlobal::locale()->currencySymbol()), legend_font, canvas); axis_text->setColor(Qt::black); if(axis_text->boundingRect().width() / 2 > max_axis_value_width) max_axis_value_width = axis_text->boundingRect().width() / 2; axis_text->move(margin + axis_width - axis_text->boundingRect().width() / 2, margin - fh); axis_text->show(); QPen axis_pen; axis_pen.setColor(Qt::black); axis_pen.setWidth(1); axis_pen.setStyle(Qt::SolidLine); QCanvasLine *y_axis = new QCanvasLine(canvas); y_axis->setPoints(margin + axis_width, margin + 3, margin + axis_width, chart_height + chart_y); y_axis->setPen(axis_pen); y_axis->show(); QCanvasLine *y_axis_dir1 = new QCanvasLine(canvas); y_axis_dir1->setPoints(margin + axis_width, margin + 3, margin + axis_width - 3, margin + 9); y_axis_dir1->setPen(axis_pen); y_axis_dir1->show(); QCanvasLine *y_axis_dir2 = new QCanvasLine(canvas); y_axis_dir2->setPoints(margin + axis_width, margin + 3, margin + axis_width + 3, margin + 9); y_axis_dir2->setPen(axis_pen); y_axis_dir2->show(); QCanvasLine *x_axis = new QCanvasLine(canvas); x_axis->setPoints(margin + axis_width, chart_height + chart_y, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis->setPen(axis_pen); x_axis->show(); QCanvasLine *x_axis_dir1 = new QCanvasLine(canvas); x_axis_dir1->setPoints(margin + chart_width + axis_width + 6, chart_height + chart_y - 3, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis_dir1->setPen(axis_pen); x_axis_dir1->show(); QCanvasLine *x_axis_dir2 = new QCanvasLine(canvas); x_axis_dir2->setPoints(margin + chart_width + axis_width + 6, chart_height + chart_y + 3, margin + chart_width + axis_width + 12, chart_height + chart_y); x_axis_dir2->setPen(axis_pen); x_axis_dir2->show(); axis_text = new QCanvasText(i18n("Time"), legend_font, canvas); axis_text->setColor(Qt::black); axis_text->move(margin + chart_width + axis_width + 15, chart_y + chart_height - fh / 2); axis_text->show(); int x_axis_extra_width = 15 + axis_text->boundingRect().width(); QPen div_pen; div_pen.setColor(Qt::black); div_pen.setWidth(1); div_pen.setStyle(Qt::DotLine); int div_height = chart_height / y_lines; for(int i = 0; i < y_lines; i++) { QCanvasLine *y_div = new QCanvasLine(canvas); y_div->setPoints(margin + axis_width, chart_y + i * div_height, margin + chart_width + axis_width, chart_y + i * div_height); y_div->setPen(div_pen); y_div->show(); QCanvasLine *y_mark = new QCanvasLine(canvas); y_mark->setPoints(margin + axis_width - 10, chart_y + i * div_height, margin + axis_width, chart_y + i * div_height); y_mark->setPen(axis_pen); y_mark->show(); if(minvalue < 0.0 && i == y_lines / 2) axis_text = new QCanvasText(KGlobal::locale()->formatLong(0), legend_font, canvas); else if(type == 2 || (maxvalue - minvalue) >= 50.0) axis_text= new QCanvasText(KGlobal::locale()->formatLong((int) round(maxvalue - (((maxvalue - minvalue) * i) / y_lines))), legend_font, canvas); else axis_text= new QCanvasText(KGlobal::locale()->formatNumber((maxvalue - (((maxvalue - minvalue) * i) / y_lines))), legend_font, canvas); axis_text->setColor(Qt::black); axis_text->move(margin + axis_width - axis_text->boundingRect().width() - 11, chart_y + i * div_height - fh / 2); axis_text->show(); } if(minvalue != 0.0) { if(type == 2 || (maxvalue - minvalue) >= 50.0) axis_text= new QCanvasText(KGlobal::locale()->formatLong((int) round(minvalue)), legend_font, canvas); else axis_text= new QCanvasText(KGlobal::locale()->formatNumber(minvalue), legend_font, canvas); } else { axis_text = new QCanvasText(KGlobal::locale()->formatLong(0), legend_font, canvas); } axis_text->setColor(Qt::black); axis_text->move(margin + axis_width - axis_text->boundingRect().width() - 11, chart_y + chart_height - fh / 2); axis_text->show(); int index = 0; int year = calSys->year(first_date) - 1; bool b_month_names = months <= 12, b_long_month_names = true; if(b_month_names) { monthdate = first_date; while(monthdate <= curmonth) { if(b_long_month_names) { if(fm.width(calSys->monthName(monthdate, false)) > linelength - 8) { b_long_month_names = false; } } if(!b_long_month_names) { if(fm.width(calSys->monthName(monthdate, true)) > linelength) { b_month_names = false; break; } } monthdate = addMonths(monthdate, 1); } } monthdate = first_date; while(monthdate <= curmonth) { if(years < 5 || year != calSys->year(monthdate)) { QCanvasLine *x_mark = new QCanvasLine(canvas); x_mark->setPoints(margin + axis_width + index * linelength, chart_height + chart_y, margin + axis_width + index * linelength, chart_height + chart_y + 10); x_mark->setPen(axis_pen); x_mark->show(); } if(b_month_names) { QCanvasText *axis_text = new QCanvasText(calSys->monthName(monthdate, !b_long_month_names), legend_font, canvas); axis_text->setColor(Qt::black); axis_text->move(margin + axis_width + index * linelength + (linelength - axis_text->boundingRect().width()) / 2, chart_height + chart_y + 11); axis_text->show(); } else if(year != calSys->year(monthdate)) { year = calSys->year(monthdate); QCanvasText *axis_text = new QCanvasText(calSys->yearString(monthdate, years >= 5), legend_font, canvas); axis_text->setColor(Qt::black); axis_text->move(margin + axis_width + index * linelength, chart_height + chart_y + 11); axis_text->show(); } monthdate = addMonths(monthdate, 1); index++; } QCanvasLine *x_mark = new QCanvasLine(canvas); x_mark->setPoints(margin + axis_width + index * linelength, chart_height + chart_y, margin + axis_width + index * linelength, chart_height + chart_y + 10); x_mark->setPen(axis_pen); x_mark->show(); int line_y = chart_height + chart_y; int line_x = margin + axis_width; int text_width = 0; int legend_x = chart_width + axis_width + margin + x_axis_extra_width + 10; int legend_y = margin; index = 0; account = NULL; desc_i = 2; if(source_org == 3) account = budget->incomesAccounts.first(); else if(source_org == 4) account = budget->expensesAccounts.first(); else if(source_org == 2) {monthly_values = &monthly_expenses;} else if(source_org == 1 || source_org == 0) {monthly_values = &monthly_incomes;} while(source_org < 3 || account || ((source_org == 7 || source_org == 11) && desc_i < desc_nr)) { if(source_org == 3 || source_org == 4) {monthly_values = &monthly_cats[account];} else if(source_org == 7) {monthly_values = &monthly_desc[descriptionCombo->text(desc_i)];} else if(source_org == 11) {monthly_values = &monthly_desc[payeeCombo->text(desc_i)];} int prev_y = 0; int index2 = 0; QValueVector::iterator it_e = monthly_values->end(); for(QValueVector::iterator it = monthly_values->begin(); it != it_e; ++it) { if(index2 == 0) { prev_y = (int) floor((chart_height * (it->value - minvalue)) / (maxvalue - minvalue)) + 1; if(n == 1) { QCanvasEllipse *dot = new QCanvasEllipse(5, 5, canvas); dot->move(line_x + linelength / 2, line_y - prev_y); QBrush brush(getColor2(index)); dot->setBrush(brush); dot->setZ(10); dot->show(); } } else { int next_y = (int) floor((chart_height * (it->value - minvalue)) / (maxvalue - minvalue)) + 1; QCanvasLine *line = new QCanvasLine(canvas); line->setPen(getPen(index)); line->setPoints(line_x + ((index2 - 1) * linelength) + linelength / 2, line_y - prev_y, line_x + (index2 * linelength) + linelength / 2, line_y - next_y); line->setZ(10); line->show(); prev_y = next_y; } index2++; } QCanvasLine *legend_line = new QCanvasLine(canvas); legend_line->setPoints(legend_x + 10, legend_y + 10 + (fh + 5) * index + fh / 2, legend_x + 10 + fh, legend_y + 10 + (fh + 5) * index + fh / 2); legend_line->setPen(getPen(index)); legend_line->show(); QCanvasText *legend_text = NULL; switch(current_source) { case -1: { legend_text= new QCanvasText(i18n("Profits"), legend_font, canvas); break; } case 0: { if(index == 0) legend_text= new QCanvasText(i18n("Incomes"), legend_font, canvas); else if(index == 1) legend_text= new QCanvasText(i18n("Expenses"), legend_font, canvas); break; } case 1: {legend_text= new QCanvasText(i18n("Incomes"), legend_font, canvas); break;} case 2: {legend_text= new QCanvasText(i18n("Expenses"), legend_font, canvas); break;} case 3: {} case 4: {legend_text= new QCanvasText(account->name(), legend_font, canvas); break;} case 5: {} case 6: {legend_text= new QCanvasText(current_account->name(), legend_font, canvas); break;} case 17: {} case 18: {} case 7: {} case 8: { if(descriptionCombo->text(desc_i).isEmpty()) legend_text= new QCanvasText(i18n("No description"), legend_font, canvas); else legend_text= new QCanvasText(descriptionCombo->text(desc_i), legend_font, canvas); break; } case 9: {} case 10: { if(current_description.isEmpty()) legend_text= new QCanvasText(i18n("No description"), legend_font, canvas); else legend_text= new QCanvasText(current_description, legend_font, canvas); break; } case 13: {} case 11: { if(payeeCombo->text(desc_i).isEmpty()) legend_text= new QCanvasText(i18n("No payer"), legend_font, canvas); else legend_text= new QCanvasText(payeeCombo->text(desc_i), legend_font, canvas); break; } case 14: {} case 12: { if(payeeCombo->text(desc_i).isEmpty()) legend_text= new QCanvasText(i18n("No payee"), legend_font, canvas); else legend_text= new QCanvasText(payeeCombo->text(desc_i), legend_font, canvas); break; } case 15: { if(current_payee.isEmpty()) legend_text= new QCanvasText(i18n("No payer"), legend_font, canvas); else legend_text= new QCanvasText(current_payee, legend_font, canvas); break; } case 16: { if(current_payee.isEmpty()) legend_text= new QCanvasText(i18n("No payee"), legend_font, canvas); else legend_text= new QCanvasText(current_payee, legend_font, canvas); break; } case 19: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = i18n("No description"); str2 = i18n("no payer");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = i18n("no payer");} else if(current_description.isEmpty()) {str1 = i18n("No description"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} legend_text= new QCanvasText(i18n("%1: Description; %2: Payer", "%1/%2").arg(str1).arg(str2), legend_font, canvas); break; } case 20: { QString str1, str2; if(current_payee.isEmpty() && current_description.isEmpty()) {str1 = i18n("No description"); str2 = i18n("no payee");} else if(current_payee.isEmpty()) {str1 = current_description; str2 = i18n("no payee");} else if(current_description.isEmpty()) {str1 = i18n("No description"); str2 = current_payee;} else {str1 = current_description; str2 = current_payee;} legend_text= new QCanvasText(i18n("%1: Description; %2: Payee", "%1/%2").arg(str1).arg(str2), legend_font, canvas); break; } } if(legend_text->boundingRect().width() > text_width) text_width = legend_text->boundingRect().width(); legend_text->setColor(Qt::black); legend_text->move(legend_x + 10 + fh + 5, legend_y + 10 + (fh + 5) * index); legend_text->show(); index++; if(source_org == 7 || source_org == 11) desc_i++; else if(source_org == 3) account = budget->incomesAccounts.next(); else if(source_org == 4) account = budget->expensesAccounts.next(); else if(source_org == 0 && monthly_values != &monthly_expenses) {monthly_values = &monthly_expenses;} else break; } QCanvasRectangle *legend_outline = new QCanvasRectangle(legend_x, legend_y, 10 + fh + 5 + text_width + 10, 10 + ((fh + 5) * index) + 5, canvas); legend_outline->setPen(QPen(Qt::black)); legend_outline->show(); double ratio = (double) view->visibleWidth() / (double) view->visibleHeight(); min_width = (int) ceil(legend_outline->x() + legend_outline->width() + margin); min_height = (int) ceil(legend_outline->y() + legend_outline->height() + margin); if(min_height < chart_height + axis_height + chart_y + margin) min_height = chart_height + axis_height + chart_y + margin; int height, width; if(floor(min_height * ratio) < min_width) { height = (int) floor(min_width / ratio); width = min_width; } else { height = min_height; width = (int) floor(min_height * ratio); } canvas->resize(width, height); canvas->update(); QWMatrix mx; mx.scale((double) view->visibleWidth() / (double) width, (double) view->visibleHeight() / (double) height); view->setWorldMatrix(mx); view->setCanvas(canvas); if(oldcanvas) { delete oldcanvas; } if(current_source == 7 || current_source == 8 || current_source == 17 || current_source == 18) { if(has_empty_description) descriptionCombo->changeItem(i18n("No description"), descriptionCombo->count() - 1); } else if(current_source == 12 || current_source == 14) { if(has_empty_payee) payeeCombo->changeItem(i18n("No payee"), payeeCombo->count() - 1); } else if(current_source == 11 || current_source == 13) { if(has_empty_payee) payeeCombo->changeItem(i18n("No payer"), payeeCombo->count() - 1); } } void OverTimeChart::resizeEvent(QResizeEvent*) { if(canvas) { double ratio = (double) view->visibleWidth() / (double) view->visibleHeight(); int height, width; if(floor(min_height * ratio) < min_width) { height = (int) floor(min_width / ratio); width = min_width; } else { height = min_height; width = (int) floor(min_height * ratio); } canvas->resize(width, height); QWMatrix mx; mx.scale((double) view->visibleWidth() / (double) width, (double) view->visibleHeight() / (double) height); view->setWorldMatrix(mx); } } void OverTimeChart::updateTransactions() { if(descriptionCombo->isEnabled() && current_account) { bool b_income = (current_account->type() == ACCOUNT_TYPE_INCOMES); int curindex = descriptionCombo->currentItem(); if(curindex > 1) { curindex = 0; } int curindex_p = 0; if(b_extra) { curindex_p = payeeCombo->currentItem(); if(curindex_p > 1) { curindex_p = 0; } } descriptionCombo->blockSignals(true); descriptionCombo->clear(); descriptionCombo->insertItem(i18n("All Descriptions Combined")); descriptionCombo->insertItem(i18n("All Descriptions Split")); if(b_extra) { if(b_income) payeeCombo->insertItem(i18n("All Payers Combined")); else payeeCombo->insertItem(i18n("All Payees Combined")); if(b_income) payeeCombo->insertItem(i18n("All Payers Split")); else payeeCombo->insertItem(i18n("All Payees Split")); } has_empty_description = false; has_empty_payee = false; QMap descriptions, payees; Transaction *trans = budget->transactions.first(); while(trans) { if((trans->fromAccount() == current_account || trans->toAccount() == current_account)) { if(trans->description().isEmpty()) has_empty_description = true; else descriptions[trans->description()] = true; if(b_extra) { if(trans->type() == TRANSACTION_TYPE_EXPENSE) { if(((Expense*) trans)->payee().isEmpty()) has_empty_payee = true; else payees[((Expense*) trans)->payee()] = true; } else if(trans->type() == TRANSACTION_TYPE_INCOME) { if(((Income*) trans)->payer().isEmpty()) has_empty_payee = true; else payees[((Income*) trans)->payer()] = true; } } } trans = budget->transactions.next(); } QMap::iterator it_e = descriptions.end(); int i = 2; for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { if((current_source == 9 || current_source == 10 || current_source == 13 || current_source == 14 || current_source == 19 || current_source == 20) && it.key() == current_description) { curindex = i; } descriptionCombo->insertItem(it.key()); i++; } if(has_empty_description) { if((current_source == 9 || current_source == 10 || current_source == 13 || current_source == 14 || current_source == 19 || current_source == 20) && current_description.isEmpty()) curindex = i; descriptionCombo->insertItem(i18n("No description")); } if(b_extra) { i = 2; QMap::iterator it2_e = payees.end(); for(QMap::iterator it2 = payees.begin(); it2 != it2_e; ++it2) { if((current_source >= 15 || current_source <= 20) && it2.key() == current_payee) { curindex_p = i; } payeeCombo->insertItem(it2.key()); i++; } if(has_empty_payee) { if((current_source >= 15 || current_source <= 20) && current_payee.isEmpty()) { curindex_p = i; } if(b_income) payeeCombo->insertItem(i18n("No payer")); else payeeCombo->insertItem(i18n("No payee")); } } if(curindex < descriptionCombo->count()) { descriptionCombo->setCurrentItem(curindex); } if(b_extra && curindex_p < payeeCombo->count()) { payeeCombo->setCurrentItem(curindex_p); } int d_index = descriptionCombo->currentItem(); int p_index = 0; if(b_extra) p_index = payeeCombo->currentItem(); if(d_index <= 1) current_description = ""; if(p_index <= 1) current_payee = ""; if(d_index == 0) { if(p_index == 0) current_source = b_income ? 5 : 6; else if(p_index == 1) current_source = b_income ? 11 : 12; else current_source = b_income ? 15 : 16; } else if(d_index == 1) { if(p_index == 0) current_source = b_income ? 7 : 8; else current_source = b_income ? 17 : 18; } else { if(p_index == 0) current_source = b_income ? 9 : 10; else if(p_index == 1) current_source = b_income ? 13 : 14; else current_source = b_income ? 19 : 20; } descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } updateDisplay(); } void OverTimeChart::updateAccounts() { if(categoryCombo->isEnabled()) { int curindex = categoryCombo->currentItem(); if(curindex > 1) { curindex = 1; } categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); if(b_extra) payeeCombo->blockSignals(true); categoryCombo->clear(); categoryCombo->insertItem(i18n("All Categories Combined")); categoryCombo->insertItem(i18n("All Categories Split")); int i = 2; if(sourceCombo->currentItem() == 2) { Account *account = budget->expensesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); if(account == current_account) curindex = i; account = budget->expensesAccounts.next(); i++; } } else { Account *account = budget->incomesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); if(account == current_account) curindex = i; account = budget->incomesAccounts.next(); i++; } } if(curindex < categoryCombo->count()) categoryCombo->setCurrentItem(curindex); if(curindex <= 1) { descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); if(b_extra) { payeeCombo->clear(); payeeCombo->setEnabled(false); if(sourceCombo->currentItem() == 3) payeeCombo->insertItem(i18n("All Payees Combined")); else payeeCombo->insertItem(i18n("All Payers Combined")); } descriptionCombo->setEnabled(false); if(b_extra) payeeCombo->setEnabled(false); } if(curindex == 0) { if(sourceCombo->currentItem() == 3) { current_source = 1; } else { current_source = 2; } } else if(curindex == 1) { if(sourceCombo->currentItem() == 3) { current_source = 3; } else { current_source = 4; } } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); if(b_extra) payeeCombo->blockSignals(false); } updateDisplay(); } #include "overtimechart.moc"