F:/KPlato/koffice/kplato/kptdoublelistviewbase.cc

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Dag Andersen kplato@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation;
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
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     //kDebug()<<k_funcinfo<<QRect(cx, cy, cw, ch)<<endl;
00050     // draw header labels
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         //kDebug()<<s<<": "<<h->label(s)<<" "<<r<<endl;
00063         int x, y;
00064         viewportToContents(r.x(), r.y(), x, y);
00065         QRect sr(x, y, r.width(), r.height());
00066         //kDebug()<<s<<": "<<h->label(s)<<" "<<sr<<endl;
00067         if (sr.x()+sr.width() <= cx || sr.x() >= cx+cw) {
00068             //kDebug()<<s<<": "<<h->label(s)<<" "<<sr<<": continue"<<endl;
00069             continue;
00070         }
00071         QRect tr = sr;
00072         if (sr.x() < cx) {
00073             tr.setX(cx);
00074             //kDebug()<<s<<": "<<h->label(s)<<" "<<tr<<endl;
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 //    p->drawRect(r.boundingRect());
00083     p->save();
00084     p->translate(0, hei+2);
00085     r = p->clipRegion();
00086     // FIXME: Doesn't clip correctly, haven't figured out why
00087     p->setClipRegion(r.intersect(QRegion(cx, cy, cw, ch)));
00088     drawContentsOffset(p, 0, 0, cx, cy, cw, ch);
00089 //    p->drawRect(r.boundingRect());
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 //    setExpandable(master->isExpandable());
00103 //    setOpen(master->isOpen());
00104     //kDebug()<<"DoubleListViewBase::SlaveListItem "<<master->text(0)<<" parent="<<static_cast<DoubleListViewBase::SlaveListItem*>(parent)->m_masterItem->text(0)<<endl;
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 /*    setExpandable(master->isExpandable());
00115     setOpen(master->isOpen());*/
00116     //kDebug()<<"DoubleListViewBase::SlaveListItem "<<master->text(0)<<" parent="<<static_cast<DoubleListViewBase::SlaveListItem*>(parent)->m_masterItem->text(0)<<endl;
00117 }
00118 DoubleListViewBase::SlaveListItem::~SlaveListItem() {
00119     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<columnCount()<<", "<<col<<endl;
00134     setTextAlignment(col, Qt::AlignRight);
00135     setText(col, KGlobal::locale()->formatNumber(value, m_prec));
00136     m_valueMap.replace(col, value);
00137     //kDebug()<<k_funcinfo<<m_masterItem->text(0)<<": column["<<col<<"]="<<value<<endl;
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     //kDebug()<<k_funcinfo<<"c="<<column<<endl;
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     //QTreeWidgetItem::paintCell(p, g, column, width, align);
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<text(0)<<endl;
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     //setText(1, QString("%1").arg(tot, m_fieldwidth, m_fmt, m_prec));
00248     setTextAlignment(1, Qt::AlignRight);
00249     setText(1, KGlobal::locale()->formatNumber(tot, m_prec));
00250     //kDebug()<<k_funcinfo<<text(0)<<"="<<tot<<endl;
00251 }
00252 
00253 void DoubleListViewBase::MasterListItem::addToTotal(double v) {
00254     m_value += v;
00255     //setText(1, QString("%1").arg(m_value, m_fieldwidth, m_fmt, m_prec));
00256     setText(1, KGlobal::locale()->formatNumber(m_value, m_prec));
00257 }
00258 
00259 double DoubleListViewBase::MasterListItem::calcTotal() {
00260     //kDebug()<<k_funcinfo<<endl;
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     //kDebug()<<k_funcinfo<<col<<endl;
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     //kDebug()<<k_funcinfo<<text(0)<<" "<<col<<"="<<tot<<endl;
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     //kDebug()<<k_funcinfo<<"c="<<column<<" value="<<m_value<<" limit="<<m_limit<<endl;
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 //    QTreeWidgetItem::paintCell(p, g, column, width, align);
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     //kDebug()<<k_funcinfo<<minimumSizeHint()<<endl;
00396     return minimumSizeHint();  //HACK: koshell splitter problem
00397 }
00398 
00399 void DoubleListViewBase::clearSlaveList() {
00400 /*    while (m_slaveList->columnCount() > 0) {
00401         m_slaveList->removeColumn(0); // removing the last one clears the list!!!
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     //kDebug()<<k_funcinfo<<endl;
00424 //    m_masterList->setOpen(item, open);
00425 }
00426 
00427 void DoubleListViewBase::slotExpanded(QTreeWidgetItem* item) {
00428     //kDebug()<<k_funcinfo<<endl;
00429     if (item) {
00430         static_cast<DoubleListViewBase::MasterListItem*>(item)->setSlaveOpen(true);
00431     }
00432 }
00433 
00434 void DoubleListViewBase::slotCollapsed(QTreeWidgetItem*item) {
00435     //kDebug()<<k_funcinfo<<endl;
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         //p->fillRect(-8, 0, 0, sy, Qt::white);
00509         p->restore();
00510     }
00511 #endif
00512 }
00513 
00514 }  //KPlato namespace
00515 
00516 #include "kptdoublelistviewbase.moc"

Généré le Wed Nov 22 23:40:56 2006 pour KPlato par  doxygen 1.5.1-p1