00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptaccountsview.h"
00021
00022 #include "kptaccountsviewconfigdialog.h"
00023 #include "kptcontext.h"
00024 #include "kptdatetime.h"
00025 #include "kptproject.h"
00026 #include "kptview.h"
00027 #include "kpteffortcostmap.h"
00028
00029 #include <qapplication.h>
00030 #include <qcombobox.h>
00031 #include <qdatetime.h>
00032 #include <qdatetimeedit.h>
00033 #include <qheader.h>
00034 #include <qlabel.h>
00035 #include <qlayout.h>
00036 #include <qpainter.h>
00037 #include <qpalette.h>
00038 #include <qpushbutton.h>
00039 #include <qvaluelist.h>
00040 #include <qpopupmenu.h>
00041 #include <qsizepolicy.h>
00042 #include <qhbox.h>
00043 #include <qpaintdevicemetrics.h>
00044
00045 #include <kcalendarsystem.h>
00046 #include <kglobal.h>
00047 #include <klistview.h>
00048 #include <klocale.h>
00049 #include <kprinter.h>
00050
00051 #include <kdebug.h>
00052
00053 namespace KPlato
00054 {
00055
00056 class Label : public QLabel
00057 {
00058 public:
00059 Label(QWidget *w)
00060 : QLabel(w)
00061 {}
00062 void paintContents(QPainter *p) {
00063 drawContents(p);
00064 }
00065 };
00066
00067 AccountsView::AccountItem::AccountItem(Account *a, QListView *parent, bool highlight)
00068 : DoubleListViewBase::MasterListItem(parent, a->name(), highlight),
00069 account(a) {
00070 if (parent->columns() >= 3) {
00071 setText(2, a->description());
00072 }
00073
00074 }
00075 AccountsView::AccountItem::AccountItem(Account *a, QListViewItem *p, bool highlight)
00076 : DoubleListViewBase::MasterListItem(p, a->name(), highlight),
00077 account(a) {
00078 if (listView() && listView()->columns() >= 3) {
00079 setText(2, a->description());
00080 }
00081
00082 }
00083
00084 AccountsView::AccountItem::AccountItem(QString text, Account *a, QListViewItem *parent, bool highlight)
00085 : DoubleListViewBase::MasterListItem(parent, text, highlight),
00086 account(a) {
00087
00088 }
00089
00090 void AccountsView::AccountItem::add(int col, const QDate &date, const EffortCost &ec) {
00091 EffortCost &cm = costMap.add(date, ec);
00092 if (m_slaveItem)
00093 m_slaveItem->setText(col, KGlobal::locale()->formatMoney(cm.cost(), "", 0));
00094 }
00095
00096 AccountsView::AccountsView(Project &project, View *view, QWidget *parent)
00097 : QWidget(parent, "Accounts view"),
00098 m_mainview(view),
00099 m_project(project),
00100 m_accounts(project.accounts()) {
00101
00102 m_date = QDate::currentDate();
00103 m_period = 0;
00104 m_periodTexts<<i18n("Day")<<i18n("Week")<<i18n("Month");
00105 m_cumulative = false;
00106
00107 QVBoxLayout *lay1 = new QVBoxLayout(this, 0, KDialog::spacingHint());
00108
00109 QHBoxLayout *lay2 = new QHBoxLayout(0, 0, KDialog::spacingHint());
00110 m_label = new Label(this);
00111 m_label->setFrameShape(QLabel::StyledPanel);
00112 m_label->setFrameShadow(QLabel::Sunken);
00113 m_label->setAlignment(int(QLabel::WordBreak | QLabel::AlignVCenter));
00114 lay2->addWidget(m_label);
00115 m_changeBtn = new QPushButton(i18n("Configure..."), this);
00116 m_changeBtn->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, m_changeBtn->sizePolicy().hasHeightForWidth()));
00117 lay2->addWidget(m_changeBtn);
00118 lay1->addLayout(lay2);
00119
00120 m_dlv = new DoubleListViewBase(this, true);
00121 m_dlv->setNameHeader(i18n("Account"));
00122
00123 init();
00124
00125 lay1->addWidget(m_dlv);
00126
00127 connect(this, SIGNAL(update()), SLOT(slotUpdate()));
00128 connect(m_changeBtn, SIGNAL(clicked()), SLOT(slotConfigure()));
00129
00130 QValueList<int> list = m_dlv->sizes();
00131 int tot = list[0] + list[1];
00132 list[0] = QMIN(35, tot);
00133 list[1] = tot-list[0];
00134 m_dlv->setSizes(list);
00135 }
00136
00137 void AccountsView::zoom(double zoom) {
00138 Q_UNUSED(zoom);
00139 }
00140
00141 void AccountsView::init() {
00142 m_date = QDate::currentDate();
00143 m_period = 0;
00144 initAccList(m_accounts.accountList());
00145 }
00146
00147 void AccountsView::draw() {
00148
00149 Context::Accountsview context;
00150 getContextClosedItems(context, m_dlv->masterListView()->firstChild());
00151 initAccList(m_accounts.accountList());
00152 setContextClosedItems(context);
00153 slotUpdate();
00154 }
00155
00156 void AccountsView::initAccList(const AccountList &list) {
00157 m_dlv->clearLists();
00158 AccountListIterator it = list;
00159 for (it.toLast(); it.current(); --it) {
00160 AccountsView::AccountItem *a = new AccountsView::AccountItem(it.current(), m_dlv->masterListView());
00161 a->setOpen(true);
00162 a->setExpandable(!it.current()->isElement());
00163 initAccSubItems(it.current(), a);
00164 }
00165 createPeriods();
00166 }
00167
00168 void AccountsView::initAccSubItems(Account *acc, AccountsView::AccountItem *parent) {
00169 if (!acc->accountList().isEmpty()) {
00170
00171
00172
00173
00174 initAccList(acc->accountList(), parent);
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 }
00189
00190 void AccountsView::initAccList(const AccountList &list, AccountsView::AccountItem *parent) {
00191 AccountListIterator it = list;
00192 for (it.toLast(); it.current(); --it) {
00193 AccountsView::AccountItem *a = new AccountsView::AccountItem(it.current(), parent);
00194 a->setOpen(true);
00195 a->setExpandable(!it.current()->isElement());
00196 initAccSubItems(it.current(), a);
00197 }
00198 }
00199
00200 void AccountsView::clearPeriods() {
00201 m_dlv->clearSlaveList();
00202 }
00203
00204 void AccountsView::createPeriods() {
00205 m_dlv->createSlaveItems();
00206 }
00207
00208 void AccountsView::slotUpdate() {
00209
00210 QApplication::setOverrideCursor(Qt::waitCursor);
00211 createPeriods();
00212 KLocale *locale = KGlobal::locale();
00213 const KCalendarSystem *cal = locale->calendar();
00214
00215 QString t;
00216 if (m_cumulative) {
00217 t += " <b>" + i18n("Cumulative") + "</b> ";
00218 }
00219 t += i18n("Cut-off date:%1").arg("<b>" + locale->formatDate(m_date, true) + "</b>");
00220 t += " " + i18n("Periodicity:%1").arg("<b>" + periodText(m_period) + "</b>");
00221 m_label->setText(t);
00222
00223
00224 QDate start = m_project.startTime().date();
00225 QDate end = m_date;
00226
00227 int c=0;
00228 if (m_period == 0) {
00229 for (QDate dt = start; dt <= end; dt = cal->addDays(dt, 1), ++c) {
00230 QString df = locale->formatDate(dt, true);
00231 m_dlv->addSlaveColumn(df);
00232 }
00233 QListViewItemIterator it(m_dlv->masterListView());
00234 for (;it.current(); ++it) {
00235 AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current());
00236 if (!item || !item->account || !item->account->isElement()) {
00237 continue;
00238 }
00239 item->costMap = m_accounts.plannedCost(*(item->account), start, end);
00240 double cost = 0.0;
00241 int col=0;
00242 for (QDate d=start; d <= end; d = cal->addDays(d, 1), ++col) {
00243 EffortCost &ec = item->costMap.effortCostOnDate(d);
00244 cost = (m_cumulative ? cost + ec.cost() : ec.cost());
00245 item->setSlaveItem(col, cost);
00246 m_cumulative ? item->setTotal(cost) : item->addToTotal(cost);
00247 }
00248 }
00249 m_dlv->calculate();
00250 QApplication::restoreOverrideCursor();
00251 return;
00252 }
00253 if (m_period == 1) {
00254
00255 int weekStartDay = locale->weekStartDay();
00256
00257 QDate dt = start;
00258 QDate pend = cal->addDays(dt, 7 + weekStartDay - 1 - cal->dayOfWeek(dt));
00259 for (; pend <= end; ++c) {
00260
00261 int y;
00262 int w = cal->weekNumber(dt, &y);
00263 QString t = i18n("<week>-<year>", "%1-%2").arg(w).arg(y);
00264 m_dlv->addSlaveColumn(t);
00265 dt = pend.addDays(1);
00266 pend = cal->addDays(pend, 7);
00267 if ((pend.year() == end.year()) && (pend.weekNumber() == end.weekNumber())) {
00268 pend = end;
00269 }
00270 }
00271 if (c == 0) {
00272 QApplication::restoreOverrideCursor();
00273 return;
00274 }
00275 QListViewItemIterator it(m_dlv->masterListView());
00276 for (;it.current(); ++it) {
00277 AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current());
00278 if (!item || !item->account || !item->account->isElement()) {
00279 continue;
00280 }
00281 item->costMap = m_accounts.plannedCost(*(item->account), start, end);
00282 double cost = 0.0;
00283 QDate d = start;
00284 QDate pend = cal->addDays(d, 7 + weekStartDay - 1 - cal->dayOfWeek(d));
00285 for (int col=0; pend <= end; ++col) {
00286 double cst = item->costMap.cost(d, d.daysTo(pend)+1);
00287 cost = (m_cumulative ? cost + cst : cst);
00288 item->setSlaveItem(col, cost);
00289 m_cumulative ? item->setTotal(cost) : item->addToTotal(cost);
00290 d = pend.addDays(1);
00291 pend = cal->addDays(pend, 7);
00292 if ((pend.year() == end.year()) && (pend.weekNumber() == end.weekNumber())) {
00293 pend = end;
00294 }
00295 }
00296 }
00297 m_dlv->calculate();
00298 QApplication::restoreOverrideCursor();
00299 return;
00300 }
00301 if (m_period == 2) {
00302
00303 QDate dt = start;
00304 QDate pend;
00305 cal->setYMD(pend, dt.year(), dt.month(), dt.daysInMonth());
00306 for (; pend <= end; ++c) {
00307
00308 QString m = cal->monthName(dt, true) + QString(" %1").arg( dt.year());
00309 m_dlv->addSlaveColumn(m);
00310
00311 dt = pend.addDays(1);
00312 pend = cal->addDays(pend, dt.daysInMonth());
00313 if ((pend.year() == end.year()) && (pend.month() == end.month())) {
00314 pend = end;
00315 }
00316 }
00317 if (c == 0) {
00318 QApplication::restoreOverrideCursor();
00319 return;
00320 }
00321 QListViewItemIterator it(m_dlv->masterListView());
00322 for (;it.current(); ++it) {
00323 AccountsView::AccountItem *item = dynamic_cast<AccountsView::AccountItem*>(it.current());
00324 if (!item || !item->account || !item->account->isElement()) {
00325 continue;
00326 }
00327 item->costMap = m_accounts.plannedCost(*(item->account), start, end);
00328 double cost = 0.0;
00329 QDate d = start;
00330 cal->setYMD(pend, d.year(), d.month(), d.daysInMonth());
00331 for (int col=0; pend <= end; ++col) {
00332 double cst = item->costMap.cost(d, d.daysTo(pend)+1);
00333 cost = (m_cumulative ? cost + cst : cst);
00334 item->setSlaveItem(col, cost);
00335 m_cumulative ? item->setTotal(cost) : item->addToTotal(cost);
00336 d = pend.addDays(1);
00337 pend = cal->addDays(pend, d.daysInMonth());
00338 if ((pend.year() == end.year()) && (pend.month() == end.month())) {
00339 pend = end;
00340 }
00341 }
00342 }
00343 m_dlv->calculate();
00344 QApplication::restoreOverrideCursor();
00345 return;
00346 }
00347 QApplication::restoreOverrideCursor();
00348 }
00349
00350 void AccountsView::print(KPrinter &printer) {
00351
00352 QPaintDeviceMetrics m = QPaintDeviceMetrics ( &printer );
00353 uint top, left, bottom, right;
00354 printer.margins(&top, &left, &bottom, &right);
00355
00356 QPainter p;
00357 p.begin(&printer);
00358 p.setViewport(left, top, m.width()-left-right, m.height()-top-bottom);
00359 p.setClipRect(left, top, m.width()-left-right, m.height()-top-bottom);
00360 QRect preg = p.clipRegion(QPainter::CoordPainter).boundingRect();
00361
00362
00363 double scale = QMIN((double)preg.width()/(double)size().width(), (double)preg.height()/(double)(size().height()));
00364
00365 if (scale < 1.0) {
00366 p.scale(scale, scale);
00367 }
00368 m_label->paintContents(&p);
00369 p.translate(0, m_label->size().height());
00370 m_dlv->paintContents(&p);
00371 p.end();
00372 }
00373
00374 bool AccountsView::setContext(Context::Accountsview &context) {
00375
00376 QValueList<int> list;
00377 list << context.accountsviewsize << context.periodviewsize;
00378 m_dlv->setSizes(list);
00379 m_date = context.date;
00380 if (!m_date.isValid())
00381 m_date = QDate::currentDate();
00382 m_period = context.period;
00383 m_cumulative = context.cumulative;
00384 setContextClosedItems(context);
00385
00386 return true;
00387 }
00388
00389 void AccountsView::setContextClosedItems(Context::Accountsview &context) {
00390 for (QStringList::ConstIterator it = context.closedItems.begin(); it != context.closedItems.end(); ++it) {
00391 if (m_accounts.findAccount(*it)) {
00392 QListViewItemIterator lit(m_dlv->masterListView());
00393 for (; lit.current(); ++lit) {
00394 if (lit.current()->text(0) == (*it)) {
00395 m_dlv->setOpen(lit.current(), false);
00396 break;
00397 }
00398 }
00399 }
00400 }
00401 }
00402
00403 void AccountsView::getContext(Context::Accountsview &context) const {
00404
00405 context.accountsviewsize = m_dlv->sizes()[0];
00406 context.periodviewsize = m_dlv->sizes()[1];
00407 context.date = m_date;
00408 context.period = m_period;
00409 context.cumulative = m_cumulative;
00410
00411
00412 getContextClosedItems(context, m_dlv->masterListView()->firstChild());
00413 }
00414
00415
00416 void AccountsView::getContextClosedItems(Context::Accountsview &context, QListViewItem *item) const {
00417 if (item == 0)
00418 return;
00419 for (QListViewItem *i = item; i; i = i->nextSibling()) {
00420 if (!i->isOpen()) {
00421 context.closedItems.append(i->text(0));
00422
00423 }
00424 getContextClosedItems(context, i->firstChild());
00425 }
00426 }
00427
00428 void AccountsView::slotConfigure() {
00429
00430 AccountsviewConfigDialog *dia = new AccountsviewConfigDialog(m_date, m_period, m_periodTexts, m_cumulative, this);
00431 if (dia->exec()) {
00432 m_date = dia->date();
00433 m_period = dia->period();
00434 m_cumulative = dia->isCumulative();
00435 emit update();
00436 }
00437 delete dia;
00438 }
00439
00440 QString AccountsView::periodText(int offset) {
00441 QString s;
00442 QStringList::const_iterator it = m_periodTexts.at(offset);
00443 if (it != m_periodTexts.constEnd()) {
00444 s = (*it);
00445 }
00446 return s;
00447 }
00448
00449 }
00450
00451 #include "kptaccountsview.moc"