diff options
Diffstat (limited to 'kplato/kptaccountsview.cpp')
-rw-r--r-- | kplato/kptaccountsview.cpp | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/kplato/kptaccountsview.cpp b/kplato/kptaccountsview.cpp new file mode 100644 index 00000000..3352a87d --- /dev/null +++ b/kplato/kptaccountsview.cpp @@ -0,0 +1,451 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Dag Andersen [email protected]> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; + version 2 of the License. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kptaccountsview.h" + +#include "kptaccountsviewconfigdialog.h" +#include "kptcontext.h" +#include "kptdatetime.h" +#include "kptproject.h" +#include "kptview.h" +#include "kpteffortcostmap.h" + +#include <tqapplication.h> +#include <tqcombobox.h> +#include <tqdatetime.h> +#include <tqdatetimeedit.h> +#include <tqheader.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqpalette.h> +#include <tqpushbutton.h> +#include <tqvaluelist.h> +#include <tqpopupmenu.h> +#include <tqsizepolicy.h> +#include <tqhbox.h> +#include <tqpaintdevicemetrics.h> + +#include <kcalendarsystem.h> +#include <tdeglobal.h> +#include <tdelistview.h> +#include <tdelocale.h> +#include <kprinter.h> + +#include <kdebug.h> + +namespace KPlato +{ + +class Label : public TQLabel +{ +public: + Label(TQWidget *w) + : TQLabel(w) + {} + void paintContents(TQPainter *p) { + drawContents(p); + } +}; + +AccountsView::AccountItem::AccountItem(Account *a, TQListView *parent, bool highlight) + : DoubleListViewBase::MasterListItem(parent, a->name(), highlight), + account(a) { + if (parent->columns() >= 3) { + setText(2, a->description()); + } + //kdDebug()<<k_funcinfo<<endl; +} +AccountsView::AccountItem::AccountItem(Account *a, TQListViewItem *p, bool highlight) + : DoubleListViewBase::MasterListItem(p, a->name(), highlight), + account(a) { + if (listView() && listView()->columns() >= 3) { + setText(2, a->description()); + } + //kdDebug()<<k_funcinfo<<endl; +} + +AccountsView::AccountItem::AccountItem(TQString text, Account *a, TQListViewItem *parent, bool highlight) + : DoubleListViewBase::MasterListItem(parent, text, highlight), + account(a) { + //kdDebug()<<k_funcinfo<<endl; +} + +void AccountsView::AccountItem::add(int col, const TQDate &date, const EffortCost &ec) { + EffortCost &cm = costMap.add(date, ec); + if (m_slaveItem) + m_slaveItem->setText(col, TDEGlobal::locale()->formatMoney(cm.cost(), "", 0)); +} + +AccountsView::AccountsView(Project &project, View *view, TQWidget *parent) + : TQWidget(parent, "Accounts view"), + m_mainview(view), + m_project(project), + m_accounts(project.accounts()) { + + m_date = TQDate::currentDate(); + m_period = 0; + m_periodTexts<<i18n("Day")<<i18n("Week")<<i18n("Month"); + m_cumulative = false; + + TQVBoxLayout *lay1 = new TQVBoxLayout(this, 0, KDialog::spacingHint()); + + TQHBoxLayout *lay2 = new TQHBoxLayout(0, 0, KDialog::spacingHint()); + m_label = new Label(this); + m_label->setFrameShape(TQLabel::StyledPanel); + m_label->setFrameShadow(TQLabel::Sunken); + m_label->setAlignment(int(TQLabel::WordBreak | TQLabel::AlignVCenter)); + lay2->addWidget(m_label); + m_changeBtn = new TQPushButton(i18n("Configure..."), this); + m_changeBtn->setSizePolicy(TQSizePolicy((TQSizePolicy::SizeType)0, (TQSizePolicy::SizeType)0, 0, 0, m_changeBtn->sizePolicy().hasHeightForWidth())); + lay2->addWidget(m_changeBtn); + lay1->addLayout(lay2); + + m_dlv = new DoubleListViewBase(this, true); + m_dlv->setNameHeader(i18n("Account")); + + init(); + + lay1->addWidget(m_dlv); + + connect(this, TQT_SIGNAL(update()), TQT_SLOT(slotUpdate())); + connect(m_changeBtn, TQT_SIGNAL(clicked()), TQT_SLOT(slotConfigure())); + + TQValueList<int> list = m_dlv->sizes(); + int tot = list[0] + list[1]; + list[0] = TQMIN(35, tot); + list[1] = tot-list[0]; + m_dlv->setSizes(list); +} + +void AccountsView::zoom(double zoom) { + Q_UNUSED(zoom); +} + +void AccountsView::init() { + m_date = TQDate::currentDate(); + m_period = 0; + initAccList(m_accounts.accountList()); +} + +void AccountsView::draw() { + //kdDebug()<<k_funcinfo<<endl; + Context::Accountsview context; + getContextClosedItems(context, m_dlv->masterListView()->firstChild()); + initAccList(m_accounts.accountList()); + setContextClosedItems(context); + slotUpdate(); +} + +void AccountsView::initAccList(const AccountList &list) { + m_dlv->clearLists(); + AccountListIterator it = list; + for (it.toLast(); it.current(); --it) { + AccountsView::AccountItem *a = new AccountsView::AccountItem(it.current(), m_dlv->masterListView()); + a->setOpen(true); + a->setExpandable(!it.current()->isElement()); + initAccSubItems(it.current(), a); + } + createPeriods(); +} + +void AccountsView::initAccSubItems(Account *acc, AccountsView::AccountItem *parent) { + if (!acc->accountList().isEmpty()) { +/* AccountsView::AccountItem *a = new AccountsView::AccountItem(i18n("Subaccounts"), acc, parent); + DoubleListViewBase::SlaveListItem *i = new DoubleListViewBase::SlaveListItem(a, parent->period); + a->period = i;*/ + + initAccList(acc->accountList(), parent); + } +// AccountsView::AccountItem *a = new AccountsView::AccountItem(i18n("Variance"), acc, parent, true); +// DoubleListViewBase::SlaveListItem *i = new DoubleListViewBase::SlaveListItem(a, parent->period, true); +// a->period = i; +// +// a = new AccountsView::AccountItem(i18n("Actual"), acc, parent); +// i = new DoubleListViewBase::SlaveListItem(a, parent->period); +// a->period = i; +// +// a = new AccountsView::AccountItem(i18n("Planned"), acc, parent); +// i = new DoubleListViewBase::SlaveListItem(a, parent->period); +// a->period = i; + +} + +void AccountsView::initAccList(const AccountList &list, AccountsView::AccountItem *parent) { + AccountListIterator it = list; + for (it.toLast(); it.current(); --it) { + AccountsView::AccountItem *a = new AccountsView::AccountItem(it.current(), parent); + a->setOpen(true); + a->setExpandable(!it.current()->isElement()); + initAccSubItems(it.current(), a); + } +} + +void AccountsView::clearPeriods() { + m_dlv->clearSlaveList(); +} + +void AccountsView::createPeriods() { + m_dlv->createSlaveItems(); +} + +void AccountsView::slotUpdate() { + //kdDebug()<<k_funcinfo<<endl; + TQApplication::setOverrideCursor(TQt::waitCursor); + createPeriods(); + TDELocale *locale = TDEGlobal::locale(); + const KCalendarSystem *cal = locale->calendar(); + + TQString t; + if (m_cumulative) { + t += " <b>" + i18n("Cumulative") + "</b> "; + } + t += i18n("Cut-off date:%1").arg("<b>" + locale->formatDate(m_date, true) + "</b>"); + t += " " + i18n("Periodicity:%1").arg("<b>" + periodText(m_period) + "</b>"); + m_label->setText(t); + + // Add columns for selected period/periods + TQDate start = m_project.startTime().date(); + TQDate end = m_date; + //kdDebug()<<k_funcinfo<<start.toString()<<" - "<<end.toString()<<endl; + int c=0; + if (m_period == 0) { //Daily + for (TQDate dt = start; dt <= end; dt = cal->addDays(dt, 1), ++c) { + TQString df = locale->formatDate(dt, true); + m_dlv->addSlaveColumn(df); + } + TQListViewItemIterator it(m_dlv->masterListView()); + for (;it.current(); ++it) { + AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current()); + if (!item || !item->account || !item->account->isElement()) { + continue; + } + item->costMap = m_accounts.plannedCost(*(item->account), start, end); + double cost = 0.0; + int col=0; + for (TQDate d=start; d <= end; d = cal->addDays(d, 1), ++col) { + EffortCost &ec = item->costMap.effortCostOnDate(d); + cost = (m_cumulative ? cost + ec.cost() : ec.cost()); + item->setSlaveItem(col, cost); + m_cumulative ? item->setTotal(cost) : item->addToTotal(cost); + } + } + m_dlv->calculate(); + TQApplication::restoreOverrideCursor(); + return; + } + if (m_period == 1) { //Weekly + //TODO make this user controlled + int weekStartDay = locale->weekStartDay(); + + TQDate dt = start; + TQDate pend = cal->addDays(dt, 7 + weekStartDay - 1 - cal->dayOfWeek(dt)); + for (; pend <= end; ++c) { + //kdDebug()<<k_funcinfo<<c<<": "<<dt<<"-"<<pend<<" : "<<end<<endl; + int y; + int w = cal->weekNumber(dt, &y); + TQString t = i18n("<week>-<year>", "%1-%2").arg(w).arg(y); + m_dlv->addSlaveColumn(t); + dt = pend.addDays(1); + pend = cal->addDays(pend, 7); + if ((pend.year() == end.year()) && (pend.weekNumber() == end.weekNumber())) { + pend = end; + } + } + if (c == 0) { + TQApplication::restoreOverrideCursor(); + return; + } + TQListViewItemIterator it(m_dlv->masterListView()); + for (;it.current(); ++it) { + AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current()); + if (!item || !item->account || !item->account->isElement()) { + continue; + } + item->costMap = m_accounts.plannedCost(*(item->account), start, end); + double cost = 0.0; + TQDate d = start; + TQDate pend = cal->addDays(d, 7 + weekStartDay - 1 - cal->dayOfWeek(d)); + for (int col=0; pend <= end; ++col) { + double cst = item->costMap.cost(d, d.daysTo(pend)+1); + cost = (m_cumulative ? cost + cst : cst); + item->setSlaveItem(col, cost); + m_cumulative ? item->setTotal(cost) : item->addToTotal(cost); + d = pend.addDays(1); // 1. next week + pend = cal->addDays(pend, 7); + if ((pend.year() == end.year()) && (pend.weekNumber() == end.weekNumber())) { + pend = end; + } + } + } + m_dlv->calculate(); + TQApplication::restoreOverrideCursor(); + return; + } + if (m_period == 2) { //Monthly + //TODO make this user controlled + TQDate dt = start; + TQDate pend; + cal->setYMD(pend, dt.year(), dt.month(), dt.daysInMonth()); + for (; pend <= end; ++c) { + //kdDebug()<<k_funcinfo<<c<<": "<<dt<<"-"<<pend<<" : "<<end<<endl; + TQString m = cal->monthName(dt, true) + TQString(" %1").arg( dt.year()); + m_dlv->addSlaveColumn(m); + + dt = pend.addDays(1); // 1. next month + pend = cal->addDays(pend, dt.daysInMonth()); + if ((pend.year() == end.year()) && (pend.month() == end.month())) { + pend = end; + } + } + if (c == 0) { + TQApplication::restoreOverrideCursor(); + return; + } + TQListViewItemIterator it(m_dlv->masterListView()); + for (;it.current(); ++it) { + AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current()); + if (!item || !item->account || !item->account->isElement()) { + continue; + } + item->costMap = m_accounts.plannedCost(*(item->account), start, end); + double cost = 0.0; + TQDate d = start; + cal->setYMD(pend, d.year(), d.month(), d.daysInMonth()); + for (int col=0; pend <= end; ++col) { + double cst = item->costMap.cost(d, d.daysTo(pend)+1); + cost = (m_cumulative ? cost + cst : cst); + item->setSlaveItem(col, cost); + m_cumulative ? item->setTotal(cost) : item->addToTotal(cost); + d = pend.addDays(1); // 1. next month + pend = cal->addDays(pend, d.daysInMonth()); + if ((pend.year() == end.year()) && (pend.month() == end.month())) { + pend = end; + } + } + } + m_dlv->calculate(); + TQApplication::restoreOverrideCursor(); + return; + } + TQApplication::restoreOverrideCursor(); +} + +void AccountsView::print(KPrinter &printer) { + //kdDebug()<<k_funcinfo<<endl; + TQPaintDeviceMetrics m = TQPaintDeviceMetrics ( &printer ); + uint top, left, bottom, right; + printer.margins(&top, &left, &bottom, &right); + //kdDebug()<<m.width()<<"x"<<m.height()<<" : "<<top<<", "<<left<<", "<<bottom<<", "<<right<<" : "<<size()<<endl; + TQPainter p; + p.begin(&printer); + p.setViewport(left, top, m.width()-left-right, m.height()-top-bottom); + p.setClipRect(left, top, m.width()-left-right, m.height()-top-bottom); + TQRect preg = p.clipRegion(TQPainter::CoordPainter).boundingRect(); + //kdDebug()<<"p="<<preg<<endl; + //p.drawRect(preg.x(), preg.y(), preg.width()-1, preg.height()-1); + double scale = TQMIN((double)preg.width()/(double)size().width(), (double)preg.height()/(double)(size().height())); + //kdDebug()<<"scale="<<scale<<endl; + if (scale < 1.0) { + p.scale(scale, scale); + } + m_label->paintContents(&p); + p.translate(0, m_label->size().height()); + m_dlv->paintContents(&p); + p.end(); +} + +bool AccountsView::setContext(Context::Accountsview &context) { + //kdDebug()<<k_funcinfo<<"---->"<<endl; + TQValueList<int> list; + list << context.accountsviewsize << context.periodviewsize; + //m_dlv->setSizes(list); //NOTE: This doesn't always work! + m_date = context.date; + if (!m_date.isValid()) + m_date = TQDate::currentDate(); + m_period = context.period; + m_cumulative = context.cumulative; + setContextClosedItems(context); + //kdDebug()<<k_funcinfo<<"<----"<<endl; + return true; +} + +void AccountsView::setContextClosedItems(Context::Accountsview &context) { + for (TQStringList::ConstIterator it = context.closedItems.begin(); it != context.closedItems.end(); ++it) { + if (m_accounts.findAccount(*it)) { + TQListViewItemIterator lit(m_dlv->masterListView()); + for (; lit.current(); ++lit) { + if (lit.current()->text(0) == (*it)) { + m_dlv->setOpen(lit.current(), false); + break; + } + } + } + } +} + +void AccountsView::getContext(Context::Accountsview &context) const { + //kdDebug()<<k_funcinfo<<endl; + context.accountsviewsize = m_dlv->sizes()[0]; + context.periodviewsize = m_dlv->sizes()[1]; + context.date = m_date; + context.period = m_period; + context.cumulative = m_cumulative; + //kdDebug()<<k_funcinfo<<"sizes="<<sizes()[0]<<","<<sizes()[1]<<endl; + + getContextClosedItems(context, m_dlv->masterListView()->firstChild()); +} + + +void AccountsView::getContextClosedItems(Context::Accountsview &context, TQListViewItem *item) const { + if (item == 0) + return; + for (TQListViewItem *i = item; i; i = i->nextSibling()) { + if (!i->isOpen()) { + context.closedItems.append(i->text(0)); + //kdDebug()<<k_funcinfo<<"add closed "<<i->text(0)<<endl; + } + getContextClosedItems(context, i->firstChild()); + } +} + +void AccountsView::slotConfigure() { + //kdDebug()<<k_funcinfo<<endl; + AccountsviewConfigDialog *dia = new AccountsviewConfigDialog(m_date, m_period, m_periodTexts, m_cumulative, this); + if (dia->exec()) { + m_date = dia->date(); + m_period = dia->period(); + m_cumulative = dia->isCumulative(); + emit update(); + } + delete dia; +} + +TQString AccountsView::periodText(int offset) { + TQString s; + TQStringList::const_iterator it = m_periodTexts.at(offset); + if (it != m_periodTexts.constEnd()) { + s = (*it); + } + return s; +} + +} //KPlato namespace + +#include "kptaccountsview.moc" |