You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
452 lines
16 KiB
452 lines
16 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2005 Dag Andersen kplato@kde.org>
|
|
|
|
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, TQ_SIGNAL(update()), TQ_SLOT(slotUpdate()));
|
|
connect(m_changeBtn, TQ_SIGNAL(clicked()), TQ_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"
|