File indexing completed on 2024-06-16 04:46:41

0001 /*
0002     SPDX-FileCopyrightText: 2000-2004 Michael Edwardes <mte@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2000-2004 Javier Campos Morales <javi_c@users.sourceforge.net>
0004     SPDX-FileCopyrightText: 2000-2004 Felix Rodriguez <frodriguez@users.sourceforge.net>
0005     SPDX-FileCopyrightText: 2000-2004 John C <thetacoturtle@users.sourceforge.net>
0006     SPDX-FileCopyrightText: 2000-2004 Thomas Baumgart <ipwizard@users.sourceforge.net>
0007     SPDX-FileCopyrightText: 2000-2004 Kevin Tambascio <ktambascio@users.sourceforge.net>
0008     SPDX-FileCopyrightText: 2000-2004 Ace Jones <ace.j@hotpop.com>
0009     SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0010     SPDX-FileCopyrightText: 2018 Michael Kiefer <Michael-Kiefer@web.de>
0011     SPDX-FileCopyrightText: 2021 Dawid Wróbel <me@dawidwrobel.com>
0012     SPDX-License-Identifier: GPL-2.0-or-later
0013 */
0014 
0015 #ifndef KREPORTSVIEW_P_H
0016 #define KREPORTSVIEW_P_H
0017 
0018 #include "kreportsview.h"
0019 
0020 // ----------------------------------------------------------------------------
0021 // QT Includes
0022 
0023 #include <QClipboard>
0024 #include <QFile>
0025 #include <QFileDialog>
0026 #include <QFileInfo>
0027 #include <QIcon>
0028 #include <QList>
0029 #include <QLocale>
0030 #include <QMenu>
0031 #include <QMimeData>
0032 #include <QPointer>
0033 #include <QPrintPreviewDialog>
0034 #include <QTextCodec>
0035 #include <QTimer>
0036 #include <QTreeWidget>
0037 #include <QTreeWidgetItem>
0038 #include <QUrlQuery>
0039 #include <QVBoxLayout>
0040 #include <QWheelEvent>
0041 
0042 // ----------------------------------------------------------------------------
0043 // KDE Includes
0044 
0045 #include <KChartAbstractCoordinatePlane>
0046 #include <KLazyLocalizedString>
0047 #include <KLocalizedString>
0048 #include <KMessageBox>
0049 #include <QPainter>
0050 
0051 // ----------------------------------------------------------------------------
0052 // Project Includes
0053 
0054 #include "ui_kreportsview.h"
0055 #include "ui_reportcontrol.h"
0056 
0057 #include "icons.h"
0058 #include "kmm_printer.h"
0059 #include "kmmtextbrowser.h"
0060 #include "kmymoneysettings.h"
0061 #include "kmymoneyviewbase_p.h"
0062 #include "kreportchartview.h"
0063 #include "kreportconfigurationfilterdlg.h"
0064 #include "mymoneyenums.h"
0065 #include "mymoneyexception.h"
0066 #include "mymoneyfile.h"
0067 #include "mymoneyreport.h"
0068 #include "objectinfotable.h"
0069 #include "pivottable.h"
0070 #include "querytable.h"
0071 #include "reportcontrolimpl.h"
0072 #include "reporttable.h"
0073 #include "tocitem.h"
0074 #include "tocitemgroup.h"
0075 #include "tocitemreport.h"
0076 
0077 using namespace reports;
0078 using namespace eMyMoney;
0079 using namespace Icons;
0080 
0081 #define VIEW_LEDGER         "ledger"
0082 #define VIEW_SCHEDULE       "schedule"
0083 #define VIEW_WELCOME        "welcome"
0084 #define VIEW_HOME           "home"
0085 #define VIEW_REPORTS        "reports"
0086 
0087 /**
0088   * Helper class for KReportView.
0089   *
0090   * This is the widget which displays a single report in the TabWidget that comprises this view.
0091   *
0092   * @author Ace Jones
0093   */
0094 
0095 class KReportTab: public QWidget
0096 {
0097 private:
0098     KMMTextBrowser* m_tableView;
0099     reports::KReportChartView *m_chartView;
0100     ReportControl             *m_control;
0101     QVBoxLayout               *m_layout;
0102     MyMoneyReport m_report;
0103     bool m_deleteMe;
0104     bool m_chartEnabled;
0105     bool m_showingChart;
0106     bool m_needReload;
0107     bool m_isChartViewValid;
0108     bool m_isTableViewValid;
0109     QPointer<reports::ReportTable> m_table;
0110 
0111     /**
0112      * Users character set encoding.
0113      */
0114     QByteArray m_encoding;
0115 
0116 public:
0117     KReportTab(QTabWidget* parent, const MyMoneyReport& report, const KReportsView* eventHandler, KReportsView::OpenOption openOption);
0118     ~KReportTab();
0119     const MyMoneyReport& report() const {
0120         return m_report;
0121     }
0122     void print();
0123     void printPreview();
0124     void toggleChart();
0125     /**
0126      * Updates information about plotted chart in report's data
0127      */
0128     void updateDataRange();
0129     void copyToClipboard();
0130     void saveAs(const QString& filename, const QString& selectedMimeType);
0131     void updateReport();
0132     QString createTable(const QString& links = QString());
0133     const ReportControl* control() const
0134     {
0135         return m_control;
0136     }
0137 
0138     bool isReadyToDelete() const
0139     {
0140         return m_deleteMe;
0141     }
0142 
0143     void setReadyToDelete(bool f)
0144     {
0145         m_deleteMe = f;
0146     }
0147 
0148     void modifyReport(const MyMoneyReport& report)
0149     {
0150         m_report = report;
0151         updateReport();
0152     }
0153 
0154     void enableAllReportActions()
0155     {
0156         pActions[eMenu::Action::ReportNew]->setEnabled(true);
0157         pActions[eMenu::Action::ReportConfigure]->setEnabled(true);
0158         pActions[eMenu::Action::ReportExport]->setEnabled(true);
0159         pActions[eMenu::Action::ReportDelete]->setEnabled(true);
0160         pActions[eMenu::Action::ReportClose]->setEnabled(true);
0161     }
0162 
0163     void showEvent(QShowEvent * event) final override;
0164     void loadTab();
0165 
0166 protected:
0167     void wheelEvent(QWheelEvent *event) override;
0168 
0169 };
0170 
0171 /**
0172   * Helper class for KReportView.
0173   *
0174   * This is a named list of reports, which will be one section
0175   * in the list of default reports
0176   *
0177   * @author Ace Jones
0178   */
0179 class ReportGroup: public QList<MyMoneyReport>
0180 {
0181 private:
0182     QString m_name;     ///< the title of the group in non-translated form
0183     QString m_title;    ///< the title of the group in i18n-ed form
0184 public:
0185     ReportGroup() {}
0186     ReportGroup(const QString& name, const QString& title): m_name(name), m_title(title) {}
0187     const QString& name() const {
0188         return m_name;
0189     }
0190     const QString& title() const {
0191         return m_title;
0192     }
0193 };
0194 
0195 /**
0196   * KReportTab Implementation
0197   */
0198 KReportTab::KReportTab(QTabWidget* parent, const MyMoneyReport& report, const KReportsView* eventHandler, KReportsView::OpenOption openOption)
0199     : QWidget(parent)
0200     , m_tableView(new KMMTextBrowser(this))
0201     , m_chartView(new KReportChartView(this))
0202     , m_control(new ReportControl(this))
0203     , m_layout(new QVBoxLayout(this))
0204     , m_report(report)
0205     , m_deleteMe(false)
0206     , m_chartEnabled(false)
0207     , m_showingChart(report.isChartByDefault())
0208     , m_needReload(openOption == KReportsView::OpenImmediately)
0209     , m_isChartViewValid(false)
0210     , m_isTableViewValid(false)
0211     , m_table(0)
0212 {
0213     m_layout->setSpacing(6);
0214     // TODO
0215     //    m_tableView->setZoomFactor(KMyMoneySettings::zoomFactor());
0216 
0217     // set button icons
0218     m_control->ui->buttonChart->setIcon(Icons::get(Icon::OfficeCharBar));
0219     m_control->ui->buttonClose->setIcon(Icons::get(Icon::DocumentClose));
0220     m_control->ui->buttonConfigure->setIcon(Icons::get(Icon::Configure));
0221     m_control->ui->buttonDelete->setIcon(Icons::get(Icon::EditRemove));
0222     m_control->ui->buttonExport->setIcon(Icons::get(Icon::DocumentExport));
0223     m_control->ui->buttonNew->setIcon(Icons::get(Icon::DocumentNew));
0224 
0225     // and actions
0226     m_control->ui->buttonClose->setDefaultAction(pActions[eMenu::Action::ReportClose]);
0227     m_control->ui->buttonConfigure->setDefaultAction(pActions[eMenu::Action::ReportConfigure]);
0228     m_control->ui->buttonDelete->setDefaultAction(pActions[eMenu::Action::ReportDelete]);
0229     m_control->ui->buttonExport->setDefaultAction(pActions[eMenu::Action::ReportExport]);
0230     m_control->ui->buttonNew->setDefaultAction(pActions[eMenu::Action::ReportNew]);
0231 
0232     m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0233     m_chartView->hide();
0234     m_tableView->hide();
0235     m_tableView->setOpenLinks(false);
0236 
0237     m_layout->addWidget(m_control);
0238     m_layout->addWidget(m_tableView);
0239     m_layout->addWidget(m_chartView);
0240     m_layout->setStretch(1, 10);
0241     m_layout->setStretch(2, 10);
0242 
0243     connect(m_control->ui->buttonChart, &QAbstractButton::clicked, eventHandler, &KReportsView::slotToggleChart);
0244 
0245     // setup style for all buttons to contain icon and text
0246     const auto buttons = m_control->findChildren<QToolButton*>();
0247     for (auto* button : qAsConst(buttons)) {
0248         button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0249     }
0250     enableAllReportActions();
0251 
0252     connect(m_tableView, &KMMTextBrowser::anchorClicked, eventHandler, &KReportsView::slotOpenUrl);
0253 
0254     // if this is a default report, then you can't delete it!
0255     if (report.id().isEmpty())
0256         m_control->ui->buttonDelete->setEnabled(false);
0257 
0258     int tabNr = parent->addTab(this,
0259                                Icons::get(Icon::Report),
0260                                report.name());
0261     parent->setTabEnabled(tabNr, true);
0262     parent->setCurrentIndex(tabNr);
0263 
0264     // get users character set encoding
0265     m_encoding = QTextCodec::codecForLocale()->name();
0266 }
0267 
0268 KReportTab::~KReportTab()
0269 {
0270     delete m_table;
0271 }
0272 
0273 
0274 void KReportTab::wheelEvent(QWheelEvent* event)
0275 {
0276     // Zoom text on Ctrl + Scroll
0277     if (event->modifiers() & Qt::CTRL) {
0278         if (!m_showingChart) {
0279             // TODO
0280             //            qreal factor = m_tableView->zoomFactor();
0281             if (event->angleDelta().y() > 0)
0282                 //                factor += 0.1;
0283                 //            else if (event->delta() < 0)
0284                 //                factor -= 0.1;
0285                 //            m_tableView->setZoomFactor(factor);
0286                 event->accept();
0287             return;
0288         }
0289     }
0290 }
0291 
0292 
0293 void KReportTab::print()
0294 {
0295     if (m_tableView) {
0296         auto printer = KMyMoneyPrinter::startPrint();
0297         if (printer != nullptr) {
0298             if (m_showingChart) {
0299                 QPainter painter(printer);
0300                 m_chartView->paint(&painter, painter.window());
0301                 QFont font = painter.font();
0302                 font.setPointSizeF(font.pointSizeF() * 0.8);
0303                 painter.setFont(font);
0304                 painter.drawText(0, 0, MyMoneyUtils::formatDate(QDate::currentDate()));
0305 
0306                 /// @todo extract url from KMyMoneyApp
0307                 QUrl file;
0308                 if (file.isValid()) {
0309                     painter.drawText(0, painter.window().height(), file.toLocalFile());
0310                 }
0311             } else {
0312                 m_tableView->print(printer);
0313             }
0314         }
0315     }
0316 }
0317 
0318 void KReportTab::printPreview()
0319 {
0320     if (m_showingChart) {
0321         if (m_chartView) {
0322             QPrintPreviewDialog dlg(KMyMoneyPrinter::instance(), m_chartView);
0323             connect(&dlg, &QPrintPreviewDialog::paintRequested, m_tableView, [&](QPrinter* printer) {
0324                 QPainter painter(printer);
0325                 m_chartView->paint(&painter, painter.window());
0326             });
0327             dlg.exec();
0328         }
0329     } else {
0330         if (m_tableView) {
0331             QPrintPreviewDialog dlg(KMyMoneyPrinter::instance(), m_tableView);
0332             connect(&dlg, &QPrintPreviewDialog::paintRequested, m_tableView, [&](QPrinter* printer) {
0333                 m_tableView->print(printer);
0334             });
0335             dlg.exec();
0336         }
0337     }
0338 }
0339 
0340 void KReportTab::saveAs(const QString& filename, const QString& selectedMimeType)
0341 {
0342     QFile file(filename);
0343 
0344     if (file.open(QIODevice::WriteOnly)) {
0345         if (selectedMimeType == QStringLiteral("text/csv")) {
0346             QTextStream(&file) << m_table->renderReport(QLatin1String("csv"), m_encoding, QString());
0347         } else {
0348             QString table = m_table->renderReport(QLatin1String("html"), m_encoding, m_report.name());
0349             QTextStream stream(&file);
0350             stream << table;
0351         }
0352         file.close();
0353     }
0354 }
0355 
0356 void KReportTab::loadTab()
0357 {
0358     m_needReload = true;
0359     if (isVisible()) {
0360         m_needReload = false;
0361         updateReport();
0362     }
0363 }
0364 
0365 void KReportTab::showEvent(QShowEvent * event)
0366 {
0367     if (m_needReload) {
0368         m_needReload = false;
0369         updateReport();
0370     }
0371     QWidget::showEvent(event);
0372 }
0373 
0374 void KReportTab::updateReport()
0375 {
0376     m_isChartViewValid = false;
0377     m_isTableViewValid = false;
0378     // reload the report from the engine. It might have
0379     // been changed by the user
0380 
0381     try {
0382         // Don't try to reload default reports from the engine
0383         if (!m_report.id().isEmpty())
0384             m_report = MyMoneyFile::instance()->report(m_report.id());
0385     } catch (const MyMoneyException &) {
0386     }
0387 
0388     delete m_table;
0389     m_table = nullptr;
0390 
0391     if (m_report.reportType() == eMyMoney::Report::ReportType::PivotTable) {
0392         m_table = new PivotTable(m_report);
0393         m_chartEnabled = true;
0394     } else if (m_report.reportType() == eMyMoney::Report::ReportType::QueryTable) {
0395         m_table = new QueryTable(m_report);
0396         m_chartEnabled = false;
0397     } else if (m_report.reportType() == eMyMoney::Report::ReportType::InfoTable) {
0398         m_table = new ObjectInfoTable(m_report);
0399         m_chartEnabled = false;
0400     }
0401 
0402     m_control->ui->buttonChart->setEnabled(m_chartEnabled);
0403 
0404     m_showingChart = !m_showingChart;
0405     toggleChart();
0406 }
0407 
0408 void KReportTab::toggleChart()
0409 {
0410     // for now it will just SHOW the chart.  In the future it actually has to toggle it.
0411 
0412     if (m_showingChart) {
0413         if (!m_isTableViewValid) {
0414             m_tableView->setHtml(m_table->renderReport(QLatin1String("html"), m_encoding, m_report.name()));
0415         }
0416         m_isTableViewValid = true;
0417         m_tableView->show();
0418         m_chartView->hide();
0419 
0420         m_control->ui->buttonChart->setText(i18n("Chart"));
0421         m_control->ui->buttonChart->setToolTip(i18n("Show the chart version of this report"));
0422         m_control->ui->buttonChart->setIcon(Icons::get(Icon::OfficeCharBar));
0423     } else {
0424         if (!m_isChartViewValid)
0425             m_table->drawChart(*m_chartView);
0426         m_isChartViewValid = true;
0427         m_tableView->hide();
0428         m_chartView->show();
0429 
0430         m_control->ui->buttonChart->setText(i18n("Report"));
0431         m_control->ui->buttonChart->setToolTip(i18n("Show the report version of this chart"));
0432         m_control->ui->buttonChart->setIcon(Icons::get(Icon::Report));
0433     }
0434     m_showingChart = ! m_showingChart;
0435 }
0436 
0437 void KReportTab::updateDataRange()
0438 {
0439     static const QRegularExpression trailingsZeroesRegEx("0+$");
0440 
0441     QList<DataDimension> grids = m_chartView->coordinatePlane()->gridDimensionsList();    // get dimensions of plotted graph
0442     if (grids.isEmpty())
0443         return;
0444     auto separator = locale().groupSeparator(); // QChar in Qt5, QString in Qt6
0445     auto decimalPoint = locale().decimalPoint(); // QChar in Qt5, QString in Qt6
0446     int precision = m_report.yLabelsPrecision();
0447     QList<QPair<QString, qreal>> dims;  // create list of dimension values in string and qreal
0448 
0449     // get qreal values
0450     dims.append(qMakePair(QString(), grids.at(1).start));
0451     dims.append(qMakePair(QString(), grids.at(1).end));
0452     dims.append(qMakePair(QString(), grids.at(1).stepWidth));
0453     dims.append(qMakePair(QString(), grids.at(1).subStepWidth));
0454 
0455     // convert qreal values to string variables
0456     for (int i = 0; i < 4; ++i) {
0457         if (i > 2)
0458             ++precision;
0459         if (precision == 0)
0460             dims[i].first = locale().toString(qRound(dims.at(i).second));
0461         else
0462             dims[i].first = locale()
0463                                 .toString(dims.at(i).second, 'f', precision)
0464                                 .remove(separator)
0465                                 .remove(trailingsZeroesRegEx)
0466                                 .remove(QRegularExpression("\\" + decimalPoint + "$"));
0467     }
0468 
0469     // save string variables in report's data
0470     m_report.setDataRangeStart(dims.at(0).first);
0471     m_report.setDataRangeEnd(dims.at(1).first);
0472     m_report.setDataMajorTick(dims.at(2).first);
0473     m_report.setDataMinorTick(dims.at(3).first);
0474 }
0475 
0476 class KReportsViewPrivate : public KMyMoneyViewBasePrivate
0477 {
0478     Q_DECLARE_PUBLIC(KReportsView)
0479 
0480 public:
0481     explicit KReportsViewPrivate(KReportsView *qq)
0482         : KMyMoneyViewBasePrivate(qq)
0483         , m_needLoad(true)
0484         , m_reportListView(nullptr)
0485         , m_columnsAlreadyAdjusted(false)
0486     {
0487     }
0488 
0489     ~KReportsViewPrivate()
0490     {
0491     }
0492 
0493     void init()
0494     {
0495         Q_Q(KReportsView);
0496         m_needLoad = false;
0497         m_needsRefresh = true;
0498 
0499         // build reports toc
0500 
0501         setColumnsAlreadyAdjusted(false);
0502         ui.setupUi(q);
0503         ui.m_tocTreeWidget->sortByColumn(0, Qt::AscendingOrder);
0504 
0505         ui.m_closeButton->setIcon(Icons::get(Icon::DialogClose));
0506         ui.m_filterContainer->hide();
0507         ui.m_searchWidget->installEventFilter(q);
0508         ui.m_tocTreeWidget->installEventFilter(q);
0509 
0510         q->connect(ui.m_reportTabWidget, &QTabWidget::tabCloseRequested, q, &KReportsView::slotClose);
0511         q->connect(ui.m_tocTreeWidget, &QTreeWidget::itemDoubleClicked, q, &KReportsView::slotItemDoubleClicked);
0512         q->connect(ui.m_tocTreeWidget, &QWidget::customContextMenuRequested, q, &KReportsView::slotListContextMenu);
0513         q->connect(MyMoneyFile::instance(), &MyMoneyFile::dataChanged, q, &KReportsView::refresh);
0514 
0515         m_focusWidget = ui.m_tocTreeWidget;
0516     }
0517 
0518     QMap<QString, bool> saveTocExpandState()
0519     {
0520         QMap<QString, bool> expandStates;
0521         for (int i = 0; i < ui.m_tocTreeWidget->topLevelItemCount(); ++i) {
0522             const auto item = ui.m_tocTreeWidget->topLevelItem(i);
0523 
0524             if (item) {
0525                 QString itemLabel = item->text(0);
0526 
0527                 if (item->isExpanded()) {
0528                     expandStates.insert(itemLabel, true);
0529                 } else {
0530                     expandStates.insert(itemLabel, false);
0531                 }
0532             }
0533         }
0534         return expandStates;
0535     }
0536 
0537     void restoreTocExpandState(QMap<QString, bool>& expandStates)
0538     {
0539         for (auto i = 0; i < ui.m_tocTreeWidget->topLevelItemCount(); ++i) {
0540             QTreeWidgetItem* item = ui.m_tocTreeWidget->topLevelItem(i);
0541 
0542             if (item) {
0543                 QString itemLabel = item->text(0);
0544 
0545                 if (expandStates.contains(itemLabel)) {
0546                     item->setExpanded(expandStates[itemLabel]);
0547                 } else {
0548                     item->setExpanded(false);
0549                 }
0550             }
0551         }
0552     }
0553 
0554     /**
0555       * Display a dialog to confirm report deletion
0556       */
0557     int deleteReportDialog(const QString &reportName)
0558     {
0559         Q_Q(KReportsView);
0560         return KMessageBox::warningContinueCancel(q,
0561                 i18n("<qt>Are you sure you want to delete report <b>%1</b>?  There is no way to recover it.</qt>",
0562                      reportName), i18n("Delete Report?"));
0563     }
0564 
0565     void addReportTab(const MyMoneyReport& report, KReportsView::OpenOption openOption)
0566     {
0567         Q_Q(KReportsView);
0568         auto reportTab = new KReportTab(ui.m_reportTabWidget, report, q, openOption);
0569         reportTab->installEventFilter(q);
0570     }
0571 
0572     void loadView()
0573     {
0574         // remember the id of the current selected item
0575         QTreeWidgetItem* item = ui.m_tocTreeWidget->currentItem();
0576         QString selectedItem = (item) ? item->text(0) : QString();
0577 
0578         // save expand states of all top-level items
0579         QMap<QString, bool> expandStates = saveTocExpandState();
0580 
0581         // find the item visible on top
0582         QTreeWidgetItem* visibleTopItem = ui.m_tocTreeWidget->itemAt(0, 0);
0583 
0584         // text of column 0 identifies the item visible on top
0585         QString visibleTopItemText;
0586 
0587         bool visibleTopItemFound = true;
0588         if (visibleTopItem == NULL) {
0589             visibleTopItemFound = false;
0590         } else {
0591             // this assumes, that all item-texts in column 0 are unique,
0592             // no matter, whether the item is a report- or a group-item
0593             visibleTopItemText = visibleTopItem->text(0);
0594         }
0595 
0596         // turn off updates to avoid flickering during reload
0597         //m_reportListView->setUpdatesEnabled(false);
0598 
0599         //
0600         // Rebuild the list page
0601         //
0602         ui.m_tocTreeWidget->clear();
0603 
0604         // Default Reports
0605         QList<ReportGroup> defaultreports;
0606         defaultReports(defaultreports);
0607 
0608         QList<ReportGroup>::const_iterator it_group = defaultreports.constBegin();
0609 
0610         // the item to be set as current item
0611         QTreeWidgetItem* currentItem = 0L;
0612 
0613         // group number, this will be used as sort key for reportgroup items
0614         // we have:
0615         // 1st some default groups
0616         // 2nd a chart group
0617         // 3rd maybe a favorite group
0618         // 4th maybe an orphan group (for old reports)
0619         int defaultGroupNo = 1;
0620         int chartGroupNo = defaultreports.size() + 1;
0621 
0622         // group for diagrams
0623         QString groupName = kli18n("Charts").untranslatedText();
0624 
0625         TocItemGroup* chartTocItemGroup = new TocItemGroup(ui.m_tocTreeWidget, chartGroupNo, i18n(groupName.toLatin1().data()));
0626 
0627         m_allTocItemGroups.insert(groupName, chartTocItemGroup);
0628 
0629         while (it_group != defaultreports.constEnd()) {
0630             groupName = (*it_group).name();
0631 
0632             TocItemGroup* defaultTocItemGroup = new TocItemGroup(ui.m_tocTreeWidget, defaultGroupNo++, i18n(groupName.toLatin1().data()));
0633 
0634             m_allTocItemGroups.insert(groupName, defaultTocItemGroup);
0635 
0636             if (groupName == selectedItem) {
0637                 currentItem = defaultTocItemGroup;
0638             }
0639 
0640             QList<MyMoneyReport>::const_iterator it_report = (*it_group).begin();
0641             while (it_report != (*it_group).end()) {
0642                 MyMoneyReport report = *it_report;
0643                 report.setGroup(groupName);
0644 
0645                 TocItemReport* reportTocItemReport =
0646                     new TocItemReport(defaultTocItemGroup, report);
0647 
0648                 if (report.name() == selectedItem) {
0649                     currentItem = reportTocItemReport;
0650                 }
0651 
0652                 // ALSO place it into the Charts list if it's displayed as a chart by default
0653                 if (report.isChartByDefault()) {
0654                     new TocItemReport(chartTocItemGroup, report);
0655                 }
0656 
0657                 ++it_report;
0658             }
0659 
0660             ++it_group;
0661         }
0662 
0663         // group for custom (favorite) reports
0664         int favoriteGroupNo = chartGroupNo + 1;
0665 
0666         groupName = kli18n("Favorite Reports").untranslatedText();
0667 
0668         TocItemGroup* favoriteTocItemGroup = new TocItemGroup(ui.m_tocTreeWidget, favoriteGroupNo, i18n(groupName.toLatin1().data()));
0669 
0670         m_allTocItemGroups.insert(groupName, favoriteTocItemGroup);
0671 
0672         TocItemGroup* orphanTocItemGroup = 0;
0673 
0674         QList<MyMoneyReport> customreports = MyMoneyFile::instance()->reportList();
0675         QList<MyMoneyReport>::const_iterator it_report = customreports.constBegin();
0676         while (it_report != customreports.constEnd()) {
0677 
0678             MyMoneyReport report = *it_report;
0679 
0680             groupName = (*it_report).group();
0681 
0682             // If this report is in a known group, place it there
0683             // KReportGroupListItem* groupnode = groupitems[(*it_report).group()];
0684             TocItemGroup* groupNode = m_allTocItemGroups[groupName];
0685 
0686             if (groupNode) {
0687                 new TocItemReport(groupNode, report);
0688             } else {
0689                 // otherwise, place it in the orphanage
0690                 if (!orphanTocItemGroup) {
0691 
0692                     // group for orphaned reports
0693                     int orphanGroupNo = favoriteGroupNo + 1;
0694 
0695                     groupName = kli18n("Old Customized Reports").untranslatedText();
0696 
0697                     orphanTocItemGroup = new TocItemGroup(ui.m_tocTreeWidget, orphanGroupNo, i18n(groupName.toLatin1().data()));
0698                     m_allTocItemGroups.insert(groupName, orphanTocItemGroup);
0699                 }
0700                 new TocItemReport(orphanTocItemGroup, report);
0701             }
0702 
0703             // ALSO place it into the Favorites list if it's a favorite
0704             if ((*it_report).isFavorite()) {
0705                 new TocItemReport(favoriteTocItemGroup, report);
0706             }
0707 
0708             // ALSO place it into the Charts list if it's displayed as a chart by default
0709             if ((*it_report).isChartByDefault()) {
0710                 new TocItemReport(chartTocItemGroup, report);
0711             }
0712 
0713             ++it_report;
0714         }
0715 
0716         //
0717         // Go through the tabs to set their update flag or delete them if needed
0718         //
0719 
0720         int index = 1;
0721         while (index < ui.m_reportTabWidget->count()) {
0722             // TODO: Find some way of detecting the file is closed and kill these tabs!!
0723             if (auto tab = dynamic_cast<KReportTab*>(ui.m_reportTabWidget->widget(index))) {
0724                 if (tab->isReadyToDelete() /* || ! reports.count() */) {
0725                     delete tab;
0726                     --index;
0727                 } else {
0728                     tab->loadTab();
0729                 }
0730             }
0731             ++index;
0732         }
0733 
0734         if (visibleTopItemFound) {
0735             // try to find the visibleTopItem that we had at the start of this method
0736 
0737             // intentionally not using 'Qt::MatchCaseSensitive' here
0738             // to avoid 'item not found' if someone corrected a typo only
0739             QList<QTreeWidgetItem*> visibleTopItemList = ui.m_tocTreeWidget->findItems(visibleTopItemText, Qt::MatchFixedString | Qt::MatchRecursive);
0740 
0741             if (visibleTopItemList.isEmpty()) {
0742                 // the item could not be found, it was deleted or renamed
0743                 visibleTopItemFound = false;
0744             } else {
0745                 visibleTopItem = visibleTopItemList.at(0);
0746                 if (visibleTopItem == NULL) {
0747                     visibleTopItemFound = false;
0748                 }
0749             }
0750         }
0751 
0752         // adjust column widths,
0753         // but only the first time when the view is loaded,
0754         // maybe the user sets other column widths later,
0755         // so don't disturb him
0756         if (columnsAlreadyAdjusted()) {
0757 
0758             // restore expand states of all top-level items
0759             restoreTocExpandState(expandStates);
0760 
0761             // restore current item
0762             ui.m_tocTreeWidget->setCurrentItem(currentItem);
0763 
0764             // try to scroll to the item visible on top
0765             // when this method started
0766             if (visibleTopItemFound) {
0767                 ui.m_tocTreeWidget->scrollToItem(visibleTopItem);
0768             } else {
0769                 ui.m_tocTreeWidget->scrollToTop();
0770             }
0771             return;
0772         }
0773 
0774         // avoid flickering
0775         ui.m_tocTreeWidget->setUpdatesEnabled(false);
0776 
0777         // expand all top-level items
0778         ui.m_tocTreeWidget->expandAll();
0779 
0780         // resize columns
0781         ui.m_tocTreeWidget->resizeColumnToContents(0);
0782         ui.m_tocTreeWidget->resizeColumnToContents(1);
0783 
0784         // restore expand states of all top-level items
0785         restoreTocExpandState(expandStates);
0786 
0787         // restore current item
0788         ui.m_tocTreeWidget->setCurrentItem(currentItem);
0789 
0790         // try to scroll to the item visible on top
0791         // when this method started
0792         if (visibleTopItemFound) {
0793             ui.m_tocTreeWidget->scrollToItem(visibleTopItem);
0794         } else {
0795             ui.m_tocTreeWidget->scrollToTop();
0796         }
0797 
0798         setColumnsAlreadyAdjusted(true);
0799 
0800         ui.m_tocTreeWidget->setUpdatesEnabled(true);
0801     }
0802 
0803     void defaultReports(QList<ReportGroup>& groups)
0804     {
0805         {
0806             ReportGroup list("Income and Expenses", i18n("Income and Expenses"));
0807 
0808             list.push_back(MyMoneyReport(
0809                                eMyMoney::Report::RowType::ExpenseIncome,
0810                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0811                                TransactionFilter::Date::CurrentMonth,
0812                                eMyMoney::Report::DetailLevel::All,
0813                                i18n("Income and Expenses This Month"),
0814                                i18n("Default Report")
0815                            ));
0816             list.push_back(MyMoneyReport(
0817                                eMyMoney::Report::RowType::ExpenseIncome,
0818                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0819                                TransactionFilter::Date::YearToDate,
0820                                eMyMoney::Report::DetailLevel::All,
0821                                i18n("Income and Expenses This Year"),
0822                                i18n("Default Report")
0823                            ));
0824             list.push_back(MyMoneyReport(
0825                                eMyMoney::Report::RowType::ExpenseIncome,
0826                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Years),
0827                                TransactionFilter::Date::All,
0828                                eMyMoney::Report::DetailLevel::All,
0829                                i18n("Income and Expenses By Year"),
0830                                i18n("Default Report")
0831                            ));
0832 
0833             list.push_back(MyMoneyReport(
0834                                eMyMoney::Report::RowType::ExpenseIncome,
0835                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0836                                TransactionFilter::Date::Last12Months,
0837                                eMyMoney::Report::DetailLevel::Top,
0838                                i18n("Income and Expenses Graph"),
0839                                i18n("Default Report")
0840                            ));
0841             list.back().setChartByDefault(true);
0842             list.back().setChartType(eMyMoney::Report::ChartType::Line);
0843             list.back().setChartDataLabels(false);
0844 
0845             list.push_back(MyMoneyReport(
0846                                eMyMoney::Report::RowType::ExpenseIncome,
0847                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0848                                TransactionFilter::Date::Last12Months,
0849                                eMyMoney::Report::DetailLevel::Top,
0850                                i18n("Income and Expenses Bar Graph"),
0851                                i18n("Default Report")
0852                            ));
0853             list.back().setChartByDefault(true);
0854             list.back().setChartType(eMyMoney::Report::ChartType::StackedBar);
0855             list.back().setChartDataLabels(false);
0856             list.back().setNegExpenses(true);
0857 
0858             list.push_back(MyMoneyReport(
0859                                eMyMoney::Report::RowType::ExpenseIncome,
0860                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0861                                TransactionFilter::Date::YearToDate,
0862                                eMyMoney::Report::DetailLevel::Group,
0863                                i18n("Income and Expenses Pie Chart"),
0864                                i18n("Default Report")
0865                            ));
0866             list.back().setChartByDefault(true);
0867             list.back().setChartType(eMyMoney::Report::ChartType::Pie);
0868             list.back().setShowingRowTotals(false);
0869 
0870             groups.push_back(list);
0871         }
0872         {
0873             ReportGroup list("Net Worth", i18n("Net Worth"));
0874 
0875             list.push_back(MyMoneyReport(
0876                                eMyMoney::Report::RowType::AssetLiability,
0877                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0878                                TransactionFilter::Date::YearToDate,
0879                                eMyMoney::Report::DetailLevel::Top,
0880                                i18n("Net Worth By Month"),
0881                                i18n("Default Report")
0882                            ));
0883             list.push_back(MyMoneyReport(
0884                                eMyMoney::Report::RowType::AssetLiability,
0885                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0886                                TransactionFilter::Date::Today,
0887                                eMyMoney::Report::DetailLevel::Top,
0888                                i18n("Net Worth Today"),
0889                                i18n("Default Report")
0890                            ));
0891             list.push_back(MyMoneyReport(
0892                                eMyMoney::Report::RowType::AssetLiability,
0893                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Years),
0894                                TransactionFilter::Date::All,
0895                                eMyMoney::Report::DetailLevel::Top,
0896                                i18n("Net Worth By Year"),
0897                                i18n("Default Report")
0898                            ));
0899             list.push_back(MyMoneyReport(
0900                                eMyMoney::Report::RowType::AssetLiability,
0901                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0902                                TransactionFilter::Date::Next7Days,
0903                                eMyMoney::Report::DetailLevel::Top,
0904                                i18n("7-day Cash Flow Forecast"),
0905                                i18n("Default Report")
0906                            ));
0907             list.back().setIncludingSchedules(true);
0908             list.back().setColumnsAreDays(true);
0909 
0910             list.push_back(MyMoneyReport(
0911                                eMyMoney::Report::RowType::AssetLiability,
0912                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
0913                                TransactionFilter::Date::Last12Months,
0914                                eMyMoney::Report::DetailLevel::Total,
0915                                i18n("Net Worth Graph"),
0916                                i18n("Default Report")
0917                            ));
0918             list.back().setChartByDefault(true);
0919             list.back().setChartCHGridLines(false);
0920             list.back().setChartSVGridLines(false);
0921             list.back().setChartType(eMyMoney::Report::ChartType::Line);
0922 
0923             list.push_back(MyMoneyReport(
0924                                eMyMoney::Report::RowType::Institution,
0925                                eMyMoney::Report::QueryColumn::None,
0926                                TransactionFilter::Date::YearToDate,
0927                                eMyMoney::Report::DetailLevel::Top,
0928                                i18n("Account Balances by Institution"),
0929                                i18n("Default Report")
0930                            ));
0931 
0932             list.push_back(MyMoneyReport(
0933                                eMyMoney::Report::RowType::AccountType,
0934                                eMyMoney::Report::QueryColumn::None,
0935                                TransactionFilter::Date::YearToDate,
0936                                eMyMoney::Report::DetailLevel::Top,
0937                                i18n("Account Balances by Type"),
0938                                i18n("Default Report")
0939                            ));
0940 
0941             groups.push_back(list);
0942         }
0943         {
0944             ReportGroup list("Transactions", i18n("Transactions"));
0945 
0946             list.push_back(MyMoneyReport(
0947                                eMyMoney::Report::RowType::Account,
0948                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Tag | eMyMoney::Report::QueryColumn::Balance,
0949                                TransactionFilter::Date::YearToDate,
0950                                eMyMoney::Report::DetailLevel::All,
0951                                i18n("Transactions by Account"),
0952                                i18n("Default Report")
0953                            ));
0954             //list.back().setConvertCurrency(false);
0955             list.push_back(MyMoneyReport(
0956                                eMyMoney::Report::RowType::Category,
0957                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Account | eMyMoney::Report::QueryColumn::Tag,
0958                                TransactionFilter::Date::YearToDate,
0959                                eMyMoney::Report::DetailLevel::All,
0960                                i18n("Transactions by Category"),
0961                                i18n("Default Report")
0962                            ));
0963             list.push_back(MyMoneyReport(
0964                                eMyMoney::Report::RowType::Payee,
0965                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Tag,
0966                                TransactionFilter::Date::YearToDate,
0967                                eMyMoney::Report::DetailLevel::All,
0968                                i18n("Transactions by Payee"),
0969                                i18n("Default Report")
0970                            ));
0971             list.push_back(MyMoneyReport(
0972                                eMyMoney::Report::RowType::Tag,
0973                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Category,
0974                                TransactionFilter::Date::YearToDate,
0975                                eMyMoney::Report::DetailLevel::All,
0976                                i18n("Transactions by Tag"),
0977                                i18n("Default Report")
0978                            ));
0979             list.push_back(MyMoneyReport(
0980                                eMyMoney::Report::RowType::Month,
0981                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Tag,
0982                                TransactionFilter::Date::YearToDate,
0983                                eMyMoney::Report::DetailLevel::All,
0984                                i18n("Transactions by Month"),
0985                                i18n("Default Report")
0986                            ));
0987             list.push_back(MyMoneyReport(
0988                                eMyMoney::Report::RowType::Week,
0989                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Tag,
0990                                TransactionFilter::Date::YearToDate,
0991                                eMyMoney::Report::DetailLevel::All,
0992                                i18n("Transactions by Week"),
0993                                i18n("Default Report")
0994                            ));
0995             list.push_back(MyMoneyReport(
0996                                eMyMoney::Report::RowType::Account,
0997                                eMyMoney::Report::QueryColumn::Loan,
0998                                TransactionFilter::Date::All,
0999                                eMyMoney::Report::DetailLevel::All,
1000                                i18n("Loan Transactions"),
1001                                i18n("Default Report")
1002                            ));
1003             list.back().setLoansOnly(true);
1004             list.push_back(MyMoneyReport(
1005                                eMyMoney::Report::RowType::AccountReconcile,
1006                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Balance,
1007                                TransactionFilter::Date::Last3Months,
1008                                eMyMoney::Report::DetailLevel::All,
1009                                i18n("Transactions by Reconciliation Status"),
1010                                i18n("Default Report")
1011                            ));
1012             groups.push_back(list);
1013         }
1014         {
1015             ReportGroup list("CashFlow", i18n("Cash Flow"));
1016             list.push_back(MyMoneyReport(eMyMoney::Report::RowType::CashFlow,
1017                                          eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Account,
1018                                          TransactionFilter::Date::CurrentMonth,
1019                                          eMyMoney::Report::DetailLevel::All,
1020                                          i18n("Cash Flow Transactions This Month"),
1021                                          i18n("Default Report")));
1022             groups.push_back(list);
1023         }
1024         {
1025             ReportGroup list("Investments", i18n("Investments"));
1026 
1027             list.push_back(MyMoneyReport(
1028                                eMyMoney::Report::RowType::TopAccount,
1029                                eMyMoney::Report::QueryColumn::Action | eMyMoney::Report::QueryColumn::Shares | eMyMoney::Report::QueryColumn::Price,
1030                                TransactionFilter::Date::YearToDate,
1031                                eMyMoney::Report::DetailLevel::All,
1032                                i18n("Investment Transactions"),
1033                                i18n("Default Report")
1034                            ));
1035             list.back().setInvestmentsOnly(true);
1036 
1037             list.push_back(MyMoneyReport(
1038                                eMyMoney::Report::RowType::AccountByTopAccount,
1039                                eMyMoney::Report::QueryColumn::Shares | eMyMoney::Report::QueryColumn::Price,
1040                                TransactionFilter::Date::YearToDate,
1041                                eMyMoney::Report::DetailLevel::All,
1042                                i18n("Investment Holdings by Account"),
1043                                i18n("Default Report")
1044                            ));
1045             list.back().setInvestmentsOnly(true);
1046 
1047             list.push_back(MyMoneyReport(
1048                                eMyMoney::Report::RowType::EquityType,
1049                                eMyMoney::Report::QueryColumn::Shares | eMyMoney::Report::QueryColumn::Price,
1050                                TransactionFilter::Date::YearToDate,
1051                                eMyMoney::Report::DetailLevel::All,
1052                                i18n("Investment Holdings by Type"),
1053                                i18n("Default Report")
1054                            ));
1055             list.back().setInvestmentsOnly(true);
1056 
1057             list.push_back(MyMoneyReport(
1058                                eMyMoney::Report::RowType::AccountByTopAccount,
1059                                eMyMoney::Report::QueryColumn::Performance,
1060                                TransactionFilter::Date::YearToDate,
1061                                eMyMoney::Report::DetailLevel::All,
1062                                i18n("Investment Performance by Account"),
1063                                i18n("Default Report")
1064                            ));
1065             list.back().setInvestmentsOnly(true);
1066 
1067             list.push_back(MyMoneyReport(
1068                                eMyMoney::Report::RowType::EquityType,
1069                                eMyMoney::Report::QueryColumn::Performance,
1070                                TransactionFilter::Date::YearToDate,
1071                                eMyMoney::Report::DetailLevel::All,
1072                                i18n("Investment Performance by Type"),
1073                                i18n("Default Report")
1074                            ));
1075             list.back().setInvestmentsOnly(true);
1076 
1077             list.push_back(MyMoneyReport(
1078                                eMyMoney::Report::RowType::AccountByTopAccount,
1079                                eMyMoney::Report::QueryColumn::CapitalGain,
1080                                TransactionFilter::Date::YearToDate,
1081                                eMyMoney::Report::DetailLevel::All,
1082                                i18n("Investment Capital Gains by Account"),
1083                                i18n("Default Report")
1084                            ));
1085             list.back().setInvestmentsOnly(true);
1086 
1087             list.push_back(MyMoneyReport(
1088                                eMyMoney::Report::RowType::EquityType,
1089                                eMyMoney::Report::QueryColumn::CapitalGain,
1090                                TransactionFilter::Date::YearToDate,
1091                                eMyMoney::Report::DetailLevel::All,
1092                                i18n("Investment Capital Gains by Type"),
1093                                i18n("Default Report")
1094                            ));
1095             list.back().setInvestmentsOnly(true);
1096 
1097             list.push_back(MyMoneyReport(
1098                                eMyMoney::Report::RowType::AssetLiability,
1099                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1100                                TransactionFilter::Date::Today,
1101                                eMyMoney::Report::DetailLevel::All,
1102                                i18n("Investment Holdings Pie"),
1103                                i18n("Default Report")
1104                            ));
1105             list.back().setChartByDefault(true);
1106             list.back().setChartCHGridLines(false);
1107             list.back().setChartSVGridLines(false);
1108             list.back().setChartType(eMyMoney::Report::ChartType::Pie);
1109             list.back().setInvestmentsOnly(true);
1110 
1111             list.push_back(MyMoneyReport(
1112                                eMyMoney::Report::RowType::AssetLiability,
1113                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1114                                TransactionFilter::Date::Last12Months,
1115                                eMyMoney::Report::DetailLevel::All,
1116                                i18n("Investment Worth Graph"),
1117                                i18n("Default Report")
1118                            ));
1119             list.back().setChartByDefault(true);
1120             list.back().setChartCHGridLines(false);
1121             list.back().setChartSVGridLines(false);
1122             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1123             list.back().setColumnsAreDays(true);
1124             list.back().setInvestmentsOnly(true);
1125 
1126             list.push_back(MyMoneyReport(
1127                                eMyMoney::Report::RowType::AssetLiability,
1128                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1129                                TransactionFilter::Date::Last12Months,
1130                                eMyMoney::Report::DetailLevel::All,
1131                                i18n("Investment Price Graph"),
1132                                i18n("Default Report")
1133                            ));
1134             list.back().setChartByDefault(true);
1135             list.back().setChartCHGridLines(false);
1136             list.back().setChartSVGridLines(false);
1137             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1138             list.back().setColumnsAreDays(true);
1139             list.back().setInvestmentsOnly(true);
1140             list.back().setIncludingBudgetActuals(false);
1141             list.back().setIncludingPrice(true);
1142             list.back().setConvertCurrency(true);
1143             list.back().setChartDataLabels(false);
1144             list.back().setSkipZero(true);
1145             list.back().setShowingColumnTotals(false);
1146             list.back().setShowingRowTotals(false);
1147 
1148             list.push_back(MyMoneyReport(
1149                                eMyMoney::Report::RowType::AssetLiability,
1150                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1151                                TransactionFilter::Date::Last12Months,
1152                                eMyMoney::Report::DetailLevel::All,
1153                                i18n("Investment Moving Average Price Graph"),
1154                                i18n("Default Report")
1155                            ));
1156             list.back().setChartByDefault(true);
1157             list.back().setChartCHGridLines(false);
1158             list.back().setChartSVGridLines(false);
1159             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1160             list.back().setColumnsAreDays(true);
1161             list.back().setInvestmentsOnly(true);
1162             list.back().setIncludingBudgetActuals(false);
1163             list.back().setIncludingAveragePrice(true);
1164             list.back().setMovingAverageDays(10);
1165             list.back().setConvertCurrency(true);
1166             list.back().setChartDataLabels(false);
1167             list.back().setShowingColumnTotals(false);
1168             list.back().setShowingRowTotals(false);
1169 
1170             list.push_back(MyMoneyReport(
1171                                eMyMoney::Report::RowType::AssetLiability,
1172                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1173                                TransactionFilter::Date::Last30Days,
1174                                eMyMoney::Report::DetailLevel::All,
1175                                i18n("Investment Moving Average"),
1176                                i18n("Default Report")
1177                            ));
1178             list.back().setChartCHGridLines(false);
1179             list.back().setChartSVGridLines(false);
1180             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1181             list.back().setColumnsAreDays(true);
1182             list.back().setInvestmentsOnly(true);
1183             list.back().setIncludingBudgetActuals(false);
1184             list.back().setIncludingMovingAverage(true);
1185             list.back().setMovingAverageDays(10);
1186 
1187             list.push_back(MyMoneyReport(
1188                                eMyMoney::Report::RowType::AssetLiability,
1189                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1190                                TransactionFilter::Date::Last30Days,
1191                                eMyMoney::Report::DetailLevel::All,
1192                                i18n("Investment Moving Average vs Actual"),
1193                                i18n("Default Report")
1194                            ));
1195             list.back().setChartByDefault(true);
1196             list.back().setChartCHGridLines(false);
1197             list.back().setChartSVGridLines(false);
1198             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1199             list.back().setColumnsAreDays(true);
1200             list.back().setInvestmentsOnly(true);
1201             list.back().setIncludingBudgetActuals(true);
1202             list.back().setIncludingMovingAverage(true);
1203             list.back().setMovingAverageDays(10);
1204             groups.push_back(list);
1205         }
1206         {
1207             ReportGroup list("Taxes", i18n("Taxes"));
1208 
1209             list.push_back(MyMoneyReport(
1210                                eMyMoney::Report::RowType::Category,
1211                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Account,
1212                                TransactionFilter::Date::YearToDate,
1213                                eMyMoney::Report::DetailLevel::All,
1214                                i18n("Tax Transactions by Category"),
1215                                i18n("Default Report")
1216                            ));
1217             list.back().setTax(true);
1218             list.push_back(MyMoneyReport(
1219                                eMyMoney::Report::RowType::Payee,
1220                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Account,
1221                                TransactionFilter::Date::YearToDate,
1222                                eMyMoney::Report::DetailLevel::All,
1223                                i18n("Tax Transactions by Payee"),
1224                                i18n("Default Report")
1225                            ));
1226             list.back().setTax(true);
1227             list.push_back(MyMoneyReport(
1228                                eMyMoney::Report::RowType::Category,
1229                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Payee | eMyMoney::Report::QueryColumn::Account,
1230                                TransactionFilter::Date::LastFiscalYear,
1231                                eMyMoney::Report::DetailLevel::All,
1232                                i18n("Tax Transactions by Category Last Fiscal Year"),
1233                                i18n("Default Report")
1234                            ));
1235             list.back().setTax(true);
1236             list.push_back(MyMoneyReport(
1237                                eMyMoney::Report::RowType::Payee,
1238                                eMyMoney::Report::QueryColumn::Number | eMyMoney::Report::QueryColumn::Category | eMyMoney::Report::QueryColumn::Account,
1239                                TransactionFilter::Date::LastFiscalYear,
1240                                eMyMoney::Report::DetailLevel::All,
1241                                i18n("Tax Transactions by Payee Last Fiscal Year"),
1242                                i18n("Default Report")
1243                            ));
1244             list.back().setTax(true);
1245             groups.push_back(list);
1246         }
1247         {
1248             ReportGroup list("Budgeting", i18n("Budgeting"));
1249 
1250             list.push_back(MyMoneyReport(
1251                                eMyMoney::Report::RowType::BudgetActual,
1252                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1253                                TransactionFilter::Date::YearToDate,
1254                                eMyMoney::Report::DetailLevel::All,
1255                                i18n("Budgeted vs. Actual This Year"),
1256                                i18n("Default Report")
1257                            ));
1258             list.back().setShowingRowTotals(true);
1259             list.back().setBudget("Any", true);
1260 
1261             list.push_back(MyMoneyReport(
1262                                eMyMoney::Report::RowType::BudgetActual,
1263                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1264                                TransactionFilter::Date::YearToMonth,
1265                                eMyMoney::Report::DetailLevel::All,
1266                                i18n("Budgeted vs. Actual This Year (YTM)"),
1267                                i18n("Default Report")
1268                            ));
1269             list.back().setShowingRowTotals(true);
1270             list.back().setBudget("Any", true);
1271             // in case we're in January, we show the last year
1272             if (QDate::currentDate().month() == 1) {
1273                 list.back().setDateFilter(TransactionFilter::Date::LastYear);
1274             }
1275 
1276             list.push_back(MyMoneyReport(
1277                                eMyMoney::Report::RowType::BudgetActual,
1278                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1279                                TransactionFilter::Date::CurrentMonth,
1280                                eMyMoney::Report::DetailLevel::All,
1281                                i18n("Monthly Budgeted vs. Actual"),
1282                                i18n("Default Report")
1283                            ));
1284             list.back().setBudget("Any", true);
1285 
1286             list.push_back(MyMoneyReport(eMyMoney::Report::RowType::BudgetActual,
1287                                          static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1288                                          TransactionFilter::Date::CurrentFiscalYear,
1289                                          eMyMoney::Report::DetailLevel::All,
1290                                          i18n("Yearly Budgeted vs. Actual"),
1291                                          i18n("Default Report")));
1292             list.back().setBudget("Any", true);
1293             list.back().setShowingRowTotals(true);
1294 
1295             list.push_back(MyMoneyReport(
1296                                eMyMoney::Report::RowType::Budget,
1297                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1298                                TransactionFilter::Date::CurrentMonth,
1299                                eMyMoney::Report::DetailLevel::All,
1300                                i18n("Monthly Budget"),
1301                                i18n("Default Report")
1302                            ));
1303             list.back().setBudget("Any", false);
1304 
1305             list.push_back(MyMoneyReport(eMyMoney::Report::RowType::Budget,
1306                                          static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1307                                          TransactionFilter::Date::CurrentFiscalYear,
1308                                          eMyMoney::Report::DetailLevel::All,
1309                                          i18n("Yearly Budget"),
1310                                          i18n("Default Report")));
1311             list.back().setBudget("Any", false);
1312             list.back().setShowingRowTotals(true);
1313             list.push_back(MyMoneyReport(eMyMoney::Report::RowType::BudgetActual,
1314                                          static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1315                                          TransactionFilter::Date::CurrentFiscalYear,
1316                                          eMyMoney::Report::DetailLevel::Group,
1317                                          i18n("Yearly Budgeted vs Actual Graph"),
1318                                          i18n("Default Report")));
1319             list.back().setChartByDefault(true);
1320             list.back().setChartCHGridLines(false);
1321             list.back().setChartSVGridLines(false);
1322             list.back().setBudget("Any", true);
1323             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1324 
1325             groups.push_back(list);
1326         }
1327         {
1328             ReportGroup list("Forecast", i18n("Forecast"));
1329 
1330             list.push_back(MyMoneyReport(
1331                                eMyMoney::Report::RowType::AssetLiability,
1332                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1333                                TransactionFilter::Date::Next12Months,
1334                                eMyMoney::Report::DetailLevel::Top,
1335                                i18n("Forecast By Month"),
1336                                i18n("Default Report")
1337                            ));
1338             list.back().setIncludingForecast(true);
1339 
1340             list.push_back(MyMoneyReport(
1341                                eMyMoney::Report::RowType::AssetLiability,
1342                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1343                                TransactionFilter::Date::NextQuarter,
1344                                eMyMoney::Report::DetailLevel::Top,
1345                                i18n("Forecast Next Quarter"),
1346                                i18n("Default Report")
1347                            ));
1348             list.back().setColumnsAreDays(true);
1349             list.back().setIncludingForecast(true);
1350 
1351             list.push_back(MyMoneyReport(
1352                                eMyMoney::Report::RowType::ExpenseIncome,
1353                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1354                                TransactionFilter::Date::CurrentYear,
1355                                eMyMoney::Report::DetailLevel::Top,
1356                                i18n("Income and Expenses Forecast This Year"),
1357                                i18n("Default Report")
1358                            ));
1359             list.back().setIncludingForecast(true);
1360 
1361             list.push_back(MyMoneyReport(
1362                                eMyMoney::Report::RowType::AssetLiability,
1363                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1364                                TransactionFilter::Date::Next3Months,
1365                                eMyMoney::Report::DetailLevel::Total,
1366                                i18n("Net Worth Forecast Graph"),
1367                                i18n("Default Report")
1368                            ));
1369             list.back().setColumnsAreDays(true);
1370             list.back().setIncludingForecast(true);
1371             list.back().setChartByDefault(true);
1372             list.back().setChartCHGridLines(false);
1373             list.back().setChartSVGridLines(false);
1374             list.back().setChartType(eMyMoney::Report::ChartType::Line);
1375             groups.push_back(list);
1376         }
1377         {
1378             ReportGroup list("Information", i18n("General Information"));
1379 
1380             list.push_back(MyMoneyReport(
1381                                eMyMoney::Report::RowType::Schedule,
1382                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1383                                TransactionFilter::Date::Next12Months,
1384                                eMyMoney::Report::DetailLevel::All,
1385                                i18n("Schedule Information"),
1386                                i18n("Default Report")
1387                            ));
1388             list.back().setDetailLevel(eMyMoney::Report::DetailLevel::All);
1389             list.push_back(MyMoneyReport(
1390                                eMyMoney::Report::RowType::Schedule,
1391                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1392                                TransactionFilter::Date::Next12Months,
1393                                eMyMoney::Report::DetailLevel::All,
1394                                i18n("Schedule Summary Information"),
1395                                i18n("Default Report")
1396                            ));
1397             list.back().setDetailLevel(eMyMoney::Report::DetailLevel::Top);
1398             list.push_back(MyMoneyReport(
1399                                eMyMoney::Report::RowType::AccountInfo,
1400                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1401                                TransactionFilter::Date::Today,
1402                                eMyMoney::Report::DetailLevel::All,
1403                                i18n("Account Information"),
1404                                i18n("Default Report")
1405                            ));
1406             list.back().setConvertCurrency(false);
1407             list.push_back(MyMoneyReport(
1408                                eMyMoney::Report::RowType::AccountLoanInfo,
1409                                static_cast<unsigned>(eMyMoney::Report::ColumnType::Months),
1410                                TransactionFilter::Date::Today,
1411                                eMyMoney::Report::DetailLevel::All,
1412                                i18n("Loan Information"),
1413                                i18n("Default Report")
1414                            ));
1415             list.back().setConvertCurrency(false);
1416             groups.push_back(list);
1417         }
1418     }
1419 
1420     bool columnsAlreadyAdjusted() const
1421     {
1422         return m_columnsAlreadyAdjusted;
1423     }
1424 
1425     void setColumnsAlreadyAdjusted(bool adjusted)
1426     {
1427         m_columnsAlreadyAdjusted = adjusted;
1428     }
1429 
1430     void setFilter(const QString& text)
1431     {
1432         const auto columns = ui.m_tocTreeWidget->columnCount();
1433         for (auto i = 0; i < ui.m_tocTreeWidget->topLevelItemCount(); ++i) {
1434             const auto toplevelItem = ui.m_tocTreeWidget->topLevelItem(i);
1435             bool hideTopLevel = true;
1436             for (auto j = 0; j < toplevelItem->childCount(); ++j) {
1437                 const auto reportItem = toplevelItem->child(j);
1438                 if (text.isEmpty()) {
1439                     reportItem->setHidden(false);
1440                     hideTopLevel = false;
1441                 } else {
1442                     reportItem->setHidden(true);
1443                     for (auto column = 0; column < columns; ++column) {
1444                         if (reportItem->text(column).contains(text, Qt::CaseInsensitive)) {
1445                             reportItem->setHidden(false);
1446                             hideTopLevel = false;
1447                             break;
1448                         }
1449                     }
1450                 }
1451             }
1452             toplevelItem->setHidden(hideTopLevel);
1453         }
1454 
1455         if (text.isEmpty()) {
1456             if (!expandStatesBeforeSearch.isEmpty()) {
1457                 restoreTocExpandState(expandStatesBeforeSearch);
1458                 expandStatesBeforeSearch.clear();
1459             }
1460         } else {
1461             if (expandStatesBeforeSearch.isEmpty()) {
1462                 expandStatesBeforeSearch = saveTocExpandState();
1463             }
1464             // show groups with matching reports as expanded
1465             for (auto i = 0; i < ui.m_tocTreeWidget->topLevelItemCount(); ++i) {
1466                 const auto toplevelItem = ui.m_tocTreeWidget->topLevelItem(i);
1467                 toplevelItem->setExpanded(!toplevelItem->isHidden());
1468             }
1469         }
1470     }
1471 
1472     /**
1473       * This member holds the load state of page
1474       */
1475     bool m_needLoad;
1476 
1477     Ui::KReportsView ui;
1478     QListWidget* m_reportListView;
1479     QMap<QString, TocItemGroup*> m_allTocItemGroups;
1480     QString m_selectedExportFilter;
1481 
1482     bool m_columnsAlreadyAdjusted;
1483     MyMoneyAccount m_currentAccount;
1484     QMap<QString, bool> expandStatesBeforeSearch;
1485 };
1486 
1487 #endif