summaryrefslogtreecommitdiffstats
path: root/kplato/kptaccountsview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kplato/kptaccountsview.cpp')
-rw-r--r--kplato/kptaccountsview.cpp451
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"