diff --git a/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp b/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp index 047a15e1f..2b9f3ef42 100644 --- a/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp +++ b/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp @@ -1,674 +1,680 @@ /*************************************************************************** kreportconfigurationdlg.cpp - description ------------------- begin : Mon Jun 21 2004 copyright : (C) 2000-2004 by Michael Edwardes email : mte@users.sourceforge.net Javier Campos Morales Felix Rodriguez John C Thomas Baumgart Kevin Tambascio Ace Jones ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "kreportconfigurationfilterdlg.h" // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include +#include #include #include #include #include "ui_kfindtransactiondlgdecl.h" KReportConfigurationFilterDlg::KReportConfigurationFilterDlg( MyMoneyReport report, QWidget *parent) : KFindTransactionDlg(parent, report.rowType() == MyMoneyReport::Row::Account), m_tab2(0), m_tab3(0), m_tabChart(0), m_initialState(report), m_currentState(report) { // // Rework labeling // setWindowTitle(i18n("Report Configuration")); delete m_ui->TextLabel1; // // Rework the buttons // // the Apply button is always enabled disconnect(SIGNAL(selectionNotEmpty(bool))); enableButtonApply(true); setButtonGuiItem(KDialog::Apply, KStandardGuiItem::ok()); setButtonToolTip(KDialog::Apply, i18nc("@info:tooltip for report configuration apply button", "Apply the configuration changes to the report")); // // Add new tabs // m_tab1 = new kMyMoneyReportConfigTab1Decl(m_ui->m_criteriaTab); m_tab1->setObjectName("kMyMoneyReportConfigTab1"); m_ui->m_criteriaTab->insertTab(0, m_tab1, i18n("Report")); if (m_initialState.reportType() == MyMoneyReport::Report::PivotTable) { m_tab2 = new kMyMoneyReportConfigTab2Decl(m_ui->m_criteriaTab); m_tab2->setObjectName("kMyMoneyReportConfigTab2"); m_ui->m_criteriaTab->insertTab(1, m_tab2, i18n("Rows/Columns")); connect(m_tab2->findChild("m_comboRows"), SIGNAL(activated(int)), this, SLOT(slotRowTypeChanged(int))); connect(m_tab2->findChild("m_comboColumns"), SIGNAL(activated(int)), this, SLOT(slotColumnTypeChanged(int))); connect(m_tab2->findChild("m_comboRows"), SIGNAL(activated(int)), this, SLOT(slotUpdateColumnsCombo())); connect(m_tab2->findChild("m_comboColumns"), SIGNAL(activated(int)), this, SLOT(slotUpdateColumnsCombo())); //control the state of the includeTransfer check connect(m_ui->m_categoriesView, SIGNAL(stateChanged()), this, SLOT(slotUpdateCheckTransfers())); m_tabChart = new kMyMoneyReportConfigTabChartDecl(m_ui->m_criteriaTab); m_tabChart->setObjectName("kMyMoneyReportConfigTabChart"); m_ui->m_criteriaTab->insertTab(2, m_tabChart, i18n("Chart")); } else if (m_initialState.reportType() == MyMoneyReport::Report::QueryTable) { // eInvestmentHoldings is a special-case report, and you cannot configure the // rows & columns of that report. if (m_initialState.rowType() < MyMoneyReport::Row::AccountByTopAccount) { m_tab3 = new kMyMoneyReportConfigTab3Decl(m_ui->m_criteriaTab); m_tab3->setObjectName("kMyMoneyReportConfigTab3"); m_ui->m_criteriaTab->insertTab(1, m_tab3, i18n("Rows/Columns")); } } m_ui->m_criteriaTab->setCurrentIndex(m_ui->m_criteriaTab->indexOf(m_tab1)); m_ui->m_criteriaTab->setMinimumSize(500, 200); QList list = MyMoneyFile::instance()->budgetList(); QList::const_iterator it_b; for (it_b = list.constBegin(); it_b != list.constEnd(); ++it_b) { m_budgets.push_back(*it_b); } // // Now set up the widgets with proper values // slotReset(); } KReportConfigurationFilterDlg::~KReportConfigurationFilterDlg() { } void KReportConfigurationFilterDlg::slotSearch() { // setup the filter from the dialog widgets setupFilter(); // Copy the m_filter over to the filter part of m_currentConfig. m_currentState.assignFilter(m_filter); // Then extract the report properties m_currentState.setName(m_tab1->findChild("m_editName")->text()); m_currentState.setComment(m_tab1->findChild("m_editComment")->text()); m_currentState.setConvertCurrency(m_tab1->findChild("m_checkCurrency")->isChecked()); m_currentState.setFavorite(m_tab1->findChild("m_checkFavorite")->isChecked()); m_currentState.setSkipZero(m_tab1->findChild("m_skipZero")->isChecked()); if (m_tab2) { MyMoneyReport::DetailLevel::Type dl[4] = { MyMoneyReport::DetailLevel::All, MyMoneyReport::DetailLevel::Top, MyMoneyReport::DetailLevel::Group, MyMoneyReport::DetailLevel::Total }; m_currentState.setDetailLevel(dl[m_tab2->findChild("m_comboDetail")->currentIndex()]); // modify the rowtype only if the widget is enabled if (m_tab2->findChild("m_comboRows")->isEnabled()) { MyMoneyReport::Row::Type rt[2] = { MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Row::AssetLiability }; m_currentState.setRowType(rt[m_tab2->findChild("m_comboRows")->currentIndex()]); } m_currentState.setShowingRowTotals(false); if (m_tab2->findChild("m_comboRows")->currentIndex() == 0) m_currentState.setShowingRowTotals(m_tab2->findChild("m_checkTotalColumn")->isChecked()); MyMoneyReport::Column::Type ct[6] = { MyMoneyReport::Column::Days, MyMoneyReport::Column::Weeks, MyMoneyReport::Column::Months, MyMoneyReport::Column::BiMonths, MyMoneyReport::Column::Quarters, MyMoneyReport::Column::Years }; bool dy[6] = { true, true, false, false, false, false }; m_currentState.setColumnType(ct[m_tab2->findChild("m_comboColumns")->currentIndex()]); //TODO (Ace) This should be implicit in the call above. MMReport needs fixin' m_currentState.setColumnsAreDays(dy[m_tab2->findChild("m_comboColumns")->currentIndex()]); m_currentState.setIncludingSchedules(m_tab2->findChild("m_checkScheduled")->isChecked()); m_currentState.setIncludingTransfers(m_tab2->findChild("m_checkTransfers")->isChecked()); m_currentState.setIncludingUnusedAccounts(m_tab2->findChild("m_checkUnused")->isChecked()); if (m_tab2->findChild("m_comboBudget")->isEnabled()) { m_currentState.setBudget(m_budgets[m_tab2->findChild("m_comboBudget")->currentItem()].id(), m_initialState.rowType() == MyMoneyReport::Row::BudgetActual); } else { m_currentState.setBudget(QString(), false); } //set moving average days if (m_tab2->findChild("m_movingAverageDays")->isEnabled()) { m_currentState.setMovingAverageDays(m_tab2->findChild("m_movingAverageDays")->value()); } } else if (m_tab3) { MyMoneyReport::Row::Type rtq[8] = { MyMoneyReport::Row::Category, MyMoneyReport::Row::TopCategory, MyMoneyReport::Row::Tag, MyMoneyReport::Row::Payee, MyMoneyReport::Row::Account, MyMoneyReport::Row::TopAccount, MyMoneyReport::Row::Month, MyMoneyReport::Row::Week }; m_currentState.setRowType(rtq[m_tab3->findChild("m_comboOrganizeBy")->currentIndex()]); unsigned qc = MyMoneyReport::QueryColumns::None; if (m_currentState.queryColumns() & MyMoneyReport::QueryColumns::Loan) // once a loan report, always a loan report qc = MyMoneyReport::QueryColumns::Loan; if (m_tab3->findChild("m_checkNumber")->isChecked()) qc |= MyMoneyReport::QueryColumns::Number; if (m_tab3->findChild("m_checkPayee")->isChecked()) qc |= MyMoneyReport::QueryColumns::Payee; if (m_tab3->findChild("m_checkTag")->isChecked()) qc |= MyMoneyReport::QueryColumns::Tag; if (m_tab3->findChild("m_checkCategory")->isChecked()) qc |= MyMoneyReport::QueryColumns::Category; if (m_tab3->findChild("m_checkMemo")->isChecked()) qc |= MyMoneyReport::QueryColumns::Memo; if (m_tab3->findChild("m_checkAccount")->isChecked()) qc |= MyMoneyReport::QueryColumns::Account; if (m_tab3->findChild("m_checkReconciled")->isChecked()) qc |= MyMoneyReport::QueryColumns::Reconciled; if (m_tab3->findChild("m_checkAction")->isChecked()) qc |= MyMoneyReport::QueryColumns::Action; if (m_tab3->findChild("m_checkShares")->isChecked()) qc |= MyMoneyReport::QueryColumns::Shares; if (m_tab3->findChild("m_checkPrice")->isChecked()) qc |= MyMoneyReport::QueryColumns::Price; if (m_tab3->findChild("m_checkBalance")->isChecked()) qc |= MyMoneyReport::QueryColumns::Balance; m_currentState.setQueryColumns(static_cast(qc)); m_currentState.setTax(m_tab3->findChild("m_checkTax")->isChecked()); m_currentState.setInvestmentsOnly(m_tab3->findChild("m_checkInvestments")->isChecked()); m_currentState.setLoansOnly(m_tab3->findChild("m_checkLoans")->isChecked()); m_currentState.setDetailLevel(m_tab3->findChild("m_checkHideSplitDetails")->isChecked() ? MyMoneyReport::DetailLevel::None : MyMoneyReport::DetailLevel::All); } if (m_tabChart) { MyMoneyReport::Chart::Type ct[5] = { MyMoneyReport::Chart::Line, MyMoneyReport::Chart::Bar, MyMoneyReport::Chart::StackedBar, MyMoneyReport::Chart::Pie, MyMoneyReport::Chart::Ring }; m_currentState.setChartType(ct[m_tabChart->findChild("m_comboType")->currentIndex()]); + MyMoneyReport::ChartPalette::Type cp[4] = { MyMoneyReport::ChartPalette::Application, MyMoneyReport::ChartPalette::Default, MyMoneyReport::ChartPalette::Rainbow, MyMoneyReport::ChartPalette::Subdued }; + m_currentState.setChartPalette(cp[m_tabChart->findChild("m_chartPalette")->currentIndex()]); m_currentState.setChartGridLines(m_tabChart->findChild("m_checkGridLines")->isChecked()); m_currentState.setChartDataLabels(m_tabChart->findChild("m_checkValues")->isChecked()); m_currentState.setChartByDefault(m_tabChart->findChild("m_checkShowChart")->isChecked()); m_currentState.setChartLineWidth(m_tabChart->findChild("m_lineWidth")->value()); } // setup the date lock MyMoneyTransactionFilter::dateOptionE range = m_ui->m_dateRange->currentItem(); m_currentState.setDateFilter(range); done(true); } void KReportConfigurationFilterDlg::slotRowTypeChanged(int row) { m_tab2->findChild("m_checkTotalColumn")->setEnabled(row == 0); } void KReportConfigurationFilterDlg::slotColumnTypeChanged(int row) { if ((m_tab2->findChild("m_comboBudget")->isEnabled() && row < 2)) { m_tab2->findChild("m_comboColumns")->setCurrentItem(i18nc("@item the columns will display monthly data", "Monthly"), false); } } void KReportConfigurationFilterDlg::slotUpdateColumnsCombo() { const int monthlyIndex = 2; const int incomeExpenseIndex = 0; const bool isIncomeExpenseForecast = m_currentState.isIncludingForecast() && m_tab2->findChild("m_comboRows")->currentIndex() == incomeExpenseIndex; if (isIncomeExpenseForecast && m_tab2->findChild("m_comboColumns")->currentIndex() != monthlyIndex) { m_tab2->findChild("m_comboColumns")->setCurrentItem(i18nc("@item the columns will display monthly data", "Monthly"), false); } } void KReportConfigurationFilterDlg::slotReset() { // // Set up the widget from the initial filter // m_currentState = m_initialState; // // Report Properties // m_tab1->findChild("m_editName")->setText(m_initialState.name()); m_tab1->findChild("m_editComment")->setText(m_initialState.comment()); m_tab1->findChild("m_checkCurrency")->setChecked(m_initialState.isConvertCurrency()); m_tab1->findChild("m_checkFavorite")->setChecked(m_initialState.isFavorite()); if (m_initialState.isIncludingPrice() || m_initialState.isSkippingZero()) { m_tab1->findChild("m_skipZero")->setChecked(m_initialState.isSkippingZero()); } else { m_tab1->findChild("m_skipZero")->setEnabled(false); } if (m_tab2) { KComboBox *combo = m_tab2->findChild("m_comboDetail"); switch (m_initialState.detailLevel()) { case MyMoneyReport::DetailLevel::None: case MyMoneyReport::DetailLevel::End: case MyMoneyReport::DetailLevel::All: combo->setCurrentItem(i18nc("All accounts", "All"), false); break; case MyMoneyReport::DetailLevel::Top: combo->setCurrentItem(i18n("Top-Level"), false); break; case MyMoneyReport::DetailLevel::Group: combo->setCurrentItem(i18n("Groups"), false); break; case MyMoneyReport::DetailLevel::Total: combo->setCurrentItem(i18n("Totals"), false); break; } combo = m_tab2->findChild("m_comboRows"); switch (m_initialState.rowType()) { case MyMoneyReport::Row::ExpenseIncome: case MyMoneyReport::Row::Budget: case MyMoneyReport::Row::BudgetActual: combo->setCurrentItem(i18n("Income & Expenses"), false); // income / expense break; default: combo->setCurrentItem(i18n("Assets & Liabilities"), false); // asset / liability break; } m_tab2->findChild("m_checkTotalColumn")->setChecked(m_initialState.isShowingRowTotals()); slotRowTypeChanged(combo->currentIndex()); combo = m_tab2->findChild("m_comboColumns"); if (m_initialState.isColumnsAreDays()) { switch (m_initialState.columnType()) { case MyMoneyReport::Column::NoColumns: case MyMoneyReport::Column::Days: combo->setCurrentItem(i18nc("@item the columns will display daily data", "Daily"), false); break; case MyMoneyReport::Column::Weeks: combo->setCurrentItem(i18nc("@item the columns will display weekly data", "Weekly"), false); break; default: break; } } else { switch (m_initialState.columnType()) { case MyMoneyReport::Column::NoColumns: case MyMoneyReport::Column::Months: combo->setCurrentItem(i18nc("@item the columns will display monthly data", "Monthly"), false); break; case MyMoneyReport::Column::BiMonths: combo->setCurrentItem(i18nc("@item the columns will display bi-monthly data", "Bi-Monthly"), false); break; case MyMoneyReport::Column::Quarters: combo->setCurrentItem(i18nc("@item the columns will display quarterly data", "Quarterly"), false); break; case MyMoneyReport::Column::Years: combo->setCurrentItem(i18nc("@item the columns will display yearly data", "Yearly"), false); break; default: break; } } //load budgets combo if (m_initialState.rowType() == MyMoneyReport::Row::Budget || m_initialState.rowType() == MyMoneyReport::Row::BudgetActual) { m_tab2->findChild("m_comboRows")->setEnabled(false); m_tab2->findChild("m_budgetFrame")->setEnabled(!m_budgets.empty()); int i = 0; for (QVector::const_iterator it_b = m_budgets.constBegin(); it_b != m_budgets.constEnd(); ++it_b) { m_tab2->findChild("m_comboBudget")->insertItem((*it_b).name(), i); //set the current selected item if ((m_initialState.budget() == "Any" && (*it_b).budgetStart().year() == QDate::currentDate().year()) || m_initialState.budget() == (*it_b).id()) m_tab2->findChild("m_comboBudget")->setCurrentItem(i); i++; } } //set moving average days spinbox QSpinBox *spinbox = m_tab2->findChild("m_movingAverageDays"); spinbox->setEnabled(m_initialState.isIncludingMovingAverage()); if (m_initialState.isIncludingMovingAverage()) { spinbox->setValue(m_initialState.movingAverageDays()); } m_tab2->findChild("m_checkScheduled")->setChecked(m_initialState.isIncludingSchedules()); m_tab2->findChild("m_checkTransfers")->setChecked(m_initialState.isIncludingTransfers()); m_tab2->findChild("m_checkUnused")->setChecked(m_initialState.isIncludingUnusedAccounts()); } else if (m_tab3) { KComboBox *combo = m_tab3->findChild("m_comboOrganizeBy"); switch (m_initialState.rowType()) { case MyMoneyReport::Row::NoRows: case MyMoneyReport::Row::Category: combo->setCurrentItem(i18n("Categories"), false); break; case MyMoneyReport::Row::TopCategory: combo->setCurrentItem(i18n("Top Categories"), false); break; case MyMoneyReport::Row::Tag: combo->setCurrentItem(i18n("Tags"), false); break; case MyMoneyReport::Row::Payee: combo->setCurrentItem(i18n("Payees"), false); break; case MyMoneyReport::Row::Account: combo->setCurrentItem(i18n("Accounts"), false); break; case MyMoneyReport::Row::TopAccount: combo->setCurrentItem(i18n("Top Accounts"), false); break; case MyMoneyReport::Row::Month: combo->setCurrentItem(i18n("Month"), false); break; case MyMoneyReport::Row::Week: combo->setCurrentItem(i18n("Week"), false); break; default: throw MYMONEYEXCEPTION("KReportConfigurationFilterDlg::slotReset(): QueryTable report has invalid rowtype"); } unsigned qc = m_initialState.queryColumns(); m_tab3->findChild("m_checkNumber")->setChecked(qc & MyMoneyReport::QueryColumns::Number); m_tab3->findChild("m_checkPayee")->setChecked(qc & MyMoneyReport::QueryColumns::Payee); m_tab3->findChild("m_checkTag")->setChecked(qc & MyMoneyReport::QueryColumns::Tag); m_tab3->findChild("m_checkCategory")->setChecked(qc & MyMoneyReport::QueryColumns::Category); m_tab3->findChild("m_checkMemo")->setChecked(qc & MyMoneyReport::QueryColumns::Memo); m_tab3->findChild("m_checkAccount")->setChecked(qc & MyMoneyReport::QueryColumns::Account); m_tab3->findChild("m_checkReconciled")->setChecked(qc & MyMoneyReport::QueryColumns::Reconciled); m_tab3->findChild("m_checkAction")->setChecked(qc & MyMoneyReport::QueryColumns::Action); m_tab3->findChild("m_checkShares")->setChecked(qc & MyMoneyReport::QueryColumns::Shares); m_tab3->findChild("m_checkPrice")->setChecked(qc & MyMoneyReport::QueryColumns::Price); m_tab3->findChild("m_checkBalance")->setChecked(qc & MyMoneyReport::QueryColumns::Balance); m_tab3->findChild("m_checkTax")->setChecked(m_initialState.isTax()); m_tab3->findChild("m_checkInvestments")->setChecked(m_initialState.isInvestmentsOnly()); m_tab3->findChild("m_checkLoans")->setChecked(m_initialState.isLoansOnly()); m_tab3->findChild("m_checkHideSplitDetails")->setChecked (m_initialState.detailLevel() == MyMoneyReport::DetailLevel::None); } if (m_tabChart) { KMyMoneyGeneralCombo* combo = m_tabChart->findChild("m_comboType"); switch (m_initialState.chartType()) { case MyMoneyReport::Chart::None: combo->setCurrentItem(MyMoneyReport::Chart::Line); break; case MyMoneyReport::Chart::Line: case MyMoneyReport::Chart::Bar: case MyMoneyReport::Chart::StackedBar: case MyMoneyReport::Chart::Pie: case MyMoneyReport::Chart::Ring: combo->setCurrentItem(m_initialState.chartType()); break; case MyMoneyReport::Chart::End: throw MYMONEYEXCEPTION("KReportConfigurationFilterDlg::slotReset(): Report has invalid charttype"); } + // keep in sync with kMyMoneyReportConfigTabChartDecl::kMyMoneyReportConfigTabChartDecl + KMyMoneyGeneralCombo* palette = m_tabChart->findChild("m_chartPalette"); + palette->setCurrentIndex(m_initialState.chartPalette()); m_tabChart->findChild("m_checkGridLines")->setChecked(m_initialState.isChartGridLines()); m_tabChart->findChild("m_checkValues")->setChecked(m_initialState.isChartDataLabels()); m_tabChart->findChild("m_checkShowChart")->setChecked(m_initialState.isChartByDefault()); m_tabChart->findChild("m_lineWidth")->setValue(m_initialState.chartLineWidth()); } // // Text Filter // QRegExp textfilter; if (m_initialState.textFilter(textfilter)) { m_ui->m_textEdit->setText(textfilter.pattern()); m_ui->m_caseSensitive->setChecked(Qt::CaseSensitive == textfilter.caseSensitivity()); m_ui->m_regExp->setChecked(QRegExp::RegExp == textfilter.patternSyntax()); m_ui->m_textNegate->setCurrentIndex(m_initialState.isInvertingText()); } // // Type & State Filters // int type; if (m_initialState.firstType(type)) m_ui->m_typeBox->setCurrentIndex(type); int state; if (m_initialState.firstState(state)) m_ui->m_stateBox->setCurrentIndex(state); // // Validity Filters // int validity; if (m_initialState.firstValidity(validity)) m_ui->m_validityBox->setCurrentIndex(validity); // // Number Filter // QString nrFrom, nrTo; if (m_initialState.numberFilter(nrFrom, nrTo)) { if (nrFrom == nrTo) { m_ui->m_nrEdit->setEnabled(true); m_ui->m_nrFromEdit->setEnabled(false); m_ui->m_nrToEdit->setEnabled(false); m_ui->m_nrEdit->setText(nrFrom); m_ui->m_nrFromEdit->setText(QString()); m_ui->m_nrToEdit->setText(QString()); m_ui->m_nrButton->setChecked(true); m_ui->m_nrRangeButton->setChecked(false); } else { m_ui->m_nrEdit->setEnabled(false); m_ui->m_nrFromEdit->setEnabled(true); m_ui->m_nrToEdit->setEnabled(false); m_ui->m_nrEdit->setText(QString()); m_ui->m_nrFromEdit->setText(nrFrom); m_ui->m_nrToEdit->setText(nrTo); m_ui->m_nrButton->setChecked(false); m_ui->m_nrRangeButton->setChecked(true); } } else { m_ui->m_nrEdit->setEnabled(true); m_ui->m_nrFromEdit->setEnabled(false); m_ui->m_nrToEdit->setEnabled(false); m_ui->m_nrEdit->setText(QString()); m_ui->m_nrFromEdit->setText(QString()); m_ui->m_nrToEdit->setText(QString()); m_ui->m_nrButton->setChecked(true); m_ui->m_nrRangeButton->setChecked(false); } // // Amount Filter // MyMoneyMoney from, to; if (m_initialState.amountFilter(from, to)) { // bool getAmountFilter(MyMoneyMoney&,MyMoneyMoney&); if (from == to) { m_ui->m_amountEdit->setEnabled(true); m_ui->m_amountFromEdit->setEnabled(false); m_ui->m_amountToEdit->setEnabled(false); m_ui->m_amountEdit->loadText(QString::number(from.toDouble())); m_ui->m_amountFromEdit->loadText(QString()); m_ui->m_amountToEdit->loadText(QString()); m_ui->m_amountButton->setChecked(true); m_ui->m_amountRangeButton->setChecked(false); } else { m_ui->m_amountEdit->setEnabled(false); m_ui->m_amountFromEdit->setEnabled(true); m_ui->m_amountToEdit->setEnabled(true); m_ui->m_amountEdit->loadText(QString()); m_ui->m_amountFromEdit->loadText(QString::number(from.toDouble())); m_ui->m_amountToEdit->loadText(QString::number(to.toDouble())); m_ui->m_amountButton->setChecked(false); m_ui->m_amountRangeButton->setChecked(true); } } else { m_ui->m_amountEdit->setEnabled(true); m_ui->m_amountFromEdit->setEnabled(false); m_ui->m_amountToEdit->setEnabled(false); m_ui->m_amountEdit->loadText(QString()); m_ui->m_amountFromEdit->loadText(QString()); m_ui->m_amountToEdit->loadText(QString()); m_ui->m_amountButton->setChecked(true); m_ui->m_amountRangeButton->setChecked(false); } // // Payees Filter // QStringList payees; if (m_initialState.payees(payees)) { if (payees.empty()) { m_ui->m_emptyPayeesButton->setChecked(true); } else { selectAllItems(m_ui->m_payeesView, false); selectItems(m_ui->m_payeesView, payees, true); } } else { selectAllItems(m_ui->m_payeesView, true); } // // Tags Filter // QStringList tags; if (m_initialState.tags(tags)) { if (tags.empty()) { m_ui->m_emptyTagsButton->setChecked(true); } else { selectAllItems(m_ui->m_tagsView, false); selectItems(m_ui->m_tagsView, tags, true); } } else { selectAllItems(m_ui->m_tagsView, true); } // // Accounts Filter // QStringList accounts; if (m_initialState.accounts(accounts)) { m_ui->m_accountsView->selectAllItems(false); m_ui->m_accountsView->selectItems(accounts, true); } else m_ui->m_accountsView->selectAllItems(true); // // Categories Filter // if (m_initialState.categories(accounts)) { m_ui->m_categoriesView->selectAllItems(false); m_ui->m_categoriesView->selectItems(accounts, true); } else m_ui->m_categoriesView->selectAllItems(true); // // Date Filter // // the following call implies a call to slotUpdateSelections, // that's why we call it last m_initialState.updateDateFilter(); QDate dateFrom, dateTo; if (m_initialState.dateFilter(dateFrom, dateTo)) { if (m_initialState.isUserDefined()) { m_ui->m_dateRange->setCurrentItem(MyMoneyTransactionFilter::userDefined); m_ui->m_fromDate->setDate(dateFrom); m_ui->m_toDate->setDate(dateTo); } else { m_ui->m_fromDate->setDate(dateFrom); m_ui->m_toDate->setDate(dateTo); KFindTransactionDlg::slotDateChanged(); } } else { m_ui->m_dateRange->setCurrentItem(MyMoneyTransactionFilter::allDates); slotDateRangeChanged(MyMoneyTransactionFilter::allDates); } slotRightSize(); } void KReportConfigurationFilterDlg::slotDateChanged() { if (m_ui->m_dateRange->currentItem() != MyMoneyTransactionFilter::userDefined) { KFindTransactionDlg::slotDateChanged(); } slotUpdateSelections(); } void KReportConfigurationFilterDlg::slotShowHelp() { KToolInvocation::invokeHelp("details.reports.config"); } //TODO Fix the reports and engine to include transfers even if categories are filtered - bug #1523508 void KReportConfigurationFilterDlg::slotUpdateCheckTransfers() { QCheckBox* cb = m_tab2->findChild("m_checkTransfers"); if (!m_ui->m_categoriesView->allItemsSelected()) { cb->setChecked(false); cb->setDisabled(true); } else { cb->setEnabled(true); } } diff --git a/kmymoney/mymoney/mymoneyreport.cpp b/kmymoney/mymoney/mymoneyreport.cpp index fa326bc25..117defc7f 100644 --- a/kmymoney/mymoney/mymoneyreport.cpp +++ b/kmymoney/mymoney/mymoneyreport.cpp @@ -1,889 +1,899 @@ /*************************************************************************** mymoneyreport.cpp ------------------- begin : Sun July 4 2004 copyright : (C) 2004-2005 by Ace Jones email : acejones@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "mymoneyreport.h" #include // ---------------------------------------------------------------------------- // QT Includes #include #include #include // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes #include "mymoneyfile.h" #include "reportdebug.h" const QStringList MyMoneyReport::Row::kText = QString("none,assetliability,expenseincome,category,topcategory,account,tag,payee,month,week,topaccount,topaccount-account,equitytype,accounttype,institution,budget,budgetactual,schedule,accountinfo,accountloaninfo,accountreconcile,cashflow").split(','); const MyMoneyReport::Report::Type MyMoneyReport::Report::kTypeArray[] = { NoReport, PivotTable, PivotTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, QueryTable, PivotTable, PivotTable, InfoTable, InfoTable, InfoTable, QueryTable, QueryTable, NoReport }; const QStringList MyMoneyReport::Column::kTypeText = QString("none,months,bimonths,quarters,4,5,6,weeks,8,9,10,11,years").split(','); // if you add names here, don't forget to update the bitmap for QueryColumns::Type // and shift the bit for QueryColumns::end one position to the left const QStringList MyMoneyReport::QueryColumns::kText = QString("none,number,payee,category,tag,memo,account,reconcileflag,action,shares,price,performance,loan,balance").split(','); const QStringList MyMoneyReport::DetailLevel::kText = QString("none,all,top,group,total,invalid").split(','); const QStringList MyMoneyReport::Chart::kText = QString("none,line,bar,pie,ring,stackedbar,invalid").split(','); +const QStringList MyMoneyReport::ChartPalette::kText = QString("application,default,rainbow,subdued").split(','); // This should live in mymoney/mymoneytransactionfilter.h const QStringList kTypeText = QString("all,payments,deposits,transfers,none").split(','); const QStringList kStateText = QString("all,notreconciled,cleared,reconciled,frozen,none").split(','); const QStringList kValidityText = QString("any,valid,invalid").split(','); const QStringList kDateLockText = QString("alldates,untiltoday,currentmonth,currentyear,monthtodate,yeartodate,yeartomonth,lastmonth,lastyear,last7days,last30days,last3months,last6months,last12months,next7days,next30days,next3months,next6months,next12months,userdefined,last3tonext3months,last11Months,currentQuarter,lastQuarter,nextQuarter,currentFiscalYear,lastFiscalYear,today,next18months").split(','); const QStringList kAccountTypeText = QString("unknown,checkings,savings,cash,creditcard,loan,certificatedep,investment,moneymarket,asset,liability,currency,income,expense,assetloan,stock,equity,invalid").split(','); QString MyMoneyReport::Row::toString(Type type) { switch(type) { case NoRows : return "NoRows"; case AssetLiability : return "AssetLiability"; case ExpenseIncome : return "ExpenseIncome"; case Category : return "Category"; case TopCategory : return "TopCategory"; case Account : return "Account"; case Tag : return "Tag"; case Payee : return "Payee"; case Month : return "Month"; case Week : return "Week"; case TopAccount : return "TopAccount"; case AccountByTopAccount: return "AccountByTopAccount"; case EquityType : return "EquityType"; case AccountType : return "AccountType"; case Institution : return "Institution"; case Budget : return "Budget"; case BudgetActual : return "BudgetActual"; case Schedule : return "Schedule"; case AccountInfo : return "AccountInfo"; case AccountLoanInfo : return "AccountLoanInfo"; case AccountReconcile : return "AccountReconcile"; case CashFlow : return "CashFlow"; default : return "undefined"; } } QString MyMoneyReport::Report::toString(Type type) { switch(type) { case NoReport: return "NoReport"; case PivotTable: return "PivotTable"; case QueryTable: return "QueryTable"; case InfoTable: return "InfoTable"; default: return "undefined"; } } MyMoneyReport::MyMoneyReport() : m_name("Unconfigured Pivot Table Report"), m_detailLevel(DetailLevel::None), m_convertCurrency(true), m_favorite(false), m_tax(false), m_investments(false), m_loans(false), m_reportType(Report::kTypeArray[Row::ExpenseIncome]), m_rowType(Row::ExpenseIncome), m_columnType(Column::Months), m_columnsAreDays(false), m_queryColumns(QueryColumns::None), m_dateLock(userDefined), m_accountGroupFilter(false), m_chartType(Chart::Line), m_chartDataLabels(true), m_chartGridLines(true), m_chartByDefault(false), + m_chartPalette(ChartPalette::Application), m_includeSchedules(false), m_includeTransfers(false), m_includeBudgetActuals(false), m_includeUnusedAccounts(false), m_showRowTotals(false), m_includeForecast(false), m_includeMovingAverage(false), m_movingAverageDays(0), m_includePrice(false), m_includeAveragePrice(false), m_mixedTime(false), m_currentDateColumn(0), m_skipZero(false) { m_chartLineWidth = m_lineWidth; } MyMoneyReport::MyMoneyReport(const QString& id, const MyMoneyReport& right) : MyMoneyObject(id), + m_chartPalette(ChartPalette::Application), m_movingAverageDays(0), m_currentDateColumn(0) { *this = right; setId(id); } MyMoneyReport::MyMoneyReport(Row::Type _rt, unsigned _ct, dateOptionE _dl, DetailLevel::Type _ss, const QString& _name, const QString& _comment) : m_name(_name), m_comment(_comment), m_detailLevel(_ss), m_convertCurrency(true), m_favorite(false), m_tax(false), m_investments(false), m_loans(false), m_reportType(Report::kTypeArray[_rt]), m_rowType(_rt), m_columnType(Column::Months), m_columnsAreDays(false), m_queryColumns(QueryColumns::None), m_dateLock(_dl), m_accountGroupFilter(false), m_chartType(Chart::Line), m_chartDataLabels(true), m_chartGridLines(true), m_chartByDefault(false), + m_chartPalette(ChartPalette::Application), m_includeSchedules(false), m_includeTransfers(false), m_includeBudgetActuals(false), m_includeUnusedAccounts(false), m_showRowTotals(false), m_includeForecast(false), m_includeMovingAverage(false), m_movingAverageDays(0), m_includePrice(false), m_includeAveragePrice(false), m_mixedTime(false), m_currentDateColumn(0), m_skipZero(false) { //set initial values m_chartLineWidth = m_lineWidth; //set report type if (m_reportType == Report::PivotTable) m_columnType = static_cast(_ct); if (m_reportType == Report::QueryTable) m_queryColumns = static_cast(_ct); setDateFilter(_dl); //throw exception if the type is inconsistent if ((_rt > static_cast(sizeof(Report::kTypeArray) / sizeof(Report::kTypeArray[0]))) || (m_reportType == Report::NoReport)) throw MYMONEYEXCEPTION("Invalid report type"); //add the corresponding account groups if (_rt == MyMoneyReport::Row::AssetLiability) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); m_showRowTotals = true; } if (_rt == MyMoneyReport::Row::Account) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::AssetLoan); addAccountGroup(MyMoneyAccount::Cash); addAccountGroup(MyMoneyAccount::Checkings); addAccountGroup(MyMoneyAccount::CreditCard); if (KMyMoneyGlobalSettings::expertMode()) addAccountGroup(MyMoneyAccount::Equity); addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); addAccountGroup(MyMoneyAccount::Liability); addAccountGroup(MyMoneyAccount::Loan); addAccountGroup(MyMoneyAccount::Savings); addAccountGroup(MyMoneyAccount::Stock); m_showRowTotals = true; } if (_rt == MyMoneyReport::Row::ExpenseIncome) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); m_showRowTotals = true; } //FIXME take this out once we have sorted out all issues regarding budget of assets and liabilities -- asoliverez@gmail.com if (_rt == MyMoneyReport::Row::Budget || _rt == MyMoneyReport::Row::BudgetActual) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); } if (_rt == MyMoneyReport::Row::AccountInfo) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } //cash flow reports show splits for all account groups if (_rt == MyMoneyReport::Row::CashFlow) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } #ifdef DEBUG_REPORTS QDebug dbg = qDebug(); dbg << _name << Row::toString(_rt) << Report::toString(m_reportType); foreach(const MyMoneyAccount::accountTypeE accountType, m_accountGroups) dbg << MyMoneyAccount::accountTypeToString(accountType); if (m_accounts.size() > 0) dbg << m_accounts; #endif } MyMoneyReport::MyMoneyReport(const QDomElement& node) : MyMoneyObject(node), + m_chartPalette(ChartPalette::Application), m_currentDateColumn(0) { // properly initialize the object before reading it *this = MyMoneyReport(); if (!read(node)) clearId(); } void MyMoneyReport::clear() { m_accountGroupFilter = false; m_accountGroups.clear(); MyMoneyTransactionFilter::clear(); } void MyMoneyReport::validDateRange(QDate& _db, QDate& _de) { _db = fromDate(); _de = toDate(); // if either begin or end date are invalid we have one of the following // possible date filters: // // a) begin date not set - first transaction until given end date // b) end date not set - from given date until last transaction // c) both not set - first transaction until last transaction // // If there is no transaction in the engine at all, we use the current // year as the filter criteria. if (!_db.isValid() || !_de.isValid()) { QList list = MyMoneyFile::instance()->transactionList(*this); QDate tmpBegin, tmpEnd; if (!list.isEmpty()) { qSort(list); // try to use the post dates tmpBegin = list.front().postDate(); tmpEnd = list.back().postDate(); // if the post dates are not valid try the entry dates if (!tmpBegin.isValid()) tmpBegin = list.front().entryDate(); if (!tmpEnd.isValid()) tmpEnd = list.back().entryDate(); } // make sure that we leave this function with valid dates no mather what if (!tmpBegin.isValid() || !tmpEnd.isValid() || tmpBegin > tmpEnd) { tmpBegin = QDate(QDate::currentDate().year(), 1, 1); // the first date in the file tmpEnd = QDate(QDate::currentDate().year(), 12, 31); // the last date in the file } if (!_db.isValid()) _db = tmpBegin; if (!_de.isValid()) _de = tmpEnd; } if (_db > _de) _db = _de; } void MyMoneyReport::setRowType(Row::Type _rt) { m_rowType = _rt; m_reportType = Report::kTypeArray[_rt]; m_accountGroupFilter = false; m_accountGroups.clear(); if (_rt == MyMoneyReport::Row::AssetLiability) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } if (_rt == MyMoneyReport::Row::ExpenseIncome) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); } } bool MyMoneyReport::accountGroups(QList& list) const { bool result = m_accountGroupFilter; if (result) { QList::const_iterator it_group = m_accountGroups.begin(); while (it_group != m_accountGroups.end()) { list += (*it_group); ++it_group; } } return result; } void MyMoneyReport::addAccountGroup(MyMoneyAccount::accountTypeE type) { if (!m_accountGroups.isEmpty() && type != MyMoneyAccount::UnknownAccountType) { if (m_accountGroups.contains(type)) return; } m_accountGroupFilter = true; if (type != MyMoneyAccount::UnknownAccountType) m_accountGroups.push_back(type); } bool MyMoneyReport::includesAccountGroup(MyMoneyAccount::accountTypeE type) const { bool result = (! m_accountGroupFilter) || (isIncludingTransfers() && m_rowType == MyMoneyReport::Row::ExpenseIncome) || m_accountGroups.contains(type); return result; } bool MyMoneyReport::includes(const MyMoneyAccount& acc) const { bool result = false; if (includesAccountGroup(acc.accountGroup())) { switch (acc.accountGroup()) { case MyMoneyAccount::Income: case MyMoneyAccount::Expense: if (isTax()) result = (acc.value("Tax") == "Yes") && includesCategory(acc.id()); else result = includesCategory(acc.id()); break; case MyMoneyAccount::Asset: case MyMoneyAccount::Liability: if (isLoansOnly()) result = acc.isLoan() && includesAccount(acc.id()); else if (isInvestmentsOnly()) result = acc.isInvest() && includesAccount(acc.id()); else if (isIncludingTransfers() && m_rowType == MyMoneyReport::Row::ExpenseIncome) // If transfers are included, ONLY include this account if it is NOT // included in the report itself!! result = ! includesAccount(acc.id()); else result = includesAccount(acc.id()); break; default: result = includesAccount(acc.id()); } } return result; } void MyMoneyReport::write(QDomElement& e, QDomDocument *doc, bool anonymous) const { // No matter what changes, be sure to have a 'type' attribute. Only change // the major type if it becomes impossible to maintain compatibility with // older versions of the program as new features are added to the reports. // Feel free to change the minor type every time a change is made here. writeBaseXML(*doc, e); if (anonymous) { e.setAttribute("name", m_id); e.setAttribute("comment", QString(m_comment).fill('x')); } else { e.setAttribute("name", m_name); e.setAttribute("comment", m_comment); } e.setAttribute("group", m_group); e.setAttribute("convertcurrency", m_convertCurrency); e.setAttribute("favorite", m_favorite); e.setAttribute("tax", m_tax); e.setAttribute("investments", m_investments); e.setAttribute("loans", m_loans); e.setAttribute("rowtype", Row::kText[m_rowType]); e.setAttribute("datelock", kDateLockText[m_dateLock]); e.setAttribute("includeschedules", m_includeSchedules); e.setAttribute("columnsaredays", m_columnsAreDays); e.setAttribute("includestransfers", m_includeTransfers); if (!m_budgetId.isEmpty()) e.setAttribute("budget", m_budgetId); e.setAttribute("includesactuals", m_includeBudgetActuals); e.setAttribute("includeunused", m_includeUnusedAccounts); e.setAttribute("includesforecast", m_includeForecast); e.setAttribute("includesprice", m_includePrice); e.setAttribute("includesaverageprice", m_includeAveragePrice); e.setAttribute("mixedtime", m_mixedTime); e.setAttribute("includesmovingaverage", m_includeMovingAverage); if (m_includeMovingAverage) e.setAttribute("movingaveragedays", m_movingAverageDays); if (m_chartType < 0 || m_chartType >= Chart::kText.size()) { qDebug("m_chartType out of bounds with %d on report of type %d. Default to none.", m_chartType, m_reportType); e.setAttribute("charttype", Chart::kText[0]); } else { e.setAttribute("charttype", Chart::kText[m_chartType]); } e.setAttribute("chartdatalabels", m_chartDataLabels); e.setAttribute("chartgridlines", m_chartGridLines); e.setAttribute("chartbydefault", m_chartByDefault); e.setAttribute("chartlinewidth", m_chartLineWidth); + e.setAttribute("chartpalette", ChartPalette::kText[m_chartPalette]); e.setAttribute("skipZero", m_skipZero); if (m_reportType == Report::PivotTable) { e.setAttribute("type", "pivottable 1.15"); e.setAttribute("detail", DetailLevel::kText[m_detailLevel]); e.setAttribute("columntype", Column::kTypeText[m_columnType]); e.setAttribute("showrowtotals", m_showRowTotals); } else if (m_reportType == Report::QueryTable) { e.setAttribute("type", "querytable 1.14"); QStringList columns; unsigned qc = m_queryColumns; unsigned it_qc = QueryColumns::Begin; unsigned index = 1; while (it_qc != QueryColumns::End) { if (qc & it_qc) columns += QueryColumns::kText[index]; it_qc *= 2; index++; } e.setAttribute("querycolumns", columns.join(",")); } else if (m_reportType == Report::InfoTable) { e.setAttribute("type", "infotable 1.0"); e.setAttribute("detail", DetailLevel::kText[m_detailLevel]); e.setAttribute("showrowtotals", m_showRowTotals); } // // Text Filter // QRegExp textfilter; if (textFilter(textfilter)) { QDomElement f = doc->createElement("TEXT"); f.setAttribute("pattern", textfilter.pattern()); f.setAttribute("casesensitive", (textfilter.caseSensitivity() == Qt::CaseSensitive) ? 1 : 0); f.setAttribute("regex", (textfilter.patternSyntax() == QRegExp::Wildcard) ? 1 : 0); f.setAttribute("inverttext", m_invertText); e.appendChild(f); } // // Type & State Filters // QList typelist; if (types(typelist) && ! typelist.empty()) { // iterate over payees, and add each one QList::const_iterator it_type = typelist.constBegin(); while (it_type != typelist.constEnd()) { QDomElement p = doc->createElement("TYPE"); p.setAttribute("type", kTypeText[*it_type]); e.appendChild(p); ++it_type; } } QList statelist; if (states(statelist) && ! statelist.empty()) { // iterate over payees, and add each one QList::const_iterator it_state = statelist.constBegin(); while (it_state != statelist.constEnd()) { QDomElement p = doc->createElement("STATE"); p.setAttribute("state", kStateText[*it_state]); e.appendChild(p); ++it_state; } } // // validity Filters // QList validitylist; if (validities(validitylist) && ! validitylist.empty()) { // iterate over validities, and add each one QList::const_iterator it_validity = validitylist.constBegin(); while (it_validity != validitylist.constEnd()) { QDomElement p = doc->createElement("VALIDITY"); p.setAttribute("validity", kValidityText[*it_validity]); e.appendChild(p); ++it_validity; } } // // Number Filter // QString nrFrom, nrTo; if (numberFilter(nrFrom, nrTo)) { QDomElement f = doc->createElement("NUMBER"); f.setAttribute("from", nrFrom); f.setAttribute("to", nrTo); e.appendChild(f); } // // Amount Filter // MyMoneyMoney from, to; if (amountFilter(from, to)) { // bool getAmountFilter(MyMoneyMoney&,MyMoneyMoney&); QDomElement f = doc->createElement("AMOUNT"); f.setAttribute("from", from.toString()); f.setAttribute("to", to.toString()); e.appendChild(f); } // // Payees Filter // QStringList payeelist; if (payees(payeelist)) { if (payeelist.empty()) { QDomElement p = doc->createElement("PAYEE"); e.appendChild(p); } else { // iterate over payees, and add each one QStringList::const_iterator it_payee = payeelist.constBegin(); while (it_payee != payeelist.constEnd()) { QDomElement p = doc->createElement("PAYEE"); p.setAttribute("id", *it_payee); e.appendChild(p); ++it_payee; } } } // // Tags Filter // QStringList taglist; if (tags(taglist)) { if (taglist.empty()) { QDomElement p = doc->createElement("TAG"); e.appendChild(p); } else { // iterate over tags, and add each one QStringList::const_iterator it_tag = taglist.constBegin(); while (it_tag != taglist.constEnd()) { QDomElement p = doc->createElement("TAG"); p.setAttribute("id", *it_tag); e.appendChild(p); ++it_tag; } } } // // Account Groups Filter // QList accountgrouplist; if (accountGroups(accountgrouplist)) { // iterate over accounts, and add each one QList::const_iterator it_group = accountgrouplist.constBegin(); while (it_group != accountgrouplist.constEnd()) { QDomElement p = doc->createElement("ACCOUNTGROUP"); p.setAttribute("group", kAccountTypeText[*it_group]); e.appendChild(p); ++it_group; } } // // Accounts Filter // QStringList accountlist; if (accounts(accountlist)) { // iterate over accounts, and add each one QStringList::const_iterator it_account = accountlist.constBegin(); while (it_account != accountlist.constEnd()) { QDomElement p = doc->createElement("ACCOUNT"); p.setAttribute("id", *it_account); e.appendChild(p); ++it_account; } } // // Categories Filter // accountlist.clear(); if (categories(accountlist)) { // iterate over accounts, and add each one QStringList::const_iterator it_account = accountlist.constBegin(); while (it_account != accountlist.constEnd()) { QDomElement p = doc->createElement("CATEGORY"); p.setAttribute("id", *it_account); e.appendChild(p); ++it_account; } } // // Date Filter // if (m_dateLock == userDefined) { QDate dateFrom, dateTo; if (dateFilter(dateFrom, dateTo)) { QDomElement f = doc->createElement("DATES"); if (dateFrom.isValid()) f.setAttribute("from", dateFrom.toString(Qt::ISODate)); if (dateTo.isValid()) f.setAttribute("to", dateTo.toString(Qt::ISODate)); e.appendChild(f); } } } bool MyMoneyReport::read(const QDomElement& e) { // The goal of this reading method is 100% backward AND 100% forward // compatibility. Any report ever created with any version of KMyMoney // should be able to be loaded by this method (as long as it's one of the // report types supported in this version, of course) bool result = false; if ( "REPORT" == e.tagName() && ( (e.attribute("type").indexOf("pivottable 1.") == 0) || (e.attribute("type").indexOf("querytable 1.") == 0) || (e.attribute("type").indexOf("infotable 1.") == 0) ) ) { result = true; clear(); int i; m_name = e.attribute("name"); m_comment = e.attribute("comment", "Extremely old report"); //set report type if (!e.attribute("type").indexOf("pivottable")) { m_reportType = MyMoneyReport::Report::PivotTable; } else if (!e.attribute("type").indexOf("querytable")) { m_reportType = MyMoneyReport::Report::QueryTable; } else if (!e.attribute("type").indexOf("infotable")) { m_reportType = MyMoneyReport::Report::InfoTable; } else { m_reportType = MyMoneyReport::Report::NoReport; } // Removed the line that screened out loading reports that are called // "Default Report". It's possible for the user to change the comment // to this, and we'd hate for it to break as a result. m_group = e.attribute("group"); m_id = e.attribute("id"); //check for reports with older settings which didn't have the detail attribute if (e.hasAttribute("detail")) { i = DetailLevel::kText.indexOf(e.attribute("detail", "all")); if (i != -1) m_detailLevel = static_cast(i); } else if (e.attribute("showsubaccounts", "0").toUInt()) { //set to show all accounts m_detailLevel = DetailLevel::All; } else { //set to show the top level account instead m_detailLevel = DetailLevel::Top; } m_convertCurrency = e.attribute("convertcurrency", "1").toUInt(); m_favorite = e.attribute("favorite", "0").toUInt(); m_tax = e.attribute("tax", "0").toUInt(); m_investments = e.attribute("investments", "0").toUInt(); m_loans = e.attribute("loans", "0").toUInt(); m_includeSchedules = e.attribute("includeschedules", "0").toUInt(); m_columnsAreDays = e.attribute("columnsaredays", "0").toUInt(); m_includeTransfers = e.attribute("includestransfers", "0").toUInt(); if (e.hasAttribute("budget")) m_budgetId = e.attribute("budget"); m_includeBudgetActuals = e.attribute("includesactuals", "0").toUInt(); m_includeUnusedAccounts = e.attribute("includeunused", "0").toUInt(); m_includeForecast = e.attribute("includesforecast", "0").toUInt(); m_includePrice = e.attribute("includesprice", "0").toUInt(); m_includeAveragePrice = e.attribute("includesaverageprice", "0").toUInt(); m_mixedTime = e.attribute("mixedtime", "0").toUInt(); m_includeMovingAverage = e.attribute("includesmovingaverage", "0").toUInt(); m_skipZero = e.attribute("skipZero", "0").toUInt(); if (m_includeMovingAverage) m_movingAverageDays = e.attribute("movingaveragedays", "1").toUInt(); //only load chart data if it is a pivot table m_chartType = static_cast(0); if (m_reportType == Report::PivotTable) { i = Chart::kText.indexOf(e.attribute("charttype")); if (i >= 0) m_chartType = static_cast(i); // if it is invalid, set to first type if (m_chartType >= Chart::End) m_chartType = Chart::Line; m_chartDataLabels = e.attribute("chartdatalabels", "1").toUInt(); m_chartGridLines = e.attribute("chartgridlines", "1").toUInt(); m_chartByDefault = e.attribute("chartbydefault", "0").toUInt(); m_chartLineWidth = e.attribute("chartlinewidth", QString(m_lineWidth)).toUInt(); } else { m_chartDataLabels = true; m_chartGridLines = true; m_chartByDefault = false; m_chartLineWidth = 1; } + i = ChartPalette::kText.indexOf(e.attribute("chartpalette", "application")); + if (i >= 0) + m_chartPalette = static_cast(i); + QString datelockstr = e.attribute("datelock", "userdefined"); // Handle the pivot 1.2/query 1.1 case where the values were saved as // numbers bool ok = false; i = datelockstr.toUInt(&ok); if (!ok) { i = kDateLockText.indexOf(datelockstr); if (i == -1) i = userDefined; } setDateFilter(static_cast(i)); i = Row::kText.indexOf(e.attribute("rowtype", "expenseincome")); if (i != -1) { setRowType(static_cast(i)); // recent versions of KMyMoney always showed a total column for // income/expense reports. We turn it on for backward compatibility // here. If the total column is turned off, the flag will be reset // in the next step if (i == Row::ExpenseIncome) m_showRowTotals = true; } if (e.hasAttribute("showrowtotals")) m_showRowTotals = e.attribute("showrowtotals").toUInt(); i = Column::kTypeText.indexOf(e.attribute("columntype", "months")); if (i != -1) setColumnType(static_cast(i)); unsigned qc = 0; QStringList columns = e.attribute("querycolumns", "none").split(','); QStringList::const_iterator it_column = columns.constBegin(); while (it_column != columns.constEnd()) { i = QueryColumns::kText.indexOf(*it_column); if (i > 0) qc |= (1 << (i - 1)); ++it_column; } setQueryColumns(static_cast(qc)); QDomNode child = e.firstChild(); while (!child.isNull() && child.isElement()) { QDomElement c = child.toElement(); if ("TEXT" == c.tagName() && c.hasAttribute("pattern")) { setTextFilter(QRegExp(c.attribute("pattern"), c.attribute("casesensitive", "1").toUInt() ? Qt::CaseSensitive : Qt::CaseInsensitive, c.attribute("regex", "1").toUInt() ? QRegExp::Wildcard : QRegExp::RegExp), c.attribute("inverttext", "0").toUInt()); } if ("TYPE" == c.tagName() && c.hasAttribute("type")) { i = kTypeText.indexOf(c.attribute("type")); if (i != -1) addType(i); } if ("STATE" == c.tagName() && c.hasAttribute("state")) { i = kStateText.indexOf(c.attribute("state")); if (i != -1) addState(i); } if ("VALIDITY" == c.tagName() && c.hasAttribute("validity")) { i = kValidityText.indexOf(c.attribute("validity")); if (i != -1) addValidity(i); } if ("NUMBER" == c.tagName()) { setNumberFilter(c.attribute("from"), c.attribute("to")); } if ("AMOUNT" == c.tagName()) { setAmountFilter(MyMoneyMoney(c.attribute("from", "0/100")), MyMoneyMoney(c.attribute("to", "0/100"))); } if ("DATES" == c.tagName()) { QDate from, to; if (c.hasAttribute("from")) from = QDate::fromString(c.attribute("from"), Qt::ISODate); if (c.hasAttribute("to")) to = QDate::fromString(c.attribute("to"), Qt::ISODate); MyMoneyTransactionFilter::setDateFilter(from, to); } if ("PAYEE" == c.tagName()) { addPayee(c.attribute("id")); } if ("TAG" == c.tagName()) { addTag(c.attribute("id")); } if ("CATEGORY" == c.tagName() && c.hasAttribute("id")) { addCategory(c.attribute("id")); } if ("ACCOUNT" == c.tagName() && c.hasAttribute("id")) { addAccount(c.attribute("id")); } if ("ACCOUNTGROUP" == c.tagName() && c.hasAttribute("group")) { i = kAccountTypeText.indexOf(c.attribute("group")); if (i != -1) addAccountGroup(static_cast(i)); } child = child.nextSibling(); } } return result; } void MyMoneyReport::writeXML(QDomDocument& document, QDomElement& parent) const { QDomElement el = document.createElement("REPORT"); write(el, &document, false); parent.appendChild(el); } bool MyMoneyReport::hasReferenceTo(const QString& id) const { QStringList list; // collect all ids accounts(list); categories(list); payees(list); tags(list); return (list.contains(id) > 0); } int MyMoneyReport::m_lineWidth = 2; void MyMoneyReport::setLineWidth(int width) { m_lineWidth = width; } diff --git a/kmymoney/mymoney/mymoneyreport.h b/kmymoney/mymoney/mymoneyreport.h index 9be413e8f..94fe7c21a 100644 --- a/kmymoney/mymoney/mymoneyreport.h +++ b/kmymoney/mymoney/mymoneyreport.h @@ -1,731 +1,747 @@ /*************************************************************************** mymoneyreport.h ------------------- begin : Sun July 4 2004 copyright : (C) 2004-2005 by Ace Jones email : acejones@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MYMONEYREPORT_H #define MYMONEYREPORT_H // ---------------------------------------------------------------------------- // QT Includes #include #include #include class QDomElement; class QDomDocument; // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include /** * This class defines a report within the MyMoneyEngine. The report class * contains all the configuration parameters needed to run a report, plus * XML serialization. * * A report is a transactionfilter, so any report can specify which * transactions it's interested down to the most minute level of detail. * It extends the transactionfilter by providing identification (name, * comments, group type, etc) as well as layout information (what kind * of layout should be used, how the rows & columns should be presented, * currency converted, etc.) * * As noted above, this class only provides a report DEFINITION. The * generation and presentation of the report itself are left to higher * level classes. * * @author Ace Jones */ class KMM_MYMONEY_EXPORT MyMoneyReport: public MyMoneyObject, public MyMoneyTransactionFilter { public: // When adding a new row type, be sure to add a corresponding entry in kTypeArray class Row { public: enum Type { NoRows = 0, AssetLiability, ExpenseIncome, Category, TopCategory, Account, Tag, Payee, Month, Week, TopAccount, AccountByTopAccount, EquityType, AccountType, Institution, Budget, BudgetActual, Schedule, AccountInfo, AccountLoanInfo, AccountReconcile, CashFlow}; /** * Return row type as string. * * @param type type to get string for * @return row type converted to string */ static QString toString(Type type); static const QStringList kText; }; class Report { public: enum Type { NoReport = 0, PivotTable, QueryTable, InfoTable }; /** * Return report type as string. * * @param type report type to get string for * @return report type converted to string */ static QString toString(Type type); static const Type kTypeArray[]; }; class Column { public: enum Type { NoColumns = 0, Days = 1, Months = 1, BiMonths = 2, Quarters = 3, Weeks = 7, Years = 12 }; static const QStringList kTypeText; }; // if you add bits to this bitmask, start with the value currently assigned to end and update its value afterwards // also don't forget to add column names to QueryColumns::kText in mymoneyreport.cpp class QueryColumns { public: enum Type { None = 0x0, Begin = 0x1, Number = 0x1, Payee = 0x2, Category = 0x4, Tag = 0x8, Memo = 0x10, Account = 0x20, Reconciled = 0x40, Action = 0x80, Shares = 0x100, Price = 0x200, Performance = 0x400, Loan = 0x800, Balance = 0x1000, End = 0x2000 }; static const QStringList kText; }; class DetailLevel { public: enum Type { None = 0, All, Top, Group, Total, End }; static const QStringList kText; }; class Chart { public: enum Type { None = 0, Line, Bar, Pie, Ring, StackedBar, End }; static const QStringList kText; }; + class ChartPalette { + public: + enum Type { Application = 0, Default, Rainbow, Subdued }; + static const QStringList kText; + }; + public: MyMoneyReport(); MyMoneyReport(Row::Type _rt, unsigned _ct, dateOptionE _dl, DetailLevel::Type _ss, const QString& _name, const QString& _comment); MyMoneyReport(const QString& id, const MyMoneyReport& right); /** * This constructor creates an object based on the data found in the * QDomElement referenced by @p node. If problems arise, the @p id of * the object is cleared (see MyMoneyObject::clearId()). */ MyMoneyReport(const QDomElement& node); // Simple get operations const QString& name() const { return m_name; } bool isShowingRowTotals() const { return (m_showRowTotals); } Report::Type reportType() const { return m_reportType; } Row::Type rowType() const { return m_rowType; } Column::Type columnType() const { return m_columnType; } bool isRunningSum() const { return (m_rowType == Row::AssetLiability); } bool isConvertCurrency() const { return m_convertCurrency; } unsigned columnPitch() const { return static_cast(m_columnType); } bool isShowingColumnTotals() const { return m_convertCurrency; } const QString& comment() const { return m_comment; } QueryColumns::Type queryColumns() const { return m_queryColumns; } const QString& group() const { return m_group; } bool isFavorite() const { return m_favorite; } bool isTax() const { return m_tax; } bool isInvestmentsOnly() const { return m_investments; } bool isLoansOnly() const { return m_loans; } DetailLevel::Type detailLevel() const { return m_detailLevel; } Chart::Type chartType() const { return m_chartType; } bool isChartDataLabels() const { return m_chartDataLabels; } bool isChartGridLines() const { return m_chartGridLines; } bool isChartByDefault() const { return m_chartByDefault; } uint chartLineWidth() const { return m_chartLineWidth; } + ChartPalette::Type chartPalette() const { + return m_chartPalette; + } bool isIncludingSchedules() const { return m_includeSchedules; } bool isColumnsAreDays() const { return m_columnsAreDays; } bool isIncludingTransfers() const { return m_includeTransfers; } bool isIncludingUnusedAccounts() const { return m_includeUnusedAccounts; } bool hasBudget() const { return !m_budgetId.isEmpty(); } const QString& budget() const { return m_budgetId; } bool isIncludingBudgetActuals() const { return m_includeBudgetActuals; } bool isIncludingForecast() const { return m_includeForecast; } bool isIncludingMovingAverage() const { return m_includeMovingAverage; } int movingAverageDays() const { return m_movingAverageDays; } bool isIncludingPrice() const { return m_includePrice; } bool isIncludingAveragePrice() const { return m_includeAveragePrice; } bool isUserDefined() const { return m_dateLock == userDefined; } bool isMixedTime() const { return m_mixedTime; } int currentDateColumn() const { return m_currentDateColumn; } /** * @see #m_skipZero */ bool isSkippingZero() const { return m_skipZero; } // Simple set operations void setName(const QString& _s) { m_name = _s; } void setConvertCurrency(bool _f) { m_convertCurrency = _f; } void setRowType(Row::Type _rt); void setColumnType(Column::Type _ct) { m_columnType = _ct; } void setComment(const QString& _comment) { m_comment = _comment; } void setGroup(const QString& _group) { m_group = _group; } void setFavorite(bool _f) { m_favorite = _f; } void setQueryColumns(QueryColumns::Type _qc) { m_queryColumns = _qc; } void setTax(bool _f) { m_tax = _f; } void setInvestmentsOnly(bool _f) { m_investments = _f; if (_f) m_loans = false; } void setLoansOnly(bool _f) { m_loans = _f; if (_f) m_investments = false; } void setDetailLevel(DetailLevel::Type _detail) { m_detailLevel = _detail; } void setChartType(Chart::Type _type) { m_chartType = _type; } void setChartDataLabels(bool _f) { m_chartDataLabels = _f; } void setChartGridLines(bool _f) { m_chartGridLines = _f; } void setChartByDefault(bool _f) { m_chartByDefault = _f; } void setChartLineWidth(uint _f) { m_chartLineWidth = _f; } + void setChartPalette(ChartPalette::Type _f) { + m_chartPalette = _f; + } void setIncludingSchedules(bool _f) { m_includeSchedules = _f; } void setColumnsAreDays(bool _f) { m_columnsAreDays = _f; } void setIncludingTransfers(bool _f) { m_includeTransfers = _f; } void setIncludingUnusedAccounts(bool _f) { m_includeUnusedAccounts = _f; } void setShowingRowTotals(bool _f) { m_showRowTotals = _f; } void setIncludingBudgetActuals(bool _f) { m_includeBudgetActuals = _f; } void setIncludingForecast(bool _f) { m_includeForecast = _f; } void setIncludingMovingAverage(bool _f) { m_includeMovingAverage = _f; } void setMovingAverageDays(int _days) { m_movingAverageDays = _days; } void setIncludingPrice(bool _f) { m_includePrice = _f; } void setIncludingAveragePrice(bool _f) { m_includeAveragePrice = _f; } void setMixedTime(bool _f) { m_mixedTime = _f; } void setCurrentDateColumn(int _f) { m_currentDateColumn = _f; } /** * @see #m_skipZero */ void setSkipZero(int _f) { m_skipZero = _f; } /** * Sets the budget used for this report * * @param _budget The ID of the budget to use, or an empty string * to indicate a budget is NOT included * @param _fa Whether to display actual data alongside the budget. * Setting to false means the report displays ONLY the budget itself. * @warning For now, the budget ID is ignored. The budget id is * simply checked for any non-empty string, and if so, hasBudget() * will return true. */ void setBudget(const QString& _budget, bool _fa = true) { m_budgetId = _budget; m_includeBudgetActuals = _fa; } /** * This method allows you to clear the underlying transaction filter */ void clear(); /** * This method allows you to set the underlying transaction filter * * @param _filter The filter which should replace the existing transaction * filter. */ void assignFilter(const MyMoneyTransactionFilter& _filter) { MyMoneyTransactionFilter::operator=(_filter); } /** * Set the underlying date filter and LOCK that filter to the specified * range. For example, if @p _u is "CurrentMonth", this report should always * be updated to the current month no matter when the report is run. * * This updating is not entirely automatic, you should update it yourself by * calling updateDateFilter. * * @param _u The date range constant (MyMoneyTransactionFilter::dateRangeE) * which this report should be locked to. */ void setDateFilter(dateOptionE _u) { m_dateLock = _u; if (_u != userDefined) MyMoneyTransactionFilter::setDateFilter(_u); } /** * Set the underlying date filter using the start and end dates provided. * Note that this does not LOCK to any range like setDateFilter(unsigned) * above. It is just a reimplementation of the MyMoneyTransactionFilter * version. * * @param _db The inclusive begin date of the date range * @param _de The inclusive end date of the date range */ void setDateFilter(const QDate& _db, const QDate& _de) { MyMoneyTransactionFilter::setDateFilter(_db, _de); } /** * Set the underlying date filter using the 'date lock' property. * * Always call this function before executing the report to be sure that * the date filters properly match the plain-language 'date lock'. * * For example, if the report is date-locked to "Current Month", and the * last time you loaded or ran the report was in August, but it's now * September, this function will update the date range to be September, * as is proper. */ void updateDateFilter() { if (m_dateLock != userDefined) MyMoneyTransactionFilter::setDateFilter(m_dateLock); } /** * Retrieves a VALID beginning & ending date for this report. * * The underlying date filter can return en empty QDate() for either the * begin or end date or both. This is typically unacceptable for reports, * which need the REAL begin and end date. * * This function gets the underlying date filter range, and if either is * an empty QDate(), it determines the missing date from looking at all * the transactions which match the underlying filter, and returning the * date of the first or last transaction (as appropriate). * * @param _db The inclusive begin date of the date range * @param _de The inclusive end date of the date range */ void validDateRange(QDate& _db, QDate& _de); /** * This method turns on the account group filter and adds the * @p type to the list of allowed groups. * * Note that account group filtering is handled differently * than all the filters of the underlying class. This filter * is meant to be applied to individual splits of matched * transactions AFTER the underlying filter is used to find * the matching transactions. * * @param type the account group to add to the allowed groups list */ void addAccountGroup(MyMoneyAccount::accountTypeE type); /** * This method returns whether an account group filter has been set, * and if so, it returns all the account groups set in the filter. * * @param list list to append account groups into * @return return true if an account group filter has been set */ bool accountGroups(QList& list) const; /** * This method returns whether the specified account group * is allowed by the account groups filter. * * @param type group to append account groups into * @return return true if an account group filter has been set */ bool includesAccountGroup(MyMoneyAccount::accountTypeE type) const; /** * This method is used to test whether a specific account * passes the accountGroup test and either the Account or * Category test, depending on which sort of Account it is. * * The m_tax and m_investments properties are also considered. * * @param acc the account in question * @return true if account is in filter set, false otherwise */ bool includes(const MyMoneyAccount& acc) const; /** * This method writes this report to the DOM element @p e, * within the DOM document @p doc. * * @param e The element which should be populated with info from this report * @param doc The document which we can use to create new sub-elements * if needed * @param anonymous Whether the sensitive parts of the report should be * masked */ void write(QDomElement& e, QDomDocument *doc, bool anonymous = false) const; /** * This method reads a report from the DOM element @p e, and * populates this report with the results. * * @param e The element from which the report should be read * * @return bool True if a report was successfully loaded from the * element @p e. If false is returned, the contents of this report * object are undefined. */ bool read(const QDomElement& e); /** * This method creates a QDomElement for the @p document * under the parent node @p parent. (This version overwrites the * MMObject base class.) * * @param document reference to QDomDocument * @param parent reference to QDomElement parent node */ virtual void writeXML(QDomDocument& document, QDomElement& parent) const; /** * This method checks if a reference to the given object exists. It returns, * a @p true if the object is referencing the one requested by the * parameter @p id. If it does not, this method returns @p false. * * @param id id of the object to be checked for references * @retval true This object references object with id @p id. * @retval false This object does not reference the object with id @p id. */ virtual bool hasReferenceTo(const QString& id) const; /** * This method allows to modify the default lineWidth for graphs. * The default is 2. */ static void setLineWidth(int width); private: /** * The user-assigned name of the report */ QString m_name; /** * The user-assigned comment for the report, in case they want to make * additional notes for themselves about the report. */ QString m_comment; /** * Where to group this report amongst the others in the UI view. This * should be assigned by the UI system. */ QString m_group; /** * How much detail to show in the accounts */ DetailLevel::Type m_detailLevel; /** * Whether to convert all currencies to the base currency of the file (true). * If this is false, it's up to the report generator to decide how to handle * the currency. */ bool m_convertCurrency; /** * Whether this is one of the users' favorite reports */ bool m_favorite; /** * Whether this report should only include categories marked as "Tax"="Yes" */ bool m_tax; /** * Whether this report should only include investment accounts */ bool m_investments; /** * Whether this report should only include loan accounts * Applies only to querytable reports. Mutually exclusive with * m_investments. */ bool m_loans; /** * What sort of algorithm should be used to run the report */ Report::Type m_reportType; /** * What sort of values should show up on the ROWS of this report */ Row::Type m_rowType; /** * What sort of values should show up on the COLUMNS of this report, * in the case of a 'PivotTable' report. Really this is used more as a * QUANTITY of months or days. Whether it's months or days is determined * by m_columnsAreDays. */ Column::Type m_columnType; /** * Whether the base unit of columns of this report is days. Only applies to * 'PivotTable' reports. If false, then columns are months or multiples thereof. */ bool m_columnsAreDays; /** * What sort of values should show up on the COLUMNS of this report, * in the case of a 'QueryTable' report */ enum QueryColumns::Type m_queryColumns; /** * The plain-language description of what the date range should be locked * to. 'userDefined' means NO locking, in any other case, the report * will be adjusted to match the date lock. So if the date lock is * 'currentMonth', the start and end dates of the underlying filter will * be updated to whatever the current month is. This updating happens * automatically when the report is loaded, and should also be done * manually by calling updateDateFilter() before generating the report */ dateOptionE m_dateLock; /** * Which account groups should be included in the report. This filter * is applied to the individual splits AFTER a transaction has been * matched using the underlying filter. */ QList m_accountGroups; /** * Whether an account group filter has been set (see m_accountGroups) */ bool m_accountGroupFilter; /** * What format should be used to draw this report as a chart */ Chart::Type m_chartType; /** * Whether the value of individual data points should be drawn on the chart */ bool m_chartDataLabels; /** * Whether grid lines should be drawn on the chart */ bool m_chartGridLines; /** * Whether this report should be shown as a chart by default (otherwise it * should be shown as a textual report) */ bool m_chartByDefault; /** * Width of the chart lines */ uint m_chartLineWidth; + /** + * Color palette used for the chart of this report + */ + ChartPalette::Type m_chartPalette; /** * Whether to include scheduled transactions */ bool m_includeSchedules; /** * Whether to include transfers. Only applies to Income/Expense reports */ bool m_includeTransfers; /** * The id of the budget associated with this report. */ QString m_budgetId; /** * Whether this report should print the actual data to go along with * the budget. This is only valid if the report has a budget. */ bool m_includeBudgetActuals; /** * Whether this report should include all accounts and not only * accounts with transactions. */ bool m_includeUnusedAccounts; /** * Whether this report should include columns for row totals */ bool m_showRowTotals; /** * Whether this report should include forecast balance */ bool m_includeForecast; /** * Whether this report should include moving average */ bool m_includeMovingAverage; /** * The amount of days that spans each moving average */ int m_movingAverageDays; /** * Whether this report should include prices */ bool m_includePrice; /** * Whether this report should include moving average prices */ bool m_includeAveragePrice; /** * Make the actual and forecast lines display as one */ bool m_mixedTime; /** * This stores the column for the current date * This value is calculated dinamically and thus it is not saved in the file */ int m_currentDateColumn; /** * This member keeps the current setting for line graphs lineWidth. * @sa setLineWidth() */ static int m_lineWidth; /** * This option is for investments reports only which * show prices instead of balances as all other reports do. *

* Select this option to include prices for the given period (week, month, * quarter, ...) only. *

*

* If this option is off the last existing price is shown for a period, if * it is on, in a table the value is '0' shown and in a chart a linear * interpolation for the missing values will be performed. *
Example: *
There are prices for January and March, but there is no price for * February. *

    *
  • OFF: shows the price for February as the last price of * January *
  • ON: in a table the value is '0', in a chart a linear * interpolation for the February-price will be performed * (so it makes a kind of average-value using the January- and the * March-price in the chart) *
*

*/ bool m_skipZero; }; /** * Make it possible to hold @ref MyMoneyReport objects inside @ref QVariant objects. */ Q_DECLARE_METATYPE(MyMoneyReport) #endif // MYMONEYREPORT_H diff --git a/kmymoney/reports/kreportchartview.cpp b/kmymoney/reports/kreportchartview.cpp index 97270100c..c95c45058 100644 --- a/kmymoney/reports/kreportchartview.cpp +++ b/kmymoney/reports/kreportchartview.cpp @@ -1,650 +1,664 @@ /*************************************************************************** kreportchartview.cpp ------------------- begin : Sun Aug 14 2005 copyright : (C) 2004-2005 by Ace Jones email : ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include "kreportchartview.h" #include // ---------------------------------------------------------------------------- // QT Includes #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include #include #include #include #include #include #include #include #include #include "kmymoneyglobalsettings.h" #include #include using namespace reports; KReportChartView::KReportChartView(QWidget* parent) : KDChart::Chart(parent), m_accountSeries(0), m_seriesTotals(0), m_numColumns(0), m_skipZero(0), m_backgroundBrush(KColorScheme(QPalette::Current).background()), m_foregroundBrush(KColorScheme(QPalette::Current).foreground()) { // ******************************************************************** // Set KMyMoney's Chart Parameter Defaults // ******************************************************************** //Set the background obtained from the color scheme BackgroundAttributes backAttr(backgroundAttributes()); backAttr.setBrush(m_backgroundBrush); backAttr.setVisible(true); setBackgroundAttributes(backAttr); //Line diagram KDChart::LineDiagram* diagram = new KDChart::LineDiagram; diagram->setModel(&m_model); this->coordinatePlane()->replaceDiagram(diagram); } void KReportChartView::drawPivotChart(const PivotGrid &grid, const MyMoneyReport &config, int numberColumns, const QStringList& columnHeadings, const QList& rowTypeList, const QStringList& columnTypeHeaderList) { //set the number of columns setNumColumns(numberColumns); //set skipZero m_skipZero = config.isSkippingZero(); //remove existing headers while (headerFooters().count() > 0) { HeaderFooter* delHeader = headerFooters().at(0); takeHeaderFooter(delHeader); delete delHeader; } //make sure the model is clear m_model.removeColumns(0, m_model.columnCount()); m_model.removeRows(0, m_model.rowCount()); //set the new header HeaderFooter* header = new HeaderFooter(this); header->setText(config.name()); header->setType(HeaderFooter::Header); header->setPosition(Position::North); TextAttributes headerTextAttr(header->textAttributes()); headerTextAttr.setPen(m_foregroundBrush.color()); header->setTextAttributes(headerTextAttr); addHeaderFooter(header); // whether to limit the chart to use series totals only. Used for reports which only // show one dimension (pie). setSeriesTotals(false); // whether series (rows) are accounts (true) or months (false). This causes a lot // of complexity in the charts. The problem is that circular reports work best with // an account in a COLUMN, while line/bar prefer it in a ROW. setAccountSeries(true); switch (config.chartType()) { case MyMoneyReport::Chart::None: case MyMoneyReport::Chart::End: case MyMoneyReport::Chart::Line: { KDChart::LineDiagram* diagram = new KDChart::LineDiagram; if (config.isSkippingZero()) { LineAttributes attributes = diagram->lineAttributes(); attributes.setMissingValuesPolicy(LineAttributes::MissingValuesAreBridged); diagram->setLineAttributes(attributes); } CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::Chart::Bar: { KDChart::BarDiagram* diagram = new KDChart::BarDiagram; CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::Chart::StackedBar: { KDChart::BarDiagram* diagram = new KDChart::BarDiagram; CartesianCoordinatePlane* cartesianPlane = new CartesianCoordinatePlane; replaceCoordinatePlane(cartesianPlane); diagram->setType(BarDiagram::Stacked); coordinatePlane()->replaceDiagram(diagram); break; } case MyMoneyReport::Chart::Pie: { KDChart::PieDiagram* diagram = new KDChart::PieDiagram; PolarCoordinatePlane* polarPlane = new PolarCoordinatePlane; replaceCoordinatePlane(polarPlane); coordinatePlane()->replaceDiagram(diagram); setAccountSeries(false); setSeriesTotals(true); break; } case MyMoneyReport::Chart::Ring: { KDChart::RingDiagram* diagram = new KDChart::RingDiagram; PolarCoordinatePlane* polarPlane = new PolarCoordinatePlane; replaceCoordinatePlane(polarPlane); polarPlane->replaceDiagram(diagram); //chartView.params()->setRelativeRingThickness( true ); setAccountSeries(false); break; } } //get the diagram for later use AbstractDiagram* planeDiagram = coordinatePlane()->diagram(); planeDiagram->setAntiAliasing(true); //set grid attributes GridAttributes gridAttr(coordinatePlane()->globalGridAttributes()); gridAttr.setGridVisible(config.isChartGridLines()); coordinatePlane()->setGlobalGridAttributes(gridAttr); - //the palette - we set it here because it is a property of the diagram - switch (KMyMoneySettings::chartsPalette()) { - case 0: + // setup chart color palette + switch (config.chartPalette()) { + case MyMoneyReport::ChartPalette::Application: + switch (KMyMoneySettings::chartsPalette()) { + case 0: + planeDiagram->useDefaultColors(); + break; + case 1: + planeDiagram->useRainbowColors(); + break; + case 2: + default: + planeDiagram->useSubduedColors(); + break; + } + break; + case MyMoneyReport::ChartPalette::Default: planeDiagram->useDefaultColors(); break; - case 1: + case MyMoneyReport::ChartPalette::Rainbow: planeDiagram->useRainbowColors(); break; - case 2: default: + case MyMoneyReport::ChartPalette::Subdued: planeDiagram->useSubduedColors(); break; } //the legend will be used later Legend* legend = new Legend(planeDiagram, this); legend->setTitleText(i18nc("Chart legend title", "Legend")); //set up the axes for cartesian diagrams if (config.chartType() == MyMoneyReport::Chart::Line || config.chartType() == MyMoneyReport::Chart::Bar || config.chartType() == MyMoneyReport::Chart::StackedBar) { //set x axis CartesianAxis *xAxis = new CartesianAxis(); xAxis->setPosition(CartesianAxis::Bottom); xAxis->setTitleText(i18n("Time")); TextAttributes xAxisTitleTextAttr(xAxis->titleTextAttributes()); xAxisTitleTextAttr.setMinimalFontSize(KGlobalSettings::generalFont().pointSize()); xAxisTitleTextAttr.setPen(m_foregroundBrush.color()); xAxis->setTitleTextAttributes(xAxisTitleTextAttr); TextAttributes xAxisTextAttr(xAxis->textAttributes()); xAxisTextAttr.setPen(m_foregroundBrush.color()); xAxisTextAttr.setAutoRotate(true); xAxis->setTextAttributes(xAxisTextAttr); RulerAttributes xAxisRulerAttr(xAxis->rulerAttributes()); xAxisRulerAttr.setTickMarkPen(m_foregroundBrush.color()); xAxisRulerAttr.setShowRulerLine(true); xAxis->setRulerAttributes(xAxisRulerAttr); //set y axis KBalanceAxis *yAxis = new KBalanceAxis(); yAxis->setPosition(CartesianAxis::Left); // TODO // if the chart shows prices and no balance // the axis title should be 'Price' if (config.isIncludingPrice()) { yAxis->setTitleText(i18n("Price")); } else { yAxis->setTitleText(i18n("Balance")); } TextAttributes yAxisTitleTextAttr(yAxis->titleTextAttributes()); yAxisTitleTextAttr.setMinimalFontSize(KGlobalSettings::generalFont().pointSize()); yAxisTitleTextAttr.setPen(m_foregroundBrush.color()); yAxis->setTitleTextAttributes(yAxisTitleTextAttr); TextAttributes yAxisTextAttr(yAxis->textAttributes()); yAxisTextAttr.setPen(m_foregroundBrush.color()); yAxis->setTextAttributes(yAxisTextAttr); RulerAttributes yAxisRulerAttr(yAxis->rulerAttributes()); yAxisRulerAttr.setTickMarkPen(m_foregroundBrush.color()); yAxisRulerAttr.setShowRulerLine(true); yAxis->setRulerAttributes(yAxisRulerAttr); //add the axes to the corresponding diagram if (config.chartType() == MyMoneyReport::Chart::Line) { KDChart::LineDiagram* lineDiagram = qobject_cast(planeDiagram); lineDiagram->addAxis(xAxis); lineDiagram->addAxis(yAxis); } else if (config.chartType() == MyMoneyReport::Chart::Bar || config.chartType() == MyMoneyReport::Chart::StackedBar) { KDChart::BarDiagram* barDiagram = qobject_cast(planeDiagram); barDiagram->addAxis(xAxis); barDiagram->addAxis(yAxis); } } switch (config.detailLevel()) { case MyMoneyReport::DetailLevel::None: case MyMoneyReport::DetailLevel::End: case MyMoneyReport::DetailLevel::All: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { // iterate over inner groups PivotOuterGroup::const_iterator it_innergroup = (*it_outergroup).begin(); while (it_innergroup != (*it_outergroup).end()) { // // Rows // QString innergroupdata; PivotInnerGroup::const_iterator it_row = (*it_innergroup).begin(); while (it_row != (*it_innergroup).end()) { //Do not include investments accounts in the chart because they are merely container of stock and other accounts if (it_row.key().accountType() != MyMoneyAccount::Investment) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_row.key().name()); } else { legendText = QString(it_row.key().name()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, it_row.value(), rowTypeList[i], legendText, 1, numColumns()); //set the legend text legend->setText(rowNum - 1, legendText); } } } ++it_row; } ++it_innergroup; } ++it_outergroup; } } break; case MyMoneyReport::DetailLevel::Top: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { // iterate over inner groups PivotOuterGroup::const_iterator it_innergroup = (*it_outergroup).begin(); while (it_innergroup != (*it_outergroup).end()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_innergroup.key()); } else { legendText = QString(it_innergroup.key()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, (*it_innergroup).m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend text legend->setText(rowNum - 1, legendText); } } ++it_innergroup; } ++it_outergroup; } } break; case MyMoneyReport::DetailLevel::Group: { int rowNum = 0; // iterate over outer groups PivotGrid::const_iterator it_outergroup = grid.begin(); while (it_outergroup != grid.end()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + it_outergroup.key()); } else { legendText = QString(it_outergroup.key()); } //set the cell value and tooltip rowNum = drawPivotRowSet(rowNum, (*it_outergroup).m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend legend->setText(rowNum - 1, legendText); } } ++it_outergroup; } //if selected, show totals too if (config.isShowingRowTotals()) { //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + i18nc("Total balance", "Total")); } else { legendText = QString(i18nc("Total balance", "Total")); } //set the cell value rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); //set the legend legend->setText(rowNum - 1, legendText); } } } } break; case MyMoneyReport::DetailLevel::Total: { int rowNum = 0; //iterate row types for (int i = 0; i < rowTypeList.size(); ++i) { //skip the budget difference rowset if (rowTypeList[i] != eBudgetDiff) { QString legendText; //only show the column type in the header if there is more than one type if (rowTypeList.size() > 1) { legendText = QString(columnTypeHeaderList[i] + " - " + i18nc("Total balance", "Total")); } else { legendText = QString(i18nc("Total balance", "Total")); } if (config.isMixedTime() && (rowTypeList[i] == eActual || rowTypeList[i] == eForecast)) { if (rowTypeList[i] == eActual) { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, config.currentDateColumn()); } else if (rowTypeList[i] == eForecast) { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, config.currentDateColumn(), numColumns()); } else { rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); } } else { //set cell value rowNum = drawPivotRowSet(rowNum, grid.m_total, rowTypeList[i], legendText, 1, numColumns()); } //set legend text legend->setText(rowNum - 1, legendText); } } } break; } // Set up X axis labels (ie "abscissa" to use the technical term) QStringList abscissaNames; if (accountSeries()) { // if not, we will set these up while putting in the chart values. int column = 1; while (column < numColumns()) { abscissaNames += QString(columnHeadings[column++]).replace(" ", " "); } m_model.setVerticalHeaderLabels(abscissaNames); } //assign model to the diagram planeDiagram->setModel(&m_model); //set the legend basic attributes //this is done after adding the legend because the values are overridden when adding the legend to the chart for (uint i = static_cast(KMyMoneyGlobalSettings::maximumLegendItems()); i < legend->datasetCount(); ++i) { legend->setDatasetHidden(i, true); } legend->setTitleText(i18nc("Chart lines legend", "Legend")); legend->setUseAutomaticMarkerSize(false); FrameAttributes legendFrameAttr(legend->frameAttributes()); legendFrameAttr.setPen(m_foregroundBrush.color()); // leave some space between the content and the frame legendFrameAttr.setPadding(2); legend->setFrameAttributes(legendFrameAttr); legend->setPosition(Position::East); legend->setTextAlignment(Qt::AlignLeft); legend->setLegendStyle(KDChart::Legend::MarkersAndLines); replaceLegend(legend); // set the text attributes after calling replaceLegend() otherwise fon sizes will get overwritten qreal generalFontSize = KGlobalSettings::generalFont().pointSizeF(); if (generalFontSize == -1) generalFontSize = 8; // this is a fallback if the fontsize was specified in pixels TextAttributes legendTextAttr(legend->textAttributes()); legendTextAttr.setPen(m_foregroundBrush.color()); legendTextAttr.setFontSize(KDChart::Measure(generalFontSize, KDChartEnums::MeasureCalculationModeAbsolute)); legend->setTextAttributes(legendTextAttr); TextAttributes legendTitleTextAttr(legend->titleTextAttributes()); legendTitleTextAttr.setPen(m_foregroundBrush.color()); legendTitleTextAttr.setFontSize(KDChart::Measure(generalFontSize + 4, KDChartEnums::MeasureCalculationModeAbsolute)); legend->setTitleTextAttributes(legendTitleTextAttr); //this sets the line width only for line diagrams setLineWidth(config.chartLineWidth()); //set data value attributes //make sure to show only the required number of fractional digits on the labels of the graph DataValueAttributes dataValueAttr(planeDiagram->dataValueAttributes()); MarkerAttributes markerAttr(dataValueAttr.markerAttributes()); markerAttr.setVisible(true); markerAttr.setMarkerStyle(MarkerAttributes::MarkerCircle); markerAttr.setMarkerSize(QSize(8, 8)); dataValueAttr.setMarkerAttributes(markerAttr); TextAttributes dataValueTextAttr(dataValueAttr.textAttributes()); dataValueTextAttr.setPen(m_foregroundBrush.color()); dataValueTextAttr.setFontSize(KDChart::Measure(generalFontSize, KDChartEnums::MeasureCalculationModeAbsolute)); dataValueAttr.setTextAttributes(dataValueTextAttr); dataValueAttr.setVisible(config.isChartDataLabels()); dataValueAttr.setDecimalDigits(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); planeDiagram->setDataValueAttributes(dataValueAttr); planeDiagram->setAllowOverlappingDataValueTexts(true); if (qMin(static_cast(KMyMoneyGlobalSettings::maximumLegendItems()), legend->datasetCount()) < 2) { // the legend is needed only if at least two data sets are rendered removeLegend(); } // fix vertical plane range in case only one value is displayed CartesianCoordinatePlane* plane = dynamic_cast(coordinatePlane()); if (plane) { QPair range = plane->verticalRange(); double center = (range.first + range.second) / 2.0; if (fabs(range.first - range.second) < 0.01) { range.first = center - 1.001; range.second = center + 1.001; plane->setVerticalRange(range); } } } unsigned KReportChartView::drawPivotRowSet(int rowNum, const PivotGridRowSet& rowSet, const ERowType rowType, const QString& legendText, int startColumn, int endColumn) { //if endColumn is invalid, make it the same as numColumns if (endColumn == 0) { endColumn = numColumns(); } // Columns if (seriesTotals()) { double value = rowSet[rowType].m_total.toDouble(); //set the tooltip QString toolTip = QString("

%1

%2
") .arg(legendText) .arg(value, 0, 'f', 2); if (accountSeries()) { //set the cell value this->setDataCell(rowNum, 0, value); this->setCellTip(rowNum, 0, toolTip); } else { this->setDataCell(0, rowNum, value); this->setCellTip(0, rowNum, toolTip); } } else { int column = startColumn; while (column <= endColumn && column < numColumns()) { double value = rowSet[rowType][column].toDouble(); //if zero and set to skip, increase column and continue with next value if (m_skipZero && rowSet[rowType][column].isZero()) { ++column; continue; } else { QString toolTip = QString("

%1

%2
") .arg(legendText) .arg(value, 0, 'f', 2); if (accountSeries()) { this->setDataCell(column - 1, rowNum, value); this->setCellTip(column - 1, rowNum, toolTip); } else { this->setDataCell(rowNum, column - 1, value); this->setCellTip(rowNum, column - 1, toolTip); } } ++column; } } return ++rowNum; } void KReportChartView::setDataCell(int row, int column, const double data) { if (coordinatePlane()->diagram()->datasetDimension() != 1) return; justifyModelSize(row + 1, column + 1); const QModelIndex index = m_model.index(row, column); m_model.setData(index, QVariant(data), Qt::DisplayRole); } void KReportChartView::setCellTip(int row, int column, QString tip) { if (coordinatePlane()->diagram()->datasetDimension() != 1) return; justifyModelSize(row + 1, column + 1); const QModelIndex index = m_model.index(row, column); m_model.setData(index, QVariant(tip), Qt::ToolTipRole); } /** * Justifies the model, so that the given rows and columns fit into it. */ void KReportChartView::justifyModelSize(int rows, int columns) { const int currentRows = m_model.rowCount(); const int currentCols = m_model.columnCount(); if (currentCols < columns) if (! m_model.insertColumns(currentCols, columns - currentCols)) qDebug() << "justifyModelSize: could not increase model size."; if (currentRows < rows) if (! m_model.insertRows(currentRows, rows - currentRows)) qDebug() << "justifyModelSize: could not increase model size."; Q_ASSERT(m_model.rowCount() >= rows); Q_ASSERT(m_model.columnCount() >= columns); } void KReportChartView::setLineWidth(const int lineWidth) { if (qobject_cast(coordinatePlane()->diagram())) { LineDiagram* lineDiagram = qobject_cast(coordinatePlane()->diagram()); QList pens; pens = lineDiagram->datasetPens(); for (int i = 0; i < pens.count(); ++i) { pens[i].setWidth(lineWidth); lineDiagram->setPen(i, pens.at(i)); } } } void KReportChartView::drawLimitLine(const double limit) { // temporarily disconnect the view from the model to aovid update of view on // emission of the dataChanged() signal for each call of setDataCell(). // This speeds up the runtime of drawLimitLine() by a factor of // approx. 60 on my box (1831ms vs. 31ms). AbstractDiagram* planeDiagram = coordinatePlane()->diagram(); planeDiagram->setModel(0); //we get the current number of rows and we add one after that int row = m_model.rowCount(); for (int col = 0; col < m_numColumns; ++col) { setDataCell(col, row, limit); } planeDiagram->setModel(&m_model); //TODO: add format to the line } void KReportChartView::removeLegend() { Legend* chartLegend = Chart::legend(); delete chartLegend; } diff --git a/kmymoney/widgets/kmymoneyreportconfigtabchartdecl.ui b/kmymoney/widgets/kmymoneyreportconfigtabchartdecl.ui index acf7b2e29..844dc45ad 100644 --- a/kmymoney/widgets/kmymoneyreportconfigtabchartdecl.ui +++ b/kmymoney/widgets/kmymoneyreportconfigtabchartdecl.ui @@ -1,177 +1,204 @@ kMyMoneyReportConfigTabChartDecl 0 0 600 - 174 + 183 Chart Tab <p>On this tab, you configure the chart drawn for this report.</p> 0 0 <p>Select what form you would like the chart to be drawn as.</p> Chart Type false Qt::Horizontal QSizePolicy::Expanding 121 20 + + + + + + Chart Palette + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + <p>Select this option to show horizontal and vertical grid lines on the chart.</p> Show grid lines <p>Select this option to draw the numeric values for data points next to their plot location.</p> Draw values on chart <p>Select this option to cause the report to be shown as a chart when you first open the report. Otherwise, it will come up as a text report.</p> Show as chart by default 0 0 <p>Select what width should be used to draw the line on the chart</p> Line width false 1 10 Qt::Horizontal QSizePolicy::Expanding 121 20 Qt::Vertical QSizePolicy::Expanding 20 20 KMyMoneyGeneralCombo KComboBox
kmymoneymvccombo.h
KComboBox QComboBox
kcombobox.h
diff --git a/kmymoney/widgets/kmymoneyreportconfigtabimpl.cpp b/kmymoney/widgets/kmymoneyreportconfigtabimpl.cpp index 245ac3010..743675294 100644 --- a/kmymoney/widgets/kmymoneyreportconfigtabimpl.cpp +++ b/kmymoney/widgets/kmymoneyreportconfigtabimpl.cpp @@ -1,93 +1,98 @@ /* This file is part of the KDE project Copyright (C) 2009 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 "kmymoneyreportconfigtabimpl.h" #include "ui_kmymoneyreportconfigtab1decl.h" #include "ui_kmymoneyreportconfigtab2decl.h" #include "ui_kmymoneyreportconfigtab3decl.h" #include "ui_kmymoneyreportconfigtabchartdecl.h" #include "mymoney/mymoneyreport.h" kMyMoneyReportConfigTab1Decl::kMyMoneyReportConfigTab1Decl(QWidget *parent) : QWidget(parent) { ui = new Ui::kMyMoneyReportConfigTab1Decl; ui->setupUi(this); } kMyMoneyReportConfigTab1Decl::~kMyMoneyReportConfigTab1Decl() { delete ui; } kMyMoneyReportConfigTab2Decl::kMyMoneyReportConfigTab2Decl(QWidget *parent) : QWidget(parent) { ui = new Ui::kMyMoneyReportConfigTab2Decl; ui->setupUi(this); } kMyMoneyReportConfigTab2Decl::~kMyMoneyReportConfigTab2Decl() { delete ui; } kMyMoneyReportConfigTab3Decl::kMyMoneyReportConfigTab3Decl(QWidget *parent) : QWidget(parent) { ui = new Ui::kMyMoneyReportConfigTab3Decl; ui->setupUi(this); ui->buttonGroup1->setExclusive(false); ui->buttonGroup1->setId(ui->m_checkMemo, 0); ui->buttonGroup1->setId(ui->m_checkShares, 1); ui->buttonGroup1->setId(ui->m_checkPrice, 2); ui->buttonGroup1->setId(ui->m_checkReconciled, 3); ui->buttonGroup1->setId(ui->m_checkAccount, 4); ui->buttonGroup1->setId(ui->m_checkNumber, 5); ui->buttonGroup1->setId(ui->m_checkPayee, 6); ui->buttonGroup1->setId(ui->m_checkCategory, 7); ui->buttonGroup1->setId(ui->m_checkAction, 8); ui->buttonGroup1->setId(ui->m_checkBalance, 9); } kMyMoneyReportConfigTab3Decl::~kMyMoneyReportConfigTab3Decl() { delete ui; } kMyMoneyReportConfigTabChartDecl::kMyMoneyReportConfigTabChartDecl(QWidget *parent) : QWidget(parent) { ui = new Ui::kMyMoneyReportConfigTabChartDecl; ui->setupUi(this); ui->m_comboType->addItem(i18nc("type of graphic chart", "Line"), MyMoneyReport::Chart::Line); ui->m_comboType->addItem(i18nc("type of graphic chart", "Bar"), MyMoneyReport::Chart::Bar); ui->m_comboType->addItem(i18nc("type of graphic chart", "Stacked Bar"), MyMoneyReport::Chart::StackedBar); ui->m_comboType->addItem(i18nc("type of graphic chart", "Pie"), MyMoneyReport::Chart::Pie); ui->m_comboType->addItem(i18nc("type of graphic chart", "Ring"), MyMoneyReport::Chart::Ring); + + ui->m_chartPalette->addItem(i18nc("chart palette", "Use application setting"), MyMoneyReport::ChartPalette::Application); + ui->m_chartPalette->addItem(i18nc("chart palette", "Default"), MyMoneyReport::ChartPalette::Default); + ui->m_chartPalette->addItem(i18nc("chart palette", "Rainbowed"), MyMoneyReport::ChartPalette::Rainbow); + ui->m_chartPalette->addItem(i18nc("chart palette", "Subdued"), MyMoneyReport::ChartPalette::Subdued); } kMyMoneyReportConfigTabChartDecl::~kMyMoneyReportConfigTabChartDecl() { delete ui; }