diff --git a/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp b/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp index 62325d1c8..b0f40bfd8 100644 --- a/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp +++ b/kmymoney/dialogs/kreportconfigurationfilterdlg.cpp @@ -1,667 +1,667 @@ /*************************************************************************** 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 "ui_kfindtransactiondlgdecl.h" KReportConfigurationFilterDlg::KReportConfigurationFilterDlg( MyMoneyReport report, QWidget *parent) : KFindTransactionDlg(parent, report.rowType() == MyMoneyReport::eAccount), 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::ePivotTable) { + 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::eQueryTable) { + } 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::eAccountByTopAccount) { 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::EDetailLevel dl[4] = { MyMoneyReport::eDetailAll, MyMoneyReport::eDetailTop, MyMoneyReport::eDetailGroup, MyMoneyReport::eDetailTotal }; 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::ERowType rt[2] = { MyMoneyReport::eExpenseIncome, MyMoneyReport::eAssetLiability }; 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::eBudgetActual); } 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::ERowType rtq[8] = { MyMoneyReport::eCategory, MyMoneyReport::eTopCategory, MyMoneyReport::eTag, MyMoneyReport::ePayee, MyMoneyReport::eAccount, MyMoneyReport::eTopAccount, MyMoneyReport::eMonth, MyMoneyReport::eWeek }; 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::eDetailNone : MyMoneyReport::eDetailAll); } if (m_tabChart) { MyMoneyReport::EChartType ct[5] = { MyMoneyReport::eChartLine, MyMoneyReport::eChartBar, MyMoneyReport::eChartStackedBar, MyMoneyReport::eChartPie, MyMoneyReport::eChartRing }; m_currentState.setChartType(ct[m_tabChart->findChild("m_comboType")->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::eDetailNone: case MyMoneyReport::eDetailEnd: case MyMoneyReport::eDetailAll: combo->setCurrentItem(i18nc("All accounts", "All"), false); break; case MyMoneyReport::eDetailTop: combo->setCurrentItem(i18n("Top-Level"), false); break; case MyMoneyReport::eDetailGroup: combo->setCurrentItem(i18n("Groups"), false); break; case MyMoneyReport::eDetailTotal: combo->setCurrentItem(i18n("Totals"), false); break; } combo = m_tab2->findChild("m_comboRows"); switch (m_initialState.rowType()) { case MyMoneyReport::eExpenseIncome: case MyMoneyReport::eBudget: case MyMoneyReport::eBudgetActual: 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::eBudget || m_initialState.rowType() == MyMoneyReport::eBudgetActual) { 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::Column::NoColumns: case MyMoneyReport::eCategory: combo->setCurrentItem(i18n("Categories"), false); break; case MyMoneyReport::eTopCategory: combo->setCurrentItem(i18n("Top Categories"), false); break; case MyMoneyReport::eTag: combo->setCurrentItem(i18n("Tags"), false); break; case MyMoneyReport::ePayee: combo->setCurrentItem(i18n("Payees"), false); break; case MyMoneyReport::eAccount: combo->setCurrentItem(i18n("Accounts"), false); break; case MyMoneyReport::eTopAccount: combo->setCurrentItem(i18n("Top Accounts"), false); break; case MyMoneyReport::eMonth: combo->setCurrentItem(i18n("Month"), false); break; case MyMoneyReport::eWeek: 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::eDetailNone); } if (m_tabChart) { KMyMoneyGeneralCombo* combo = m_tabChart->findChild("m_comboType"); switch (m_initialState.chartType()) { case MyMoneyReport::eChartNone: combo->setCurrentItem(MyMoneyReport::eChartLine); break; case MyMoneyReport::eChartLine: case MyMoneyReport::eChartBar: case MyMoneyReport::eChartStackedBar: case MyMoneyReport::eChartPie: case MyMoneyReport::eChartRing: combo->setCurrentItem(m_initialState.chartType()); break; case MyMoneyReport::eChartEnd: throw MYMONEYEXCEPTION("KReportConfigurationFilterDlg::slotReset(): Report has invalid charttype"); } 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); // // 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 6f33f70a3..b3b2a7df2 100644 --- a/kmymoney/mymoney/mymoneyreport.cpp +++ b/kmymoney/mymoney/mymoneyreport.cpp @@ -1,868 +1,868 @@ /*************************************************************************** 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 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::kRowTypeText = 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::EReportType MyMoneyReport::kTypeArray[] = { eNoReport, ePivotTable, ePivotTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, eQueryTable, ePivotTable, ePivotTable, eInfoTable, eInfoTable, eInfoTable, eQueryTable, eQueryTable, eNoReport }; const QStringList MyMoneyReport::kDetailLevelText = QString("none,all,top,group,total,invalid").split(','); const QStringList MyMoneyReport::kChartTypeText = QString("none,line,bar,pie,ring,stackedbar,invalid").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 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::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(eDetailNone), m_convertCurrency(true), m_favorite(false), m_tax(false), m_investments(false), m_loans(false), - m_reportType(kTypeArray[eExpenseIncome]), + m_reportType(Report::kTypeArray[eExpenseIncome]), m_rowType(eExpenseIncome), m_columnType(Column::Months), m_columnsAreDays(false), m_queryColumns(QueryColumns::None), m_dateLock(userDefined), m_accountGroupFilter(false), m_chartType(eChartLine), m_chartDataLabels(true), m_chartGridLines(true), m_chartByDefault(false), 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_movingAverageDays(0), m_currentDateColumn(0) { *this = right; setId(id); } MyMoneyReport::MyMoneyReport(ERowType _rt, unsigned _ct, dateOptionE _dl, EDetailLevel _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(kTypeArray[_rt]), + 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(eChartLine), m_chartDataLabels(true), m_chartGridLines(true), m_chartByDefault(false), 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 == ePivotTable) + if (m_reportType == Report::PivotTable) m_columnType = static_cast(_ct); - if (m_reportType == eQueryTable) + if (m_reportType == Report::QueryTable) m_queryColumns = static_cast(_ct); setDateFilter(_dl); //throw exception if the type is inconsistent - if ((_rt > static_cast(sizeof(kTypeArray) / sizeof(kTypeArray[0]))) - || (m_reportType == eNoReport)) + 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::eAssetLiability) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); m_showRowTotals = true; } if (_rt == MyMoneyReport::eAccount) { 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::eExpenseIncome) { 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::eBudget || _rt == MyMoneyReport::eBudgetActual) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); } if (_rt == MyMoneyReport::eAccountInfo) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } //cash flow reports show splits for all account groups if (_rt == MyMoneyReport::eCashFlow) { addAccountGroup(MyMoneyAccount::Expense); addAccountGroup(MyMoneyAccount::Income); addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } #ifdef DEBUG_REPORTS QDebug dbg = qDebug(); - dbg << _name << toString(_rt) << toString(m_reportType); + dbg << _name << 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_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(ERowType _rt) { m_rowType = _rt; - m_reportType = kTypeArray[_rt]; + m_reportType = Report::kTypeArray[_rt]; m_accountGroupFilter = false; m_accountGroups.clear(); if (_rt == MyMoneyReport::eAssetLiability) { addAccountGroup(MyMoneyAccount::Asset); addAccountGroup(MyMoneyAccount::Liability); } if (_rt == MyMoneyReport::eExpenseIncome) { 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::eExpenseIncome) || 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::eExpenseIncome) // 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", kRowTypeText[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 >= kChartTypeText.size()) { qDebug("m_chartType out of bounds with %d on report of type %d. Default to none.", m_chartType, m_reportType); e.setAttribute("charttype", kChartTypeText[0]); } else { e.setAttribute("charttype", kChartTypeText[m_chartType]); } e.setAttribute("chartdatalabels", m_chartDataLabels); e.setAttribute("chartgridlines", m_chartGridLines); e.setAttribute("chartbydefault", m_chartByDefault); e.setAttribute("chartlinewidth", m_chartLineWidth); e.setAttribute("skipZero", m_skipZero); - if (m_reportType == ePivotTable) { + if (m_reportType == Report::PivotTable) { e.setAttribute("type", "pivottable 1.15"); e.setAttribute("detail", kDetailLevelText[m_detailLevel]); e.setAttribute("columntype", Column::kTypeText[m_columnType]); e.setAttribute("showrowtotals", m_showRowTotals); - } else if (m_reportType == eQueryTable) { + } 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 == eInfoTable) { + } else if (m_reportType == Report::InfoTable) { e.setAttribute("type", "infotable 1.0"); e.setAttribute("detail", kDetailLevelText[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; } } // // 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::ePivotTable; + m_reportType = MyMoneyReport::Report::PivotTable; } else if (!e.attribute("type").indexOf("querytable")) { - m_reportType = MyMoneyReport::eQueryTable; + m_reportType = MyMoneyReport::Report::QueryTable; } else if (!e.attribute("type").indexOf("infotable")) { - m_reportType = MyMoneyReport::eInfoTable; + m_reportType = MyMoneyReport::Report::InfoTable; } else { - m_reportType = MyMoneyReport::eNoReport; + 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 = kDetailLevelText.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 = eDetailAll; } else { //set to show the top level account instead m_detailLevel = eDetailTop; } 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 == ePivotTable) { + if (m_reportType == Report::PivotTable) { i = kChartTypeText.indexOf(e.attribute("charttype")); if (i >= 0) m_chartType = static_cast(i); // if it is invalid, set to first type if (m_chartType >= eChartEnd) m_chartType = eChartLine; 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; } 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 = kRowTypeText.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 == eExpenseIncome) 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 ("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; } QString MyMoneyReport::toString(ERowType type) { switch(type) { case eNoRows : return "eNoRows"; case eAssetLiability : return "eAssetLiability"; case eExpenseIncome : return "eExpenseIncome"; case eCategory : return "eCategory"; case eTopCategory : return "eTopCategory"; case eAccount : return "eAccount"; case eTag : return "eTag"; case ePayee : return "ePayee"; case eMonth : return "eMonth"; case eWeek : return "eWeek"; case eTopAccount : return "eTopAccount"; case eAccountByTopAccount: return "eAccountByTopAccount"; case eEquityType : return "eEquityType"; case eAccountType : return "eAccountType"; case eInstitution : return "eInstitution"; case eBudget : return "eBudget"; case eBudgetActual : return "eBudgetActual"; case eSchedule : return "eSchedule"; case eAccountInfo : return "eAccountInfo"; case eAccountLoanInfo : return "eAccountLoanInfo"; case eAccountReconcile : return "eAccountReconcile"; case eCashFlow : return "eCashFlow"; default : return "undefined"; } } - -QString MyMoneyReport::toString(MyMoneyReport::EReportType type) -{ - switch(type) { - case eNoReport: return "eNoReport"; - case ePivotTable: return "ePivotTable"; - case eQueryTable: return "eQueryTable"; - case eInfoTable: return "eInfoTable"; - default: return "undefined"; - } -} diff --git a/kmymoney/mymoney/mymoneyreport.h b/kmymoney/mymoney/mymoneyreport.h index 8e5c34089..05e90097f 100644 --- a/kmymoney/mymoney/mymoneyreport.h +++ b/kmymoney/mymoney/mymoneyreport.h @@ -1,719 +1,722 @@ /*************************************************************************** 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 enum ERowType { eNoRows = 0, eAssetLiability, eExpenseIncome, eCategory, eTopCategory, eAccount, eTag, ePayee, eMonth, eWeek, eTopAccount, eAccountByTopAccount, eEquityType, eAccountType, eInstitution, eBudget, eBudgetActual, eSchedule, eAccountInfo, eAccountLoanInfo, eAccountReconcile, eCashFlow}; - enum EReportType { eNoReport = 0, ePivotTable, eQueryTable, eInfoTable }; + 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; }; enum EDetailLevel { eDetailNone = 0, eDetailAll, eDetailTop, eDetailGroup, eDetailTotal, eDetailEnd }; enum EChartType { eChartNone = 0, eChartLine, eChartBar, eChartPie, eChartRing, eChartStackedBar, eChartEnd }; static const QStringList kRowTypeText; static const QStringList kDetailLevelText; static const QStringList kChartTypeText; - static const EReportType kTypeArray[]; public: MyMoneyReport(); MyMoneyReport(ERowType _rt, unsigned _ct, dateOptionE _dl, EDetailLevel _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); } - EReportType reportType() const { + Report::Type reportType() const { return m_reportType; } ERowType rowType() const { return m_rowType; } Column::Type columnType() const { return m_columnType; } bool isRunningSum() const { return (m_rowType == eAssetLiability); } 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; } EDetailLevel detailLevel() const { return m_detailLevel; } EChartType 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; } 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(ERowType _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(EDetailLevel _detail) { m_detailLevel = _detail; } void setChartType(EChartType _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 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); /** * Return row type as string. * * @param type type to get string for * @return row type converted to string */ static QString toString(ERowType type); - /** - * Return report type as string. - * - * @param type report type to get string for - * @return report type converted to string - */ - static QString toString(EReportType type); - 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 */ enum EDetailLevel 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 */ - enum EReportType m_reportType; + Report::Type m_reportType; /** * What sort of values should show up on the ROWS of this report */ enum ERowType 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 */ enum EChartType 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; /** * 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/views/kreportsview.cpp b/kmymoney/views/kreportsview.cpp index 7f80e6eb6..6c9d39afc 100644 --- a/kmymoney/views/kreportsview.cpp +++ b/kmymoney/views/kreportsview.cpp @@ -1,1784 +1,1784 @@ /*************************************************************************** kreportsview.cpp - description ------------------- begin : Sat Mar 27 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 "kreportsview.h" // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include "querytable.h" #include "objectinfotable.h" #include "kreportconfigurationfilterdlg.h" using namespace reports; #define VIEW_LEDGER "ledger" #define VIEW_SCHEDULE "schedule" #define VIEW_WELCOME "welcome" #define VIEW_HOME "home" #define VIEW_REPORTS "reports" /** * KReportsView::KReportTab Implementation */ KReportsView::KReportTab::KReportTab(KTabWidget* parent, const MyMoneyReport& report): QWidget(parent), m_part(new KHTMLPart(this)), m_chartView(new KReportChartView(this)), m_control(new kMyMoneyReportControl(this)), m_layout(new QVBoxLayout(this)), m_report(report), m_deleteMe(false), m_chartEnabled(false), m_showingChart(false), m_needReload(true), m_table(0) { m_layout->setSpacing(6); m_part->setFontScaleFactor(KMyMoneyGlobalSettings::fontSizePercentage()); //set button icons m_control->buttonChart->setIcon(KIcon("office-chart-line")); m_control->buttonClose->setIcon(KIcon("document-close")); m_control->buttonConfigure->setIcon(KIcon("configure")); m_control->buttonCopy->setIcon(KIcon("edit-copy")); m_control->buttonDelete->setIcon(KIcon("edit-delete")); m_control->buttonExport->setIcon(KIcon("document-export")); m_control->buttonNew->setIcon(KIcon("document-new")); m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_chartView->hide(); m_layout->addWidget(m_control); m_layout->addWidget(m_part->view()); m_layout->addWidget(m_chartView); parent->addTab(this, KIcon("application-vnd.oasis.opendocument.spreadsheet"), report.name()); parent->setTabEnabled(parent->indexOf(this), true); // get users character set encoding m_encoding = KGlobal::locale()->encoding(); } KReportsView::KReportTab::~KReportTab() { delete m_table; //This is to prevent a crash on exit with KDE 4.3.2 delete m_part; } void KReportsView::KReportTab::print() { if (m_part && m_part->view()) m_part->view()->print(); } void KReportsView::KReportTab::copyToClipboard() { QMimeData* pMimeData = new QMimeData(); pMimeData->setHtml(m_table->renderHTML(qobject_cast(this), m_encoding, m_report.name(), true)); QApplication::clipboard()->setMimeData(pMimeData); } void KReportsView::KReportTab::saveAs(const QString& filename, bool includeCSS) { QFile file(filename); if (file.open(QIODevice::WriteOnly)) { if (QFileInfo(filename).suffix().toLower() == "csv") { QTextStream(&file) << m_table->renderCSV(); } else { QString table = m_table->renderHTML(qobject_cast(this), m_encoding, m_report.name(), includeCSS); QTextStream stream(&file); stream << table; } file.close(); } } void KReportsView::KReportTab::loadTab() { m_needReload = true; if (isVisible()) { m_needReload = false; updateReport(); } } void KReportsView::KReportTab::showEvent(QShowEvent * event) { if (m_needReload) { m_needReload = false; updateReport(); } QWidget::showEvent(event); } void KReportsView::KReportTab::updateReport() { // reload the report from the engine. It might have // been changed by the user try { // Don't try to reload default reports from the engine if (!m_report.id().isEmpty()) m_report = MyMoneyFile::instance()->report(m_report.id()); } catch (const MyMoneyException &) { } delete m_table; m_table = 0; - if (m_report.reportType() == MyMoneyReport::ePivotTable) { + if (m_report.reportType() == MyMoneyReport::Report::PivotTable) { m_table = new PivotTable(m_report); m_chartEnabled = true; - } else if (m_report.reportType() == MyMoneyReport::eQueryTable) { + } else if (m_report.reportType() == MyMoneyReport::Report::QueryTable) { m_table = new QueryTable(m_report); m_chartEnabled = false; - } else if (m_report.reportType() == MyMoneyReport::eInfoTable) { + } else if (m_report.reportType() == MyMoneyReport::Report::InfoTable) { m_table = new ObjectInfoTable(m_report); m_chartEnabled = false; } m_part->begin(); m_part->write(m_table->renderHTML(qobject_cast(this), m_encoding, m_report.name())); m_part->end(); m_table->drawChart(*m_chartView); m_control->buttonChart->setEnabled(m_chartEnabled); if (m_report.isChartByDefault() && !m_showingChart) toggleChart(); } void KReportsView::KReportTab::toggleChart() { // for now it will just SHOW the chart. In the future it actually has to toggle it. if (m_showingChart) { m_part->view()->show(); m_chartView->hide(); m_control->buttonChart->setText(i18n("Chart")); m_control->buttonChart->setToolTip(i18n("Show the chart version of this report")); m_control->buttonChart->setIcon(KIcon("office-chart-line")); } else { m_part->view()->hide(); m_chartView->show(); m_control->buttonChart->setText(i18n("Report")); m_control->buttonChart->setToolTip(i18n("Show the report version of this chart")); m_control->buttonChart->setIcon(KIcon("view-financial-list")); } m_showingChart = ! m_showingChart; } /** * KReportsView Implementation */ class KReportsView::Private { public: Private() { fSavProps = new FileSaveProperties(); } ~Private() { delete fSavProps; } class FileSaveProperties { public: FileSaveProperties() { includeCssCheckBox = 0; cbIsChecked = true; filter = "*.csv"; filtCsv = "*.csv|" + i18nc("CSV (Filefilter)", "CSV files"); filtHtml = "*.html|" + i18nc("HTML (Filefilter)", "HTML files"); } /** * 'include css' checkbox for file save dialog. */ QCheckBox* includeCssCheckBox; /** * Persistent checked-state of includeCssCheckBox. */ bool cbIsChecked; /** * Current filtername of file save dialog * without description, e.g. @c '*.csv' */ QString filter; /** * CSV filtername and description. * * @see KFileDialog::KFileDialog */ QString filtCsv; /** * HTML filtername and description. * * @see KFileDialog::KFileDialog */ QString filtHtml; }; FileSaveProperties* fSavProps; }; KReportsView::KReportsView(QWidget *parent, const char *name) : KMyMoneyViewBase(parent, name, i18n("Reports")), d(new Private), m_needReload(false), m_reportListView(0) { // build reports toc setColumnsAlreadyAdjusted(false); m_reportTabWidget = new KTabWidget(this); addWidget(m_reportTabWidget); m_reportTabWidget->setTabsClosable(true); m_listTab = new QWidget(m_reportTabWidget); m_listTabLayout = new QVBoxLayout(m_listTab); m_listTabLayout->setSpacing(6); m_tocTreeWidget = new QTreeWidget(m_listTab); // report-group items have only 1 column (name of group), // report items have 2 columns (report name and comment) m_tocTreeWidget->setColumnCount(2); // headers QStringList headers; headers << i18n("Reports") << i18n("Comment"); m_tocTreeWidget->setHeaderLabels(headers); m_tocTreeWidget->setAlternatingRowColors(true); m_tocTreeWidget->setSortingEnabled(true); m_tocTreeWidget->sortByColumn(0, Qt::AscendingOrder); // for report group items: // doubleclick toggles the expand-state, // so avoid any further action in case of doubleclick // (see slotItemDoubleClicked) m_tocTreeWidget->setExpandsOnDoubleClick(false); m_tocTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu); m_tocTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_listTabLayout->addWidget(m_tocTreeWidget); m_reportTabWidget->addTab(m_listTab, i18n("Reports")); connect(m_reportTabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(slotClose(int))); connect(m_tocTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemDoubleClicked(QTreeWidgetItem*,int))); connect(m_tocTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotListContextMenu(QPoint))); connect(MyMoneyFile::instance(), SIGNAL(dataChanged()), this, SLOT(slotLoadView())); } KReportsView::~KReportsView() { delete d; } void KReportsView::showEvent(QShowEvent * event) { emit aboutToShow(); if (m_needReload) { loadView(); m_needReload = false; } KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) emit reportSelected(tab->report()); else emit reportSelected(MyMoneyReport()); // don't forget base class implementation KMyMoneyViewBase::showEvent(event); } void KReportsView::slotLoadView() { m_needReload = true; if (isVisible()) { loadView(); m_needReload = false; } } void KReportsView::loadView() { // remember the id of the current selected item QTreeWidgetItem* item = m_tocTreeWidget->currentItem(); QString selectedItem = (item) ? item->text(0) : QString(); // save expand states of all top-level items QMap expandStates; for (int i = 0; i < m_tocTreeWidget->topLevelItemCount(); i++) { QTreeWidgetItem* item = m_tocTreeWidget->topLevelItem(i); if (item) { QString itemLabel = item->text(0); if (item->isExpanded()) { expandStates.insert(itemLabel, true); } else { expandStates.insert(itemLabel, false); } } } // find the item visible on top QTreeWidgetItem* visibleTopItem = m_tocTreeWidget->itemAt(0, 0); // text of column 0 identifies the item visible on top QString visibleTopItemText; bool visibleTopItemFound = true; if (visibleTopItem == NULL) { visibleTopItemFound = false; } else { // this assumes, that all item-texts in column 0 are unique, // no matter, whether the item is a report- or a group-item visibleTopItemText = visibleTopItem->text(0); } // turn off updates to avoid flickering during reload //m_reportListView->setUpdatesEnabled(false); // // Rebuild the list page // m_tocTreeWidget->clear(); // Default Reports QList defaultreports; defaultReports(defaultreports); QList::const_iterator it_group = defaultreports.constBegin(); // the item to be set as current item QTreeWidgetItem* currentItem = 0L; // group number, this will be used as sort key for reportgroup items // we have: // 1st some default groups // 2nd a chart group // 3rd maybe a favorite group // 4th maybe an orphan group (for old reports) int defaultGroupNo = 1; int chartGroupNo = defaultreports.size() + 1; // group for diagrams QString groupName = I18N_NOOP("Charts"); TocItemGroup* chartTocItemGroup = new TocItemGroup(m_tocTreeWidget, chartGroupNo, i18n(groupName.toLatin1().data())); m_allTocItemGroups.insert(groupName, chartTocItemGroup); while (it_group != defaultreports.constEnd()) { QString groupName = (*it_group).name(); TocItemGroup* defaultTocItemGroup = new TocItemGroup(m_tocTreeWidget, defaultGroupNo++, i18n(groupName.toLatin1().data())); m_allTocItemGroups.insert(groupName, defaultTocItemGroup); if (groupName == selectedItem) { currentItem = defaultTocItemGroup; } QList::const_iterator it_report = (*it_group).begin(); while (it_report != (*it_group).end()) { MyMoneyReport report = *it_report; report.setGroup(groupName); TocItemReport* reportTocItemReport = new TocItemReport(defaultTocItemGroup, report); if (report.name() == selectedItem) { currentItem = reportTocItemReport; } // ALSO place it into the Charts list if it's displayed as a chart by default if (report.isChartByDefault()) { new TocItemReport(chartTocItemGroup, report); } ++it_report; } ++it_group; } // group for custom (favorite) reports int favoriteGroupNo = chartGroupNo + 1; groupName = I18N_NOOP("Favorite Reports"); TocItemGroup* favoriteTocItemGroup = new TocItemGroup(m_tocTreeWidget, favoriteGroupNo, i18n(groupName.toLatin1().data())); m_allTocItemGroups.insert(groupName, favoriteTocItemGroup); TocItemGroup* orphanTocItemGroup = 0; QList customreports = MyMoneyFile::instance()->reportList(); QList::const_iterator it_report = customreports.constBegin(); while (it_report != customreports.constEnd()) { MyMoneyReport report = *it_report; QString groupName = (*it_report).group(); // If this report is in a known group, place it there // KReportGroupListItem* groupnode = groupitems[(*it_report).group()]; TocItemGroup* groupNode = m_allTocItemGroups[groupName]; if (groupNode) { new TocItemReport(groupNode, report); } else { // otherwise, place it in the orphanage if (!orphanTocItemGroup) { // group for orphaned reports int orphanGroupNo = favoriteGroupNo + 1; QString groupName = I18N_NOOP("Old Customized Reports"); orphanTocItemGroup = new TocItemGroup(m_tocTreeWidget, orphanGroupNo, i18n(groupName.toLatin1().data())); m_allTocItemGroups.insert(groupName, orphanTocItemGroup); } new TocItemReport(orphanTocItemGroup, report); } // ALSO place it into the Favorites list if it's a favorite if ((*it_report).isFavorite()) { new TocItemReport(favoriteTocItemGroup, report); } // ALSO place it into the Charts list if it's displayed as a chart by default if ((*it_report).isChartByDefault()) { new TocItemReport(chartTocItemGroup, report); } ++it_report; } // // Go through the tabs to set their update flag or delete them if needed // int index = 1; while (index < m_reportTabWidget->count()) { // TODO: Find some way of detecting the file is closed and kill these tabs!! KReportTab* tab = dynamic_cast(m_reportTabWidget->widget(index)); if (tab->isReadyToDelete() /* || ! reports.count() */) { delete tab; --index; } else { tab->loadTab(); } ++index; } if (visibleTopItemFound) { // try to find the visibleTopItem that we had at the start of this method // intentionally not using 'Qt::MatchCaseSensitive' here // to avoid 'item not found' if someone corrected a typo only QList visibleTopItemList = m_tocTreeWidget->findItems(visibleTopItemText, Qt::MatchFixedString | Qt::MatchRecursive); if (visibleTopItemList.isEmpty()) { // the item could not be found, it was deleted or renamed visibleTopItemFound = false; } else { visibleTopItem = visibleTopItemList.at(0); if (visibleTopItem == NULL) { visibleTopItemFound = false; } } } // adjust column widths, // but only the first time when the view is loaded, // maybe the user sets other column widths later, // so don't disturb him if (columnsAlreadyAdjusted()) { // restore expand states of all top-level items restoreTocExpandState(expandStates); // restore current item m_tocTreeWidget->setCurrentItem(currentItem); // try to scroll to the item visible on top // when this method started if (visibleTopItemFound) { m_tocTreeWidget->scrollToItem(visibleTopItem); } else { m_tocTreeWidget->scrollToTop(); } return; } // avoid flickering m_tocTreeWidget->setUpdatesEnabled(false); // expand all top-level items m_tocTreeWidget->expandAll(); // resize columns m_tocTreeWidget->resizeColumnToContents(0); m_tocTreeWidget->resizeColumnToContents(1); // restore expand states of all top-level items restoreTocExpandState(expandStates); // restore current item m_tocTreeWidget->setCurrentItem(currentItem); // try to scroll to the item visible on top // when this method started if (visibleTopItemFound) { m_tocTreeWidget->scrollToItem(visibleTopItem); } else { m_tocTreeWidget->scrollToTop(); } setColumnsAlreadyAdjusted(true); m_tocTreeWidget->setUpdatesEnabled(true); } void KReportsView::slotOpenUrl(const KUrl &url, const KParts::OpenUrlArguments&, const KParts::BrowserArguments&) { QString view = url.fileName(); QString command = url.queryItem("command"); QString id = url.queryItem("id"); QString tid = url.queryItem("tid"); if (view == VIEW_REPORTS) { if (command.isEmpty()) { // slotRefreshView(); } else if (command == "print") slotPrintView(); else if (command == "copy") slotCopyView(); else if (command == "save") slotSaveView(); else if (command == "configure") slotConfigure(); else if (command == "duplicate") slotDuplicate(); else if (command == "close") slotCloseCurrent(); else if (command == "delete") slotDelete(); else qWarning() << i18n("Unknown command '%1' in KReportsView::slotOpenUrl()", qPrintable(command)); } else if (view == VIEW_LEDGER) { emit ledgerSelected(id, tid); } else { qWarning() << i18n("Unknown view '%1' in KReportsView::slotOpenUrl()", qPrintable(view)); } } void KReportsView::slotPrintView() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) tab->print(); } void KReportsView::slotCopyView() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) tab->copyToClipboard(); } void KReportsView::slotSaveView() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) { d->fSavProps->includeCssCheckBox = new QCheckBox(i18n("Include Stylesheet")); // restore checkbox checked state d->fSavProps->includeCssCheckBox->setChecked(d->fSavProps->cbIsChecked); QString filterList = d->fSavProps->filtCsv + '\n' + d->fSavProps->filtHtml; QPointer dlg = new KFileDialog(KUrl("kfiledialog:///kmymoney-export"), filterList, this, qobject_cast(d->fSavProps->includeCssCheckBox)); connect(dlg, SIGNAL(filterChanged(QString)), this, SLOT(slotSaveFilterChanged(QString))); dlg->setOperationMode(KFileDialog::Saving); dlg->setCaption(i18n("Export as")); // set current file filter && enable or disable includeCssCheckBox KFileFilterCombo* combo = dlg->filterWidget(); if (d->fSavProps->filter == "*.csv") { combo->setCurrentFilter(d->fSavProps->filtCsv); d->fSavProps->includeCssCheckBox->setEnabled(false); } else { combo->setCurrentFilter(d->fSavProps->filtHtml); d->fSavProps->includeCssCheckBox->setEnabled(true); } if (dlg->exec() == QDialog::Accepted) { KUrl newURL = dlg->selectedUrl(); if (!newURL.isEmpty()) { QString newName = newURL.pathOrUrl(); if (newName.indexOf('.') == -1) newName.append(d->fSavProps->filter.remove('*')); // save checkbox checked state d->fSavProps->cbIsChecked = d->fSavProps->includeCssCheckBox->isChecked(); try { tab->saveAs(newName, d->fSavProps->includeCssCheckBox->isEnabled() && d->fSavProps->includeCssCheckBox->isChecked()); } catch (const MyMoneyException &e) { KMessageBox::error(this, i18n("Failed to save: %1", e.what())); } } } delete d->fSavProps->includeCssCheckBox; delete dlg; } } void KReportsView::slotSaveFilterChanged(const QString& filter) { d->fSavProps->filter = filter; if (filter == "*.html") { d->fSavProps->includeCssCheckBox->setEnabled(true); } else { d->fSavProps->includeCssCheckBox->setEnabled(false); } } void KReportsView::slotConfigure() { QString cm = "KReportsView::slotConfigure"; KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (!tab) { // nothing to do return; } MyMoneyReport report = tab->report(); if (report.comment() == i18n("Default Report") || report.comment() == i18n("Generated Report")) { report.setComment(i18n("Custom Report")); report.setName(i18n("%1 (Customized)", report.name())); } QPointer dlg = new KReportConfigurationFilterDlg(report); if (dlg->exec()) { MyMoneyReport newreport = dlg->getConfig(); // If this report has an ID, then MODIFY it, otherwise ADD it MyMoneyFileTransaction ft; try { if (! newreport.id().isEmpty()) { MyMoneyFile::instance()->modifyReport(newreport); ft.commit(); tab->modifyReport(newreport); m_reportTabWidget->setTabText(m_reportTabWidget->indexOf(tab), newreport.name()); m_reportTabWidget->setCurrentIndex(m_reportTabWidget->indexOf(tab)) ; } else { MyMoneyFile::instance()->addReport(newreport); ft.commit(); QString reportGroupName = newreport.group(); // find report group TocItemGroup* tocItemGroup = m_allTocItemGroups[reportGroupName]; if (!tocItemGroup) { QString error = i18n("Could not find reportgroup \"%1\" for report \"%2\".\nPlease report this error to the developer's list: kmymoney-devel@kde.org", reportGroupName, newreport.name()); // write to messagehandler qWarning() << cm << error; // also inform user KMessageBox::error(m_reportTabWidget, error, i18n("Critical Error")); // cleanup delete dlg; return; } // do not add TocItemReport to TocItemGroup here, // this is done in loadView addReportTab(newreport); } } catch (const MyMoneyException &e) { KMessageBox::error(this, i18n("Failed to configure report: %1", e.what())); } } delete dlg; } void KReportsView::slotDuplicate() { QString cm = "KReportsView::slotDuplicate"; KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (!tab) { // nothing to do return; } MyMoneyReport dupe = tab->report(); dupe.setName(i18n("Copy of %1", dupe.name())); if (dupe.comment() == i18n("Default Report")) dupe.setComment(i18n("Custom Report")); dupe.clearId(); QPointer dlg = new KReportConfigurationFilterDlg(dupe); if (dlg->exec()) { MyMoneyReport newReport = dlg->getConfig(); MyMoneyFileTransaction ft; try { MyMoneyFile::instance()->addReport(newReport); ft.commit(); QString reportGroupName = newReport.group(); // find report group TocItemGroup* tocItemGroup = m_allTocItemGroups[reportGroupName]; if (!tocItemGroup) { QString error = i18n("Could not find reportgroup \"%1\" for report \"%2\".\nPlease report this error to the developer's list: kmymoney-devel@kde.org", reportGroupName, newReport.name()); // write to messagehandler qWarning() << cm << error; // also inform user KMessageBox::error(m_reportTabWidget, error, i18n("Critical Error")); // cleanup delete dlg; return; } // do not add TocItemReport to TocItemGroup here, // this is done in loadView addReportTab(newReport); } catch (const MyMoneyException &e) { QString error = i18n("Cannot add report, reason: \"%1\"", e.what()); // write to messagehandler qWarning() << cm << error; // also inform user KMessageBox::error(m_reportTabWidget, error, i18n("Critical Error")); } } delete dlg; } void KReportsView::slotDelete() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (!tab) { // nothing to do return; } MyMoneyReport report = tab->report(); if (! report.id().isEmpty()) { if (KMessageBox::Continue == deleteReportDialog(report.name())) { // close the tab and then remove the report so that it is not // generated again during the following loadView() call slotClose(m_reportTabWidget->currentIndex()); MyMoneyFileTransaction ft; MyMoneyFile::instance()->removeReport(report); ft.commit(); } } else { KMessageBox::information(this, QString("") + i18n("%1 is a default report, so it cannot be deleted.", report.name()) + QString(""), i18n("Delete Report?")); } } int KReportsView::deleteReportDialog(const QString &reportName) { return KMessageBox::warningContinueCancel(this, QString("") + i18n("Are you sure you want to delete report %1? There is no way to recover it.", reportName) + QString(""), i18n("Delete Report?")); } void KReportsView::slotOpenReport(const QString& id) { if (id.isEmpty()) { // nothing to do return; } KReportTab* page = 0; // Find the tab which contains the report int index = 1; while (index < m_reportTabWidget->count()) { KReportTab* current = dynamic_cast(m_reportTabWidget->widget(index)); if (current->report().id() == id) { page = current; break; } ++index; } // Show the tab, or create a new one, as needed if (page) m_reportTabWidget->setCurrentIndex(m_reportTabWidget->indexOf(page)); else addReportTab(MyMoneyFile::instance()->report(id)); } void KReportsView::slotOpenReport(const MyMoneyReport& report) { kDebug(2) << Q_FUNC_INFO << " " << report.name(); KReportTab* page = 0; // Find the tab which contains the report indicated by this list item int index = 1; while (index < m_reportTabWidget->count()) { KReportTab* current = dynamic_cast(m_reportTabWidget->widget(index)); if (current->report().name() == report.name()) { page = current; break; } ++index; } // Show the tab, or create a new one, as needed if (page) m_reportTabWidget->setCurrentIndex(m_reportTabWidget->indexOf(page)); else addReportTab(report); } void KReportsView::slotItemDoubleClicked(QTreeWidgetItem* item, int) { TocItem* tocItem = dynamic_cast(item); if (!tocItem->isReport()) { // toggle the expanded-state for reportgroup-items item->setExpanded(item->isExpanded() ? false : true); // nothing else to do for reportgroup-items return; } TocItemReport* reportTocItem = dynamic_cast(tocItem); MyMoneyReport& report = reportTocItem->getReport(); KReportTab* page = 0; // Find the tab which contains the report indicated by this list item int index = 1; while (index < m_reportTabWidget->count()) { KReportTab* current = dynamic_cast(m_reportTabWidget->widget(index)); // If this report has an ID, we'll use the ID to match if (! report.id().isEmpty()) { if (current->report().id() == report.id()) { page = current; break; } } // Otherwise, use the name to match. THIS ASSUMES that no 2 default reports // have the same name...but that would be pretty a boneheaded thing to do. else { if (current->report().name() == report.name()) { page = current; break; } } ++index; } // Show the tab, or create a new one, as needed if (page) m_reportTabWidget->setCurrentIndex(m_reportTabWidget->indexOf(page)); else addReportTab(report); } void KReportsView::slotToggleChart() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) tab->toggleChart(); } void KReportsView::slotCloseCurrent() { slotClose(m_reportTabWidget->currentIndex()); } void KReportsView::slotClose(int index) { KReportTab* tab = dynamic_cast(m_reportTabWidget->widget(index)); if (tab) { m_reportTabWidget->removeTab(index); tab->setReadyToDelete(true); } } void KReportsView::slotCloseAll() { KReportTab* tab = dynamic_cast(m_reportTabWidget->widget(1)); while (tab) { m_reportTabWidget->removeTab(m_reportTabWidget->indexOf(tab)); tab->setReadyToDelete(true); tab = dynamic_cast(m_reportTabWidget->widget(1)); } } void KReportsView::addReportTab(const MyMoneyReport& report) { KReportTab* tab = new KReportTab(m_reportTabWidget, report); connect(tab->control()->buttonChart, SIGNAL(clicked()), this, SLOT(slotToggleChart())); connect(tab->control()->buttonConfigure, SIGNAL(clicked()), this, SLOT(slotConfigure())); connect(tab->control()->buttonNew, SIGNAL(clicked()), this, SLOT(slotDuplicate())); connect(tab->control()->buttonCopy, SIGNAL(clicked()), this, SLOT(slotCopyView())); connect(tab->control()->buttonExport, SIGNAL(clicked()), this, SLOT(slotSaveView())); connect(tab->control()->buttonDelete, SIGNAL(clicked()), this, SLOT(slotDelete())); connect(tab->control()->buttonClose, SIGNAL(clicked()), this, SLOT(slotCloseCurrent())); connect(tab->browserExtenstion(), SIGNAL(openUrlRequest(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)), this, SLOT(slotOpenUrl(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments))); // if this is a default report, then you can't delete it! if (report.id().isEmpty()) tab->control()->buttonDelete->setEnabled(false); m_reportTabWidget->setCurrentIndex(m_reportTabWidget->indexOf(tab)); } void KReportsView::slotListContextMenu(const QPoint & p) { QTreeWidgetItem *item = m_tocTreeWidget->itemAt(p); if (!item) { return; } TocItem* tocItem = dynamic_cast(item); if (!tocItem->isReport()) { // currently there is no context menu for reportgroup items return; } KMenu* contextmenu = new KMenu(this); contextmenu->addAction(i18nc("To open a new report", "&Open"), this, SLOT(slotOpenFromList())); contextmenu->addAction(i18nc("Configure a report", "&Configure"), this, SLOT(slotConfigureFromList())); contextmenu->addAction(i18n("&New report"), this, SLOT(slotNewFromList())); // Only add this option if it's a custom report. Default reports cannot be deleted TocItemReport* reportTocItem = dynamic_cast(tocItem); MyMoneyReport& report = reportTocItem->getReport(); if (! report.id().isEmpty()) { contextmenu->addAction(i18n("&Delete"), this, SLOT(slotDeleteFromList())); } contextmenu->popup(m_tocTreeWidget->mapToGlobal(p)); } void KReportsView::slotOpenFromList() { TocItem* tocItem = dynamic_cast(m_tocTreeWidget->currentItem()); if (tocItem) slotItemDoubleClicked(tocItem, 0); } void KReportsView::slotConfigureFromList() { TocItem* tocItem = dynamic_cast(m_tocTreeWidget->currentItem()); if (tocItem) { slotItemDoubleClicked(tocItem, 0); slotConfigure(); } } void KReportsView::slotNewFromList() { TocItem* tocItem = dynamic_cast(m_tocTreeWidget->currentItem()); if (tocItem) { slotItemDoubleClicked(tocItem, 0); slotDuplicate(); } } void KReportsView::slotDeleteFromList() { TocItem* tocItem = dynamic_cast(m_tocTreeWidget->currentItem()); if (tocItem) { TocItemReport* reportTocItem = dynamic_cast(tocItem); MyMoneyReport& report = reportTocItem->getReport(); // If this report does not have an ID, it's a default report and cannot be deleted if (! report.id().isEmpty() && KMessageBox::Continue == deleteReportDialog(report.name())) { // check if report's tab is open; start from 1 because 0 is toc tab for (int i = 1; i < m_reportTabWidget->count(); ++i) { KReportTab* tab = dynamic_cast(m_reportTabWidget->widget(i)); if (tab->report().id() == report.id()) { slotClose(i); // if open, close it, so no crash when switching to it break; } } MyMoneyFileTransaction ft; MyMoneyFile::instance()->removeReport(report); ft.commit(); } } } void KReportsView::defaultReports(QList& groups) { { ReportGroup list("Income and Expenses", i18n("Income and Expenses")); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::eDetailAll, i18n("Income and Expenses This Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Income and Expenses This Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Years, MyMoneyTransactionFilter::allDates, MyMoneyReport::eDetailAll, i18n("Income and Expenses By Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::eDetailTop, i18n("Income and Expenses Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setChartDataLabels(false); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailGroup, i18n("Income and Expenses Pie Chart"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartType(MyMoneyReport::eChartPie); list.back().setShowingRowTotals(false); groups.push_back(list); } { ReportGroup list("Net Worth", i18n("Net Worth")); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailTop, i18n("Net Worth By Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::eDetailTop, i18n("Net Worth Today"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Years, MyMoneyTransactionFilter::allDates, MyMoneyReport::eDetailTop, i18n("Net Worth By Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next7Days, MyMoneyReport::eDetailTop, i18n("7-day Cash Flow Forecast"), i18n("Default Report") )); list.back().setIncludingSchedules(true); list.back().setColumnsAreDays(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::eDetailTotal, i18n("Net Worth Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.push_back(MyMoneyReport( MyMoneyReport::eInstitution, MyMoneyReport::QueryColumns::None, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailTop, i18n("Account Balances by Institution"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eAccountType, MyMoneyReport::QueryColumns::None, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailTop, i18n("Account Balances by Type"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("Transactions", i18n("Transactions")); list.push_back(MyMoneyReport( MyMoneyReport::eAccount, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag | MyMoneyReport::QueryColumns::Balance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Account"), i18n("Default Report") )); //list.back().setConvertCurrency(false); list.push_back(MyMoneyReport( MyMoneyReport::eCategory, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Category"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::ePayee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Payee"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eTag, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Tag"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eMonth, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eWeek, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Transactions by Week"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::eAccount, MyMoneyReport::QueryColumns::Loan, MyMoneyTransactionFilter::allDates, MyMoneyReport::eDetailAll, i18n("Loan Transactions"), i18n("Default Report") )); list.back().setLoansOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAccountReconcile, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Balance, MyMoneyTransactionFilter::last3Months, MyMoneyReport::eDetailAll, i18n("Transactions by Reconciliation Status"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("CashFlow", i18n("Cash Flow")); list.push_back(MyMoneyReport( MyMoneyReport::eCashFlow, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Cash Flow Transactions This Month"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("Investments", i18n("Investments")); list.push_back(MyMoneyReport( MyMoneyReport::eTopAccount, MyMoneyReport::QueryColumns::Action | MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Investment Transactions"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAccountByTopAccount, MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Investment Holdings by Account"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eEquityType, MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Investment Holdings by Type"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAccountByTopAccount, MyMoneyReport::QueryColumns::Performance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Investment Performance by Account"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eEquityType, MyMoneyReport::QueryColumns::Performance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Investment Performance by Type"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::eDetailAll, i18n("Investment Holdings Pie"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartPie); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::eDetailAll, i18n("Investment Worth Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::eDetailAll, i18n("Investment Price Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.back().setIncludingBudgetActuals(false); list.back().setIncludingPrice(true); list.back().setConvertCurrency(true); list.back().setChartDataLabels(false); list.back().setSkipZero(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::eDetailAll, i18n("Investment Moving Average Price Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.back().setIncludingBudgetActuals(false); list.back().setIncludingAveragePrice(true); list.back().setMovingAverageDays(10); list.back().setConvertCurrency(true); list.back().setChartDataLabels(false); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last30Days, MyMoneyReport::eDetailAll, i18n("Investment Moving Average"), i18n("Default Report") )); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.back().setIncludingBudgetActuals(false); list.back().setIncludingMovingAverage(true); list.back().setMovingAverageDays(10); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last30Days, MyMoneyReport::eDetailAll, i18n("Investment Moving Average vs Actual"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.back().setIncludingBudgetActuals(true); list.back().setIncludingMovingAverage(true); list.back().setMovingAverageDays(10); groups.push_back(list); } { ReportGroup list("Taxes", i18n("Taxes")); list.push_back(MyMoneyReport( MyMoneyReport::eCategory, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Tax Transactions by Category"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::ePayee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Tax Transactions by Payee"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::eCategory, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::lastFiscalYear, MyMoneyReport::eDetailAll, i18n("Tax Transactions by Category Last Fiscal Year"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::ePayee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::lastFiscalYear, MyMoneyReport::eDetailAll, i18n("Tax Transactions by Payee Last Fiscal Year"), i18n("Default Report") )); list.back().setTax(true); groups.push_back(list); } { ReportGroup list("Budgeting", i18n("Budgeting")); list.push_back(MyMoneyReport( MyMoneyReport::eBudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::eDetailAll, i18n("Budgeted vs. Actual This Year"), i18n("Default Report") )); list.back().setShowingRowTotals(true); list.back().setBudget("Any", true); list.push_back(MyMoneyReport( MyMoneyReport::eBudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToMonth, MyMoneyReport::eDetailAll, i18n("Budgeted vs. Actual This Year (YTM)"), i18n("Default Report") )); list.back().setShowingRowTotals(true); list.back().setBudget("Any", true); // in case we're in January, we show the last year if (QDate::currentDate().month() == 1) { list.back().setDateFilter(MyMoneyTransactionFilter::lastYear); } list.push_back(MyMoneyReport( MyMoneyReport::eBudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::eDetailAll, i18n("Monthly Budgeted vs. Actual"), i18n("Default Report") )); list.back().setBudget("Any", true); list.push_back(MyMoneyReport( MyMoneyReport::eBudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::eDetailAll, i18n("Yearly Budgeted vs. Actual"), i18n("Default Report") )); list.back().setBudget("Any", true); list.back().setShowingRowTotals(true); list.push_back(MyMoneyReport( MyMoneyReport::eBudget, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::eDetailAll, i18n("Monthly Budget"), i18n("Default Report") )); list.back().setBudget("Any", false); list.push_back(MyMoneyReport( MyMoneyReport::eBudget, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::eDetailAll, i18n("Yearly Budget"), i18n("Default Report") )); list.back().setBudget("Any", false); list.back().setShowingRowTotals(true); list.push_back(MyMoneyReport( MyMoneyReport::eBudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::eDetailGroup, i18n("Yearly Budgeted vs Actual Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setBudget("Any", true); list.back().setChartType(MyMoneyReport::eChartLine); groups.push_back(list); } { ReportGroup list("Forecast", i18n("Forecast")); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::eDetailTop, i18n("Forecast By Month"), i18n("Default Report") )); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::nextQuarter, MyMoneyReport::eDetailTop, i18n("Forecast Next Quarter"), i18n("Default Report") )); list.back().setColumnsAreDays(true); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::eExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::eDetailTop, i18n("Income and Expenses Forecast This Year"), i18n("Default Report") )); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::eAssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next3Months, MyMoneyReport::eDetailTotal, i18n("Net Worth Forecast Graph"), i18n("Default Report") )); list.back().setColumnsAreDays(true); list.back().setIncludingForecast(true); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::eChartLine); groups.push_back(list); } { ReportGroup list("Information", i18n("General Information")); list.push_back(MyMoneyReport( MyMoneyReport::eSchedule, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::eDetailAll, i18n("Schedule Information"), i18n("Default Report") )); list.back().setDetailLevel(MyMoneyReport::eDetailAll); list.push_back(MyMoneyReport( MyMoneyReport::eSchedule, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::eDetailAll, i18n("Schedule Summary Information"), i18n("Default Report") )); list.back().setDetailLevel(MyMoneyReport::eDetailTop); list.push_back(MyMoneyReport( MyMoneyReport::eAccountInfo, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::eDetailAll, i18n("Account Information"), i18n("Default Report") )); list.back().setConvertCurrency(false); list.push_back(MyMoneyReport( MyMoneyReport::eAccountLoanInfo, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::eDetailAll, i18n("Loan Information"), i18n("Default Report") )); list.back().setConvertCurrency(false); groups.push_back(list); } } bool KReportsView::columnsAlreadyAdjusted() { return m_columnsAlreadyAdjusted; } void KReportsView::setColumnsAlreadyAdjusted(bool adjusted) { m_columnsAlreadyAdjusted = adjusted; } void KReportsView::restoreTocExpandState(QMap& expandStates) { for (int i = 0; i < m_tocTreeWidget->topLevelItemCount(); i++) { QTreeWidgetItem* item = m_tocTreeWidget->topLevelItem(i); if (item) { QString itemLabel = item->text(0); if (expandStates.contains(itemLabel)) { item->setExpanded(expandStates[itemLabel]); } else { item->setExpanded(false); } } } } // Make sure, that these definitions are only used within this file // this does not seem to be necessary, but when building RPMs the // build option 'final' is used and all CPP files are concatenated. // So it could well be, that in another CPP file these definitions // are also used. #undef VIEW_LEDGER #undef VIEW_SCHEDULE #undef VIEW_WELCOME #undef VIEW_HOME #undef VIEW_REPORTS