diff --git a/kmymoney/settings/kmymoney.kcfg b/kmymoney/settings/kmymoney.kcfg index 060c2ce9d..f5a75bfc0 100644 --- a/kmymoney/settings/kmymoney.kcfg +++ b/kmymoney/settings/kmymoney.kcfg @@ -1,462 +1,468 @@ false 1 10 true true false false 0 0 20 10 0 60 false false 0 0 999 (None) 0 0 999 false false false false 4 4 10 true true 0 0 false false false true true 0 true true false account,cashflow,payee,category,tag,memo,number,date,amount,state number,date,payee,category,tag,memo,payment,deposit,state 8,1,2,3,4,5,6,7,-9,10 100 true true false false false false false false false false false false false true true true 0 0 11 1 1 28 QDateTime::fromString("1900-01-01T00:00:00", Qt::ISODate) true 240,240,240 255,255,255 154,154,154 255,255,0 152,251,152 255,0,0 0,0,255 255,0,0 255,242,155 255,255,221 false 1,-9,-4 1,-4 1,-9,-4 Day 0 4 false 0 90 1 999 30 1 999 3 1 999 0 0 31 1 true true true Bar Banca,Banque Kreditkarte And. Kto. Eröffnungssaldo Rechnung false 10 0 100 2 0 256 2 0 2 + + + + false + + diff --git a/kmymoney/views/CMakeLists.txt b/kmymoney/views/CMakeLists.txt index df9074b2a..62bba7395 100644 --- a/kmymoney/views/CMakeLists.txt +++ b/kmymoney/views/CMakeLists.txt @@ -1,65 +1,66 @@ include_directories( ${KMyMoney_SOURCE_DIR}/libkdchart/include) ############# next target (views) STATIC ################### set(libviews_a_SOURCES kaccountsview.cpp kbudgetview.cpp kcategoriesview.cpp kforecastview.cpp kgloballedgerview.cpp kwelcomepage.cpp khomeview.cpp kinstitutionsview.cpp kinvestmentview.cpp kmymoneyfile.cpp kmymoneyview.cpp kpayeesview.cpp kreportsview.cpp kscheduledview.cpp tocitem.cpp tocitemgroup.cpp tocitemreport.cpp kscheduletreeitem.cpp ktagsview.cpp konlinejoboutbox.cpp kpayeeidentifierview.cpp payeeidentifierselectiondelegate.cpp ) set(libviews_a_HEADER kmymoneyview.h) set(libviews_a_UI kaccountsviewdecl.ui kbudgetviewdecl.ui kcategoriesviewdecl.ui kforecastviewdecl.ui kinstitutionsviewdecl.ui kinvestmentviewdecl.ui kpayeesviewdecl.ui + kreportsviewdecl.ui kscheduledviewdecl.ui ktagsviewdecl.ui konlinejoboutbox.ui kpayeeidentifierview.ui ) # The handling of these ui files depends # on libkmymoney.so (the widgets library) kde4_add_ui_files(libviews_a_SOURCES ${libviews_a_UI}) kde4_add_library(views STATIC ${libviews_a_SOURCES}) # TODO: Remove this dependency. But it is needed as long as the payee editor uses these objects directly # This should be replaced by virtual methods in a pure abstract object. target_link_libraries( views payeeidentifier_iban_bic payeeidentifier_nationalAccount kmm_mymoney # needed to load payeeIdentifier ) # we rely on some of the dialogs to be generated add_dependencies(views dialogs newinvestmentwizard newloanwizard endingbalancedlg) ########### install files ############### install(FILES ${libviews_a_HEADER} DESTINATION ${INCLUDE_INSTALL_DIR}/kmymoney COMPONENT Devel) diff --git a/kmymoney/views/kreportsview.cpp b/kmymoney/views/kreportsview.cpp index c1ba6dc68..769a34a83 100644 --- a/kmymoney/views/kreportsview.cpp +++ b/kmymoney/views/kreportsview.cpp @@ -1,1873 +1,1899 @@ /*************************************************************************** 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 #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include "kmymoney.h" #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 */ class KReportsView::KReportTab::Private : public QObject { Q_OBJECT public: KReportsView::KReportTab *q; Private(KReportsView::KReportTab *parent) : q(parent) {} public slots: void slotPaintRequested(QPrinter *printer); }; void KReportsView::KReportTab::Private::slotPaintRequested(QPrinter *printer) { if (!q->m_chartView->isHidden()) { QPainter painter(printer); int h = painter.fontMetrics().height(); q->m_chartView->paint(&painter, QRect(0, 0, printer->pageRect().width(), printer->pageRect().height() - h)); QFont font = painter.font(); font.setPointSizeF(font.pointSizeF() * 0.8); painter.setFont(font); painter.drawText(0, h, KGlobal::locale()->formatDate(QDate::currentDate(), KLocale::ShortDate)); QUrl file(kmymoney->filename()); painter.drawText(0, printer->pageRect().height(), file.toLocalFile()); } else if (q->m_part && q->m_part->view()) #if KDE_IS_VERSION(4, 14, 65) q->m_part->view()->print(kmymoney->printer(), true); #else q->m_part->view()->print(); #endif } 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), d(new Private(this)) { 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; delete d; } void KReportsView::KReportTab::print() { #if KDE_IS_VERSION(4, 14, 65) QPrintDialog dlg(kmymoney->printer(), this); if (!dlg.exec()) return; #endif d->slotPaintRequested(kmymoney->printer()); } void KReportsView::KReportTab::printPreview() { QPrintPreviewDialog dlg(kmymoney->printer(), this); connect(&dlg, SIGNAL(paintRequested(QPrinter*)), d, SLOT(slotPaintRequested(QPrinter*))); dlg.exec(); } 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::Report::PivotTable) { m_table = new PivotTable(m_report); m_chartEnabled = true; } else if (m_report.reportType() == MyMoneyReport::Report::QueryTable) { m_table = new QueryTable(m_report); m_chartEnabled = false; } 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")), + QWidget(parent), d(new Private), m_needReload(false) { + setupUi(this); // build reports toc setColumnsAlreadyAdjusted(false); - m_reportTabWidget = new KTabWidget(this); - addWidget(m_reportTabWidget); m_reportTabWidget->setTabsClosable(true); + // setup icons for collapse and expand button + KGuiItem collapseGuiItem("", + KIcon("zoom-out"), + QString(), + QString()); + KGuiItem expandGuiItem("", + KIcon("zoom-in"), + QString(), + QString()); + m_collapseButton->setGuiItem(collapseGuiItem); + m_expandButton->setGuiItem(expandGuiItem); + connect(m_collapseButton, SIGNAL(clicked()), this, SLOT(slotExpandCollapse())); + connect(m_expandButton, SIGNAL(clicked()), this, SLOT(slotExpandCollapse())); + 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(4); // headers QStringList headers; headers << i18n("Reports") << i18n("Comment") << i18n("Start date") << i18n("End date"); 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::ExtendedSelection); 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(); + if (KMyMoneyGlobalSettings::showReportsExpanded()) { + m_tocTreeWidget->expandAll(); + } 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); + QWidget::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); } // // 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::slotPrintPreviewView() { KReportTab* tab = dynamic_cast(m_reportTabWidget->currentWidget()); if (tab) tab->printPreview(); } 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) { QList items = m_tocTreeWidget->selectedItems(); if (items.isEmpty()) return; QList tocItems; foreach(QTreeWidgetItem *item, items) { TocItem* tocItem = dynamic_cast(item); if (!tocItem || !tocItem->isReport()) continue; tocItems.append(tocItem); } if (tocItems.isEmpty()) return; KMenu* contextmenu = new KMenu(this); contextmenu->addAction(i18nc("To open a report", "&Open"), this, SLOT(slotOpenFromList())); contextmenu->addAction(i18nc("To print a report", "&Print"), this, SLOT(slotPrintFromList())); if (tocItems.size() == 1) { TocItem* tocItem = dynamic_cast(tocItems.at(0)); 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() { QList items = m_tocTreeWidget->selectedItems(); if (items.isEmpty()) return; foreach(QTreeWidgetItem *item, items) { TocItem* tocItem = dynamic_cast(item); if (tocItem && tocItem->isReport()) slotItemDoubleClicked(tocItem, 0); } } void KReportsView::slotPrintFromList() { QList items = m_tocTreeWidget->selectedItems(); if (items.isEmpty()) return; foreach(QTreeWidgetItem *item, items) { TocItem* tocItem = dynamic_cast(item); if (tocItem && tocItem->isReport()) { slotItemDoubleClicked(tocItem, 0); slotPrintView(); } } } 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::Row::ExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::DetailLevel::All, i18n("Income and Expenses This Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Income and Expenses This Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Column::Years, MyMoneyTransactionFilter::allDates, MyMoneyReport::DetailLevel::All, i18n("Income and Expenses By Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::DetailLevel::Top, i18n("Income and Expenses Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartType(MyMoneyReport::Chart::Line); list.back().setChartDataLabels(false); list.push_back(MyMoneyReport( MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::Group, i18n("Income and Expenses Pie Chart"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartType(MyMoneyReport::Chart::Pie); list.back().setShowingRowTotals(false); groups.push_back(list); } { ReportGroup list("Net Worth", i18n("Net Worth")); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::Top, i18n("Net Worth By Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::DetailLevel::Top, i18n("Net Worth Today"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Years, MyMoneyTransactionFilter::allDates, MyMoneyReport::DetailLevel::Top, i18n("Net Worth By Year"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next7Days, MyMoneyReport::DetailLevel::Top, i18n("7-day Cash Flow Forecast"), i18n("Default Report") )); list.back().setIncludingSchedules(true); list.back().setColumnsAreDays(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::DetailLevel::Total, i18n("Net Worth Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); list.push_back(MyMoneyReport( MyMoneyReport::Row::Institution, MyMoneyReport::QueryColumns::None, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::Top, i18n("Account Balances by Institution"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountType, MyMoneyReport::QueryColumns::None, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::Top, i18n("Account Balances by Type"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("Transactions", i18n("Transactions")); list.push_back(MyMoneyReport( MyMoneyReport::Row::Account, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag | MyMoneyReport::QueryColumns::Balance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Account"), i18n("Default Report") )); //list.back().setConvertCurrency(false); list.push_back(MyMoneyReport( MyMoneyReport::Row::Category, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Category"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::Payee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Payee"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::Tag, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Tag"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::Month, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Month"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::Week, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Tag, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Transactions by Week"), i18n("Default Report") )); list.push_back(MyMoneyReport( MyMoneyReport::Row::Account, MyMoneyReport::QueryColumns::Loan, MyMoneyTransactionFilter::allDates, MyMoneyReport::DetailLevel::All, i18n("Loan Transactions"), i18n("Default Report") )); list.back().setLoansOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountReconcile, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Balance, MyMoneyTransactionFilter::last3Months, MyMoneyReport::DetailLevel::All, i18n("Transactions by Reconciliation Status"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("CashFlow", i18n("Cash Flow")); list.push_back(MyMoneyReport( MyMoneyReport::Row::CashFlow, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Cash Flow Transactions This Month"), i18n("Default Report") )); groups.push_back(list); } { ReportGroup list("Investments", i18n("Investments")); list.push_back(MyMoneyReport( MyMoneyReport::Row::TopAccount, MyMoneyReport::QueryColumns::Action | MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Investment Transactions"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountByTopAccount, MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Investment Holdings by Account"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::EquityType, MyMoneyReport::QueryColumns::Shares | MyMoneyReport::QueryColumns::Price, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Investment Holdings by Type"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountByTopAccount, MyMoneyReport::QueryColumns::Performance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Investment Performance by Account"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::EquityType, MyMoneyReport::QueryColumns::Performance, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Investment Performance by Type"), i18n("Default Report") )); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::DetailLevel::All, i18n("Investment Holdings Pie"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Pie); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::DetailLevel::All, i18n("Investment Worth Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); list.back().setColumnsAreDays(true); list.back().setInvestmentsOnly(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::DetailLevel::All, i18n("Investment Price Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); 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::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last12Months, MyMoneyReport::DetailLevel::All, i18n("Investment Moving Average Price Graph"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); 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::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last30Days, MyMoneyReport::DetailLevel::All, i18n("Investment Moving Average"), i18n("Default Report") )); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); 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::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::last30Days, MyMoneyReport::DetailLevel::All, i18n("Investment Moving Average vs Actual"), i18n("Default Report") )); list.back().setChartByDefault(true); list.back().setChartGridLines(false); list.back().setChartType(MyMoneyReport::Chart::Line); 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::Row::Category, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Tax Transactions by Category"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::Payee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Tax Transactions by Payee"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::Category, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Payee | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::lastFiscalYear, MyMoneyReport::DetailLevel::All, i18n("Tax Transactions by Category Last Fiscal Year"), i18n("Default Report") )); list.back().setTax(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::Payee, MyMoneyReport::QueryColumns::Number | MyMoneyReport::QueryColumns::Category | MyMoneyReport::QueryColumns::Account, MyMoneyTransactionFilter::lastFiscalYear, MyMoneyReport::DetailLevel::All, 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::Row::BudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToDate, MyMoneyReport::DetailLevel::All, i18n("Budgeted vs. Actual This Year"), i18n("Default Report") )); list.back().setShowingRowTotals(true); list.back().setBudget("Any", true); list.push_back(MyMoneyReport( MyMoneyReport::Row::BudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::yearToMonth, MyMoneyReport::DetailLevel::All, 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::Row::BudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::DetailLevel::All, i18n("Monthly Budgeted vs. Actual"), i18n("Default Report") )); list.back().setBudget("Any", true); list.push_back(MyMoneyReport( MyMoneyReport::Row::BudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::DetailLevel::All, i18n("Yearly Budgeted vs. Actual"), i18n("Default Report") )); list.back().setBudget("Any", true); list.back().setShowingRowTotals(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::Budget, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentMonth, MyMoneyReport::DetailLevel::All, i18n("Monthly Budget"), i18n("Default Report") )); list.back().setBudget("Any", false); list.push_back(MyMoneyReport( MyMoneyReport::Row::Budget, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::DetailLevel::All, i18n("Yearly Budget"), i18n("Default Report") )); list.back().setBudget("Any", false); list.back().setShowingRowTotals(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::BudgetActual, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::DetailLevel::Group, 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::Chart::Line); groups.push_back(list); } { ReportGroup list("Forecast", i18n("Forecast")); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::DetailLevel::Top, i18n("Forecast By Month"), i18n("Default Report") )); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::nextQuarter, MyMoneyReport::DetailLevel::Top, i18n("Forecast Next Quarter"), i18n("Default Report") )); list.back().setColumnsAreDays(true); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::ExpenseIncome, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::currentYear, MyMoneyReport::DetailLevel::Top, i18n("Income and Expenses Forecast This Year"), i18n("Default Report") )); list.back().setIncludingForecast(true); list.push_back(MyMoneyReport( MyMoneyReport::Row::AssetLiability, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next3Months, MyMoneyReport::DetailLevel::Total, 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::Chart::Line); groups.push_back(list); } { ReportGroup list("Information", i18n("General Information")); list.push_back(MyMoneyReport( MyMoneyReport::Row::Schedule, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::DetailLevel::All, i18n("Schedule Information"), i18n("Default Report") )); list.back().setDetailLevel(MyMoneyReport::DetailLevel::All); list.push_back(MyMoneyReport( MyMoneyReport::Row::Schedule, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::next12Months, MyMoneyReport::DetailLevel::All, i18n("Schedule Summary Information"), i18n("Default Report") )); list.back().setDetailLevel(MyMoneyReport::DetailLevel::Top); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountInfo, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::DetailLevel::All, i18n("Account Information"), i18n("Default Report") )); list.back().setConvertCurrency(false); list.push_back(MyMoneyReport( MyMoneyReport::Row::AccountLoanInfo, MyMoneyReport::Column::Months, MyMoneyTransactionFilter::today, MyMoneyReport::DetailLevel::All, 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); } } } } +void KReportsView::slotExpandCollapse() +{ + if (sender() == m_expandButton) { + KMyMoneyGlobalSettings::setShowReportsExpanded(true); + m_tocTreeWidget->expandAll(); + } else { + KMyMoneyGlobalSettings::setShowReportsExpanded(false); + m_tocTreeWidget->collapseAll(); + } +} + // 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 #include "kreportsview.moc" diff --git a/kmymoney/views/kreportsview.h b/kmymoney/views/kreportsview.h index c0d9dd29a..d74a3d63f 100644 --- a/kmymoney/views/kreportsview.h +++ b/kmymoney/views/kreportsview.h @@ -1,261 +1,268 @@ /*************************************************************************** kreportsview.h - 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. * * * ***************************************************************************/ #ifndef KREPORTSVIEW_H #define KREPORTSVIEW_H // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include #include #include // ---------------------------------------------------------------------------- // Project Includes #ifdef _CHECK_MEMORY #include #endif #include "mymoneyschedule.h" #include #include #include "pivottable.h" #include "querytable.h" #include "../widgets/kmymoneyreportcontrolimpl.h" #include "kreportchartview.h" #include "kmymoneyview.h" #include "tocitem.h" #include "tocitemgroup.h" #include "tocitemreport.h" +#include "ui_kreportsviewdecl.h" + class MyMoneyReport; /** * Displays a page where reports can be placed. * * @author Ace Jones * * @short A view for reports. **/ -class KReportsView : public KMyMoneyViewBase +class KReportsView : public QWidget, Ui::KReportsViewDecl { Q_OBJECT public: /** * Helper class for KReportView. * * This is the widget which displays a single report in the TabWidget that comprises this view. * * @author Ace Jones */ class KReportTab: public QWidget { private: KHTMLPart* m_part; reports::KReportChartView* m_chartView; kMyMoneyReportControl* m_control; QVBoxLayout* m_layout; MyMoneyReport m_report; bool m_deleteMe; bool m_chartEnabled; bool m_showingChart; bool m_needReload; reports::ReportTable* m_table; class Private; Private* const d; /** * Users character set encoding. */ QByteArray m_encoding; public: KReportTab(KTabWidget* parent, const MyMoneyReport& report); ~KReportTab(); const MyMoneyReport& report() const { return m_report; } void print(); void printPreview(); void toggleChart(); void copyToClipboard(); void saveAs(const QString& filename, bool includeCSS = false); void updateReport(); QString createTable(const QString& links = QString()); const kMyMoneyReportControlDecl* control() const { return m_control; } bool isReadyToDelete() const { return m_deleteMe; } void setReadyToDelete(bool f) { m_deleteMe = f; } void modifyReport(const MyMoneyReport& report) { m_report = report; } void showEvent(QShowEvent * event); void loadTab(); KParts::BrowserExtension* browserExtenstion() const { return m_part->browserExtension(); } }; /** * Helper class for KReportView. * * This is a named list of reports, which will be one section * in the list of default reports * * @author Ace Jones */ class ReportGroup: public QList { private: QString m_name; ///< the title of the group in non-translated form QString m_title; ///< the title of the group in i18n-ed form public: ReportGroup() {} ReportGroup(const QString& name, const QString& title): m_name(name), m_title(title) {} const QString& name() const { return m_name; } const QString& title() const { return m_title; } }; private: /// \internal d-pointer class. class Private; /// \internal d-pointer instance. Private* const d; bool m_needReload; - KTabWidget* m_reportTabWidget; QWidget* m_listTab; QVBoxLayout* m_listTabLayout; QTreeWidget* m_tocTreeWidget; QMap m_allTocItemGroups; bool m_columnsAlreadyAdjusted; void restoreTocExpandState(QMap& expandStates); public: /** * Standard constructor. * * @param parent The QWidget this is used in. * @param name The QT name. * * @return An object of type KReportsView * * @see ~KReportsView */ explicit KReportsView(QWidget *parent = 0, const char *name = 0); /** * Standard destructor. * * @return Nothing. * * @see KReportsView */ ~KReportsView(); /** * Overridden so we can reload the view if necessary. * * @return Nothing. */ void showEvent(QShowEvent * event); protected: void addReportTab(const MyMoneyReport&); void loadView(); static void defaultReports(QList&); bool columnsAlreadyAdjusted(); void setColumnsAlreadyAdjusted(bool adjusted); public slots: void slotOpenUrl(const KUrl &url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& browArgs); void slotLoadView(); void slotPrintView(); void slotPrintPreviewView(); void slotCopyView(); void slotSaveView(); void slotConfigure(); void slotDuplicate(); void slotToggleChart(); void slotItemDoubleClicked(QTreeWidgetItem* item, int); void slotOpenReport(const QString&); void slotOpenReport(const MyMoneyReport&); void slotCloseCurrent(); void slotClose(int index); void slotCloseAll(); void slotDelete(); void slotListContextMenu(const QPoint &); void slotOpenFromList(); void slotPrintFromList(); void slotConfigureFromList(); void slotNewFromList(); void slotDeleteFromList(); protected slots: void slotSaveFilterChanged(const QString&); + void slotExpandCollapse(); signals: /** * This signal is emitted whenever a report is selected */ void reportSelected(const MyMoneyReport&); /** * This signal is emitted whenever a transaction is selected */ void ledgerSelected(const QString&, const QString&); + /** + * This signal is emitted whenever the view is about to be shown. + */ + void aboutToShow(); + private: /** * Display a dialog to confirm report deletion */ int deleteReportDialog(const QString&); }; #endif diff --git a/kmymoney/views/kreportsviewdecl.ui b/kmymoney/views/kreportsviewdecl.ui new file mode 100644 index 000000000..f34822386 --- /dev/null +++ b/kmymoney/views/kreportsviewdecl.ui @@ -0,0 +1,93 @@ + + + KReportsViewDecl + + + + 0 + 0 + 244 + 164 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + Collapse all accounts in the list + + + + + + + + + + Expand all accounts in the list + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+ + KPushButton + QPushButton +
kpushbutton.h
+
+ + KTabWidget + QTabWidget +
ktabwidget.h
+ 1 +
+
+ + +