00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptdoublelistviewbase.h"
00021
00022 #include "kptproject.h"
00023 #include "kptview.h"
00024
00025 #include <QPainter>
00026 #include <QLayout>
00027 #include <QMap>
00028 #include <QSplitter>
00029 #include <QString>
00030 #include <QList>
00031 #include <QPoint>
00032 #include <QTreeWidgetItem>
00033 #include <QRect>
00034 #include <QScrollBar>
00035 #include <QHeaderView>
00036
00037 #include <kcalendarsystem.h>
00038 #include <kglobal.h>
00039 #include <klocale.h>
00040 #include <kprinter.h>
00041
00042
00043 #include <kdebug.h>
00044
00045 namespace KPlato
00046 {
00047 void ListView::paintToPrinter(QPainter * p, int cx, int cy, int cw, int ch) {
00048 #if 0
00049
00050
00051 p->save();
00052 QRegion r = p->clipRegion();
00053 p->setClipRegion(r.intersect(QRegion(cx, 0, cw, ch)));
00054 QColor bgc(193, 223, 255);
00055 QBrush bg(bgc);
00056 p->setBackgroundMode(Qt::OpaqueMode);
00057 p->setBackgroundColor(bgc);
00058 Q3Header *h = header();
00059 int hei = 0;
00060 for (int s = 0; s < h->count(); ++s) {
00061 QRect r = h->sectionRect(s);
00062
00063 int x, y;
00064 viewportToContents(r.x(), r.y(), x, y);
00065 QRect sr(x, y, r.width(), r.height());
00066
00067 if (sr.x()+sr.width() <= cx || sr.x() >= cx+cw) {
00068
00069 continue;
00070 }
00071 QRect tr = sr;
00072 if (sr.x() < cx) {
00073 tr.setX(cx);
00074
00075 }
00076 p->eraseRect(tr);
00077 p->drawText(tr, columnAlignment(s)|Qt::AlignVCenter, h->label(s), -1);
00078 hei = qMax(tr.height(), hei);
00079 }
00080 r = p->clipRegion();
00081 p->restore();
00082
00083 p->save();
00084 p->translate(0, hei+2);
00085 r = p->clipRegion();
00086
00087 p->setClipRegion(r.intersect(QRegion(cx, cy, cw, ch)));
00088 drawContentsOffset(p, 0, 0, cx, cy, cw, ch);
00089
00090 p->restore();
00091 #endif
00092 }
00093
00094 DoubleListViewBase::SlaveListItem::SlaveListItem(DoubleListViewBase::MasterListItem *master, QTreeWidget *parent, QTreeWidgetItem *after, bool highlight)
00095 : QTreeWidgetItem(parent, after),
00096 m_masterItem(master),
00097 m_value(0.0),
00098 m_highlight(highlight),
00099 m_valueMap() {
00100
00101 setFormat();
00102
00103
00104
00105 }
00106 DoubleListViewBase::SlaveListItem::SlaveListItem(DoubleListViewBase::MasterListItem *master, QTreeWidgetItem *parent, QTreeWidgetItem *after, bool highlight)
00107 : QTreeWidgetItem(parent, after),
00108 m_masterItem(master),
00109 m_value(0.0),
00110 m_highlight(highlight),
00111 m_valueMap() {
00112
00113 setFormat();
00114
00115
00116
00117 }
00118 DoubleListViewBase::SlaveListItem::~SlaveListItem() {
00119
00120 if (m_masterItem)
00121 m_masterItem->slaveItemDeleted();
00122 }
00123
00124 void DoubleListViewBase::SlaveListItem::clearColumn(int col) {
00125 if (col >= columnCount()) {
00126 return;
00127 }
00128 treeWidget()->headerItem()->setText(col, "");
00129 setText(col, "");
00130 m_valueMap[col] = 0;
00131 }
00132 void DoubleListViewBase::SlaveListItem::setColumn(int col, double value) {
00133
00134 setTextAlignment(col, Qt::AlignRight);
00135 setText(col, KGlobal::locale()->formatNumber(value, m_prec));
00136 m_valueMap.replace(col, value);
00137
00138 }
00139
00140 void DoubleListViewBase::SlaveListItem::setLimit(int col, double limit) {
00141 m_limitMap[col] = limit;
00142 }
00143
00144 void DoubleListViewBase::SlaveListItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) {
00145
00146 QColorGroup g = cg;
00147 if (m_highlight) {
00148 if (m_limitMap.contains(column)) {
00149 if (m_valueMap[column] > m_limitMap[column]) {
00150 g.setColor(QColorGroup::Text, QColor(Qt::red));
00151 } else if (m_valueMap[column] < m_limitMap[column]) {
00152 g.setColor(QColorGroup::Text, QColor(Qt::green));
00153 }
00154 }
00155 }
00156
00157 }
00158
00159 void DoubleListViewBase::SlaveListItem::setFormat(int fieldwidth, char fmt, int prec) {
00160 m_fieldwidth = fieldwidth;
00161 m_fmt = fmt;
00162 m_prec = prec;
00163 }
00164
00165
00166 DoubleListViewBase::MasterListItem::MasterListItem(QTreeWidget *parent, bool highlight)
00167 : QTreeWidgetItem(parent),
00168 m_slaveItem(0),
00169 m_value(0.0),
00170 m_limit(0.0),
00171 m_highlight(highlight) {
00172
00173 setFormat();
00174
00175 }
00176
00177 DoubleListViewBase::MasterListItem::MasterListItem(QTreeWidget *parent, QString text, bool highlight)
00178 : QTreeWidgetItem(parent),
00179 m_slaveItem(0),
00180 m_value(0.0),
00181 m_limit(0.0),
00182 m_highlight(highlight) {
00183 setText(0, text);
00184 setFormat();
00185
00186 }
00187
00188 DoubleListViewBase::MasterListItem::MasterListItem(QTreeWidgetItem *parent, bool highlight)
00189 : QTreeWidgetItem(parent),
00190 m_slaveItem(0),
00191 m_value(0.0),
00192 m_limit(0.0),
00193 m_highlight(highlight) {
00194
00195 setFormat();
00196
00197 }
00198
00199 DoubleListViewBase::MasterListItem::MasterListItem(QTreeWidgetItem *parent, QString text, bool highlight)
00200 : QTreeWidgetItem(parent),
00201 m_slaveItem(0),
00202 m_value(0.0),
00203 m_limit(0.0),
00204 m_highlight(highlight) {
00205
00206 setFormat();
00207 setText(0, text);
00208
00209 }
00210
00211 DoubleListViewBase::MasterListItem::~MasterListItem() {
00212 if (m_slaveItem)
00213 m_slaveItem->masterItemDeleted();
00214 }
00215
00216 void DoubleListViewBase::MasterListItem::createSlaveItems(QTreeWidget *lv, QTreeWidgetItem *after) {
00217
00218 if (m_slaveItem) {
00219 kError()<<k_funcinfo<<"Slave item already exists"<<endl;
00220 } else {
00221 if (parent() == 0) {
00222 m_slaveItem = new DoubleListViewBase::SlaveListItem(this, lv, after);
00223 } else {
00224 m_slaveItem = new DoubleListViewBase::SlaveListItem(this, static_cast<DoubleListViewBase::MasterListItem*>(parent())->m_slaveItem, after);
00225 }
00226 }
00227 DoubleListViewBase::SlaveListItem *prev = 0;
00228 QTreeWidgetItem *item = 0;
00229 for (int i=0; (item = child(i)) != 0; ++i) {
00230 static_cast<DoubleListViewBase::MasterListItem*>(item)->createSlaveItems(lv, prev);
00231 prev = static_cast<DoubleListViewBase::MasterListItem*>(item)->m_slaveItem;
00232 }
00233 }
00234
00235 void DoubleListViewBase::MasterListItem::setSlaveOpen(bool on) {
00236 if (m_slaveItem)
00237 m_slaveItem->setExpanded(on);
00238 }
00239
00240 void DoubleListViewBase::MasterListItem::slaveItemDeleted() {
00241 setTotal(0);
00242 m_slaveItem = 0;
00243 }
00244
00245 void DoubleListViewBase::MasterListItem::setTotal(double tot) {
00246 m_value = tot;
00247
00248 setTextAlignment(1, Qt::AlignRight);
00249 setText(1, KGlobal::locale()->formatNumber(tot, m_prec));
00250
00251 }
00252
00253 void DoubleListViewBase::MasterListItem::addToTotal(double v) {
00254 m_value += v;
00255
00256 setText(1, KGlobal::locale()->formatNumber(m_value, m_prec));
00257 }
00258
00259 double DoubleListViewBase::MasterListItem::calcTotal() {
00260
00261 double tot=0.0;
00262 QTreeWidgetItem *item=child(0);
00263 if (!item) {
00264 tot = m_value;
00265 } else {
00266 for (int i=0; (item = child(i)) != 0; ++i) {
00267 tot += static_cast<DoubleListViewBase::MasterListItem*>(item)->calcTotal();
00268 }
00269 }
00270 setTotal(tot);
00271 return tot;
00272 }
00273
00274 void DoubleListViewBase::MasterListItem::setSlaveItem(int col, double value) {
00275 if (m_slaveItem) {
00276 m_slaveItem->setColumn(col, value);
00277 }
00278 }
00279
00280 void DoubleListViewBase::MasterListItem::clearColumn(int col) {
00281 QTreeWidgetItem *item=0;
00282 for (int i=0; (item = child(i)) != 0; ++i) {
00283 static_cast<DoubleListViewBase::MasterListItem*>(item)->clearColumn(col);
00284 }
00285 setTotal(0);
00286 if (m_slaveItem == 0) {
00287 kError()<<k_funcinfo<<"No m_slaveItem"<<endl;
00288 return;
00289 }
00290 m_slaveItem->clearColumn(0);
00291 }
00292
00293 void DoubleListViewBase::MasterListItem::calcSlaveItems() {
00294 if (m_slaveItem == 0 || m_slaveItem->treeWidget() == 0) {
00295 kError()<<k_funcinfo<<"No m_slaveItem or m_slaveItem->treeWidget()"<<endl;
00296 return;
00297 }
00298 int cols = m_slaveItem->columnCount();
00299 for (int i = 0; i < cols; ++i) {
00300 calcSlaveItems(i);
00301 }
00302 }
00303
00304 double DoubleListViewBase::MasterListItem::calcSlaveItems(int col) {
00305
00306 if (m_slaveItem == 0)
00307 return 0.0;
00308 QTreeWidgetItem *item=child(0);
00309 if (!item) {
00310 return m_slaveItem->value(col);
00311 }
00312 double tot=0.0;
00313 for (int i=0; (item = child(i)) != 0; ++i) {
00314 tot += static_cast<DoubleListViewBase::MasterListItem*>(item)->calcSlaveItems(col);
00315 }
00316
00317 setSlaveItem(col, tot);
00318 return tot;
00319 }
00320
00321 void DoubleListViewBase::MasterListItem::setSlaveLimit(int col, double limit) {
00322 if (m_slaveItem) {
00323 m_slaveItem->setLimit(col, limit);
00324 }
00325 }
00326
00327 void DoubleListViewBase::MasterListItem::setSlaveHighlight(bool on) {
00328 if (m_slaveItem) {
00329 m_slaveItem->setHighlight(on);
00330 }
00331 }
00332
00333 void DoubleListViewBase::MasterListItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int align) {
00334
00335 QColorGroup g = cg;
00336 if (column == 1 && m_highlight) {
00337 if (m_value > m_limit) {
00338 g.setColor(QColorGroup::Text, QColor(Qt::red));
00339 } else if (m_value < m_limit) {
00340 g.setColor(QColorGroup::Text, QColor(Qt::green));
00341 }
00342 }
00343
00344 }
00345
00346 void DoubleListViewBase::MasterListItem::setFormat(int fieldwidth, char fmt, int prec) {
00347 m_fieldwidth = fieldwidth;
00348 m_fmt = fmt;
00349 m_prec = prec;
00350 }
00351
00352
00353 DoubleListViewBase::DoubleListViewBase(QWidget *parent, bool description)
00354 : QSplitter(parent),
00355 m_fieldwidth(0),
00356 m_fmt('f'),
00357 m_prec(0) {
00358
00359 setOrientation(Qt::Horizontal);
00360 setHandleWidth(qMin(2, handleWidth()));
00361
00362 m_masterList = new ListView(this);
00363 QHeaderView *h = m_masterList->header();
00364 m_masterList->setSortingEnabled(false);
00365 m_masterList->setSelectionMode(QAbstractItemView::NoSelection);
00366 m_masterList->setHeaderLabels(QStringList()<<i18n("Name")<<i18n("Total")<<i18n("Description"));
00367 m_masterList->headerItem()->setTextAlignment(1, Qt::AlignRight);
00368 h->moveSection(2, 1);
00369 h->setResizeMode(2, QHeaderView::Stretch);
00370 h->setSectionHidden(2, !description);
00371
00372 m_masterList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00373 m_masterList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
00374
00375 m_slaveList = new ListView(this);
00376 m_slaveList->header()->setDefaultAlignment(Qt::AlignRight);
00377 m_slaveList->setItemsExpandable(false);
00378 m_slaveList->setSelectionMode(QAbstractItemView::NoSelection);
00379 m_slaveList->setRootIsDecorated(false);
00380 m_slaveList->setIndentation(0);
00381 int left, top, right, bottom;
00382 m_slaveList->getContentsMargins(&left, &top, &right, &bottom);
00383 m_slaveList->setContentsMargins(2, top, right, bottom);
00384
00385 m_slaveList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
00386
00387 connect(m_slaveList->verticalScrollBar(), SIGNAL(valueChanged(int)), m_masterList->verticalScrollBar(), SLOT(setValue(int)));
00388
00389 connect(m_masterList, SIGNAL(itemExpanded(QTreeWidgetItem*)), SLOT(slotExpanded(QTreeWidgetItem*)));
00390 connect(m_masterList, SIGNAL(itemCollapsed(QTreeWidgetItem*)), SLOT(slotCollapsed(QTreeWidgetItem*)));
00391
00392 }
00393
00394 QSize DoubleListViewBase::sizeHint() const {
00395
00396 return minimumSizeHint();
00397 }
00398
00399 void DoubleListViewBase::clearSlaveList() {
00400
00401
00402
00403 m_slaveList->clear();
00404 }
00405
00406 void DoubleListViewBase::createSlaveItems() {
00407 clearSlaveList();
00408 DoubleListViewBase::SlaveListItem *prev = 0;
00409 QTreeWidgetItem *item=0;
00410 for (int i=0; (item=m_masterList->topLevelItem(i)) != 0; ++i) {
00411 static_cast<DoubleListViewBase::MasterListItem*>(item)->createSlaveItems(m_slaveList, prev);
00412 prev = static_cast<DoubleListViewBase::MasterListItem*>(item)->slaveItem();
00413 }
00414 }
00415
00416
00417 void DoubleListViewBase::print(KPrinter &printer) {
00418 kDebug()<<k_funcinfo<<endl;
00419 Q_UNUSED(printer);
00420 }
00421
00422 void DoubleListViewBase::setOpen(QTreeWidgetItem *item, bool open) {
00423
00424
00425 }
00426
00427 void DoubleListViewBase::slotExpanded(QTreeWidgetItem* item) {
00428
00429 if (item) {
00430 static_cast<DoubleListViewBase::MasterListItem*>(item)->setSlaveOpen(true);
00431 }
00432 }
00433
00434 void DoubleListViewBase::slotCollapsed(QTreeWidgetItem*item) {
00435
00436 if (item) {
00437 static_cast<DoubleListViewBase::MasterListItem*>(item)->setSlaveOpen(false);
00438 }
00439 }
00440
00441 void DoubleListViewBase::setDescriptionHeader(QString text) {
00442 m_masterList->headerItem()->setText(1, text);
00443 }
00444
00445 void DoubleListViewBase::setNameHeader(QString text) {
00446 m_masterList->headerItem()->setText(0, text);
00447 }
00448
00449 void DoubleListViewBase::setTotalHeader(QString text) {
00450 m_masterList->headerItem()->setText(2, text);
00451 }
00452
00453 void DoubleListViewBase::setSlaveLabels(const QStringList &text) {
00454 m_slaveList->setHeaderLabels(text);
00455 }
00456
00457 void DoubleListViewBase::calculate() {
00458 QTreeWidgetItem *lvi=0;
00459 for (int i=0; (lvi=m_masterList->topLevelItem(i)) != 0; ++i) {
00460 static_cast<DoubleListViewBase::MasterListItem *>(lvi)->calcSlaveItems();
00461 static_cast<DoubleListViewBase::MasterListItem *>(lvi)->calcTotal();
00462 }
00463 }
00464
00465 void DoubleListViewBase::clearLists() {
00466 m_slaveList->clear();
00467 m_masterList->clear();
00468 }
00469
00470 void DoubleListViewBase::setMasterFormat(int fieldwidth, char fmt, int prec) {
00471 foreach (QTreeWidgetItem *i, masterItems()) {
00472 static_cast<DoubleListViewBase::MasterListItem*>(i)->setFormat(fieldwidth, fmt, prec);
00473 }
00474 }
00475 void DoubleListViewBase::setSlaveFormat(int fieldwidth, char fmt, int prec) {
00476 foreach (QTreeWidgetItem *i, slaveItems()) {
00477 static_cast<DoubleListViewBase::SlaveListItem*>(i)->setFormat(fieldwidth, fmt, prec);
00478 }
00479 }
00480
00481 void DoubleListViewBase::setFormat(int fieldwidth, char fmt, int prec) {
00482 m_fieldwidth = fieldwidth;
00483 m_fmt = fmt;
00484 m_prec = prec;
00485 setMasterFormat(fieldwidth, fmt, prec);
00486 setSlaveFormat(fieldwidth, fmt, prec);
00487 }
00488
00489 void DoubleListViewBase::paintContents(QPainter *p) {
00490
00491 kDebug()<<k_funcinfo<<endl;
00492 #if 0
00493 QRect cm = m_masterList->contentsRect();
00494 QRect cs = m_slaveList->contentsRect();
00495 int mx, my, sx, sy;
00496 m_masterList->contentsToViewport(cm.x(), cm.y(), mx, my);
00497 m_slaveList->contentsToViewport(cs.x(), cs.y(), sx, sy);
00498 if (sizes()[0] > 0) {
00499 p->save();
00500 p->translate(mx, my);
00501 m_masterList->paintToPrinter(p, -mx, -my, cm.width(), cm.height());
00502 p->restore();
00503 }
00504 if (sizes()[1] > 0) {
00505 p->save();
00506 p->translate(cm.width() + 8 + sx, sy);
00507 m_slaveList->paintToPrinter(p, -sx, -sy, cs.width(), cs.height());
00508
00509 p->restore();
00510 }
00511 #endif
00512 }
00513
00514 }
00515
00516 #include "kptdoublelistviewbase.moc"