kpilot

listCat.cc

Go to the documentation of this file.
00001 /* KPilot
00002 **
00003 ** Copyright (C) 2000-2001 by Adriaan de Groot
00004 **
00005 ** This file defines a specialization of KListView that can
00006 ** be used to sort some fixed set of object into some fixed
00007 ** set of categories.
00008 */
00009 
00010 /*
00011 ** This program is free software; you can redistribute it and/or modify
00012 ** it under the terms of the GNU General Public License as published by
00013 ** the Free Software Foundation; either version 2 of the License, or
00014 ** (at your option) any later version.
00015 **
00016 ** This program is distributed in the hope that it will be useful,
00017 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 ** GNU General Public License for more details.
00020 **
00021 ** You should have received a copy of the GNU General Public License
00022 ** along with this program in a file called COPYING; if not, write to
00023 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00024 ** MA 02110-1301, USA.
00025 */
00026 
00027 /*
00028 ** Bug reports and questions can be sent to kde-pim@kde.org
00029 */
00030 
00031 #include "options.h"
00032 
00033 #include <qpainter.h>
00034 #include <klocale.h>
00035 
00036 #include "listCat.moc"
00037 
00038 
00039 ListCategorizer::ListCategorizer(QWidget * parent,
00040     const char *name) :
00041     KListView(parent, name), 
00042     fStartOpen(false)
00043 {
00044     FUNCTIONSETUP;
00045     setupWidget();
00046 }
00047 
00048 ListCategorizer::ListCategorizer(const QStringList & i,
00049     bool startOpen,
00050     QWidget * parent,
00051     const char *name) :
00052     KListView(parent, name), 
00053     fStartOpen(startOpen)
00054 {
00055     FUNCTIONSETUP;
00056     addCategories(i);
00057 }
00058 
00059 void ListCategorizer::addCategories(const QStringList & l)
00060 {
00061     FUNCTIONSETUP;
00062     QStringList::ConstIterator i;
00063 
00064     for (i = l.begin(); i != l.end(); ++i)
00065     {
00066         (void) addCategory(*i);
00067     }
00068 }
00069 
00070 QListViewItem *ListCategorizer::addCategory(const QString & name,
00071     const QString & desc)
00072 {
00073     FUNCTIONSETUP;
00074     QListViewItem *m = new QListViewItem(this, name, desc);
00075 
00076     m->setSelectable(false);
00077     m->setOpen(fStartOpen);
00078     return m;
00079 }
00080 
00081 void ListCategorizer::setupWidget()
00082 {
00083     FUNCTIONSETUP;
00084     addColumn(i18n("Category"));
00085     addColumn(i18n("Description"));
00086     setItemsMovable(false);
00087     setDragEnabled(true);
00088     setAcceptDrops(true);
00089     setDropVisualizer(true);
00090     setRootIsDecorated(true);
00091 }
00092 
00093 /* virtual */ bool ListCategorizer::acceptDrag(QDropEvent * event) const
00094 {
00095     FUNCTIONSETUP;
00096     if (!(event->source()))
00097         return false;
00098     QListViewItem *p = itemAt(event->pos());
00099 
00100     if (!p)
00101         return false;
00102 
00103     return true;
00104 }
00105 
00106 /* virtual */ void ListCategorizer::contentsDropEvent(QDropEvent * e)
00107 {
00108     FUNCTIONSETUP;
00109     cleanDropVisualizer();
00110 
00111     if (!acceptDrag(e))
00112         return;
00113     e->accept();
00114 
00115     QListViewItem *p = itemAt(e->pos());
00116     QListViewItem *selection = currentItem();
00117 
00118     if (!p)
00119     {
00120         WARNINGKPILOT << "Drop without a category!" << endl;
00121         return;
00122     }
00123 
00124     QListViewItem *category = p->parent();
00125 
00126     if (!category)
00127     {
00128         category = p;
00129     }
00130 
00131     moveItem(selection, category, 0L);
00132 }
00133 
00134 /* virtual */ void ListCategorizer::startDrag()
00135 {
00136     FUNCTIONSETUP;
00137     QListViewItem *p = currentItem();
00138 
00139     if (!p || !p->parent())
00140         return;
00141 
00142     KListView::startDrag();
00143 }
00144 
00145 QStringList ListCategorizer::listSiblings(const QListViewItem * p, int column) const
00146 {
00147     FUNCTIONSETUP;
00148     QStringList l;
00149 
00150     while (p)
00151     {
00152         l.append(p->text(column));
00153         p = p->nextSibling();
00154     }
00155 
00156     return l;
00157 }
00158 
00159 QListViewItem *ListCategorizer::findCategory(const QString & category) const
00160 {
00161     FUNCTIONSETUP;
00162     QListViewItem *p = firstChild();
00163 
00164     while (p)
00165     {
00166         if (p->text(0) == category)
00167             return p;
00168         p = p->nextSibling();
00169     }
00170 
00171     return 0L;
00172 }
00173 
00174 QListViewItem *ListCategorizer::addItem(const QString & category,
00175     const QString & name, const QString & description)
00176 {
00177     FUNCTIONSETUP;
00178     QListViewItem *p = findCategory(category);
00179 
00180     if (!p)
00181         return 0L;
00182 
00183     return new QListViewItem(p, name, description);
00184 }
00185 
00186 #define RVPAD   (4)
00187 
00188 RichListViewItem::RichListViewItem(QListViewItem *p,
00189     QString l,
00190     int c) :
00191     QListViewItem(p,l)
00192 {
00193     FUNCTIONSETUP;
00194 
00195     fColumns=c;
00196     fIsRich = new bool[c];
00197     fRect = new QRect[c];
00198 
00199     for (int i=0; i<c; i++)
00200     {
00201         fIsRich[i]=false;
00202     }
00203 }
00204 
00205 RichListViewItem::~RichListViewItem()
00206 {
00207     FUNCTIONSETUP;
00208 
00209     delete[] fIsRich;
00210     delete[] fRect;
00211 }
00212 
00213 void RichListViewItem::computeHeight(int c)
00214 {
00215     FUNCTIONSETUP;
00216 
00217     if (!fIsRich[c]) return;
00218 
00219     QListView *v = listView();
00220     
00221     fRect[c] = v->fontMetrics().boundingRect(v->itemMargin()+RVPAD,0+RVPAD,
00222         v->columnWidth(c)-v->itemMargin()-RVPAD,300,
00223         AlignLeft | AlignTop | WordBreak,
00224         text(c));
00225 }
00226 
00227 
00228 /* virtual */ void RichListViewItem::setup()
00229 {
00230     FUNCTIONSETUP;
00231 
00232     QListViewItem::setup();
00233 
00234     int h = height();
00235 
00236     for (int i=0; i<fColumns; i++)
00237     {
00238         computeHeight(i);
00239         h = kMax(h,fRect[i].height()+2*RVPAD);
00240     }
00241 
00242     setHeight(h);
00243 }
00244 
00245 
00246 /* virtual */ void RichListViewItem::paintCell(QPainter *p,
00247     const QColorGroup &gc,
00248     int column,
00249     int width,
00250     int alignment)
00251 {
00252     FUNCTIONSETUP;
00253 
00254     if ((!column) || (!fIsRich[column]))
00255     {
00256         QListViewItem::paintCell(p,gc,column,width,alignment);
00257         return;
00258     }
00259 
00260     QListView *v = listView();
00261 
00262     p->eraseRect(0,0,width,height());
00263     p->setBackgroundColor(gc.background());
00264     p->eraseRect(RVPAD,RVPAD,width-RVPAD,height()-RVPAD);
00265     p->setPen(gc.text());
00266     p->drawText(v->itemMargin()+RVPAD,0+RVPAD,
00267         width-v->itemMargin()-RVPAD,height()-RVPAD,
00268         AlignTop | AlignLeft | WordBreak,
00269         text(column),
00270         -1,
00271         &fRect[column]);
00272 }