00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "editoritem.h"
00023 #include "editor.h"
00024 #include "property.h"
00025 #include "widget.h"
00026 #include "factory.h"
00027 #include "utils.h"
00028
00029 #include <qpainter.h>
00030 #include <qpixmap.h>
00031 #include <qheader.h>
00032 #include <qstyle.h>
00033 #include <qlabel.h>
00034 #include <qlayout.h>
00035
00036 #include <kdebug.h>
00037 #include <kiconloader.h>
00038 #include <kstyle.h>
00039 #include <kpopupmenu.h>
00040 #include <kapplication.h>
00041
00042 #define BRANCHBOX_SIZE 9
00043
00044 namespace KoProperty {
00045 class EditorItemPrivate
00046 {
00047 public:
00048 EditorItemPrivate()
00049 : property(0) {}
00050 ~EditorItemPrivate() {}
00051
00052 Property *property;
00053 Editor *editor;
00054 };
00055
00057 static void paintListViewExpander(QPainter* p, QWidget* w, int height, const QColorGroup& cg, bool isOpen)
00058 {
00059 const int marg = (height -2 - BRANCHBOX_SIZE) / 2;
00060 int xmarg = marg;
00061
00062
00063 #if 0
00065 KStyle* kstyle = dynamic_cast<KStyle*>(widget->style());
00066 if (kstyle) {
00067 kstyle->drawKStylePrimitive(
00068 KStyle::KPE_ListViewExpander, p, w, QRect( xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE ),
00069 cg, isOpen ? 0 : QStyle::Style_On,
00070 QStyleOption::Default);
00071 }
00072 else {
00073 #endif
00074 Q_UNUSED(w);
00075
00076 p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR );
00077 p->drawRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE);
00078 p->fillRect(xmarg+1, marg + 1, BRANCHBOX_SIZE-2, BRANCHBOX_SIZE-2,
00079
00080 cg.base());
00081
00082 p->setPen( cg.foreground() );
00083 p->drawLine(xmarg+2, marg+BRANCHBOX_SIZE/2, xmarg+BRANCHBOX_SIZE-3, marg+BRANCHBOX_SIZE/2);
00084 if(!isOpen) {
00085 p->drawLine(xmarg+BRANCHBOX_SIZE/2, marg+2,
00086 xmarg+BRANCHBOX_SIZE/2, marg+BRANCHBOX_SIZE-3);
00087 }
00088
00089 }
00090
00093 class GroupWidgetBase : public QWidget
00094 {
00095 public:
00096 GroupWidgetBase(QWidget* parent)
00097 : QWidget(parent)
00098 , m_isOpen(true)
00099 , m_mouseDown(false)
00100 {
00101 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, 0, 1));
00102 }
00103
00104 void setText( const QString &text )
00105 {
00106 m_titleStr = text;
00107 }
00108
00109 void setIcon( const QPixmap &pix )
00110 {
00111 m_miniicon = pix;
00112 }
00113
00114 virtual bool isOpen() const
00115 {
00116 return m_isOpen;
00117 }
00118
00119 virtual void setOpen(bool set)
00120 {
00121 m_isOpen = set;
00122 }
00123
00124 virtual QSize sizeHint () const
00125 {
00126 QSize s( QWidget::sizeHint() );
00127 s.setHeight(fontMetrics().height()*2);
00128 return s;
00129 }
00130
00131 protected:
00132 virtual void paintEvent(QPaintEvent *) {
00133 QRect r(rect());
00134 QPainter p(this);
00135 QStyle::StyleFlags flags = m_mouseDown ? QStyle::Style_Down : QStyle::Style_Default;
00136 kapp->style().drawPrimitive(QStyle::PE_HeaderSection, &p, r, palette().active(), flags);
00137
00138 paintListViewExpander(&p, this, r.height()+2, palette().active(), isOpen());
00139 if (!m_miniicon.isNull()) {
00140 p.drawPixmap(24, (r.height()-m_miniicon.height())/2, m_miniicon);
00141 }
00142
00143 if (!m_titleStr.isNull())
00144 {
00145 int indent = 16 + (m_miniicon.isNull() ? 0 : (m_miniicon.width()+4));
00146 p.setPen(palette().active().text());
00147 QFont f = p.font();
00148 f.setBold(true);
00149 p.setFont(f);
00150 p.drawText(indent+8, 0, width()-(indent+8),
00151 height(), AlignLeft | AlignVCenter | SingleLine,
00152 m_titleStr);
00153 }
00154
00155
00156 }
00157
00158 virtual bool event( QEvent * e ) {
00159 if (e->type()==QEvent::MouseButtonPress || e->type()==QEvent::MouseButtonRelease) {
00160 QMouseEvent* me = static_cast<QMouseEvent*>(e);
00161 if (me->button() == Qt::LeftButton) {
00162 m_mouseDown = e->type()==QEvent::MouseButtonPress;
00163 update();
00164 }
00165 }
00166 return QWidget::event(e);
00167 }
00168
00169 protected:
00170 QString m_titleStr;
00171 QPixmap m_miniicon;
00172 bool m_isOpen : 1;
00173 bool m_mouseDown : 1;
00174 };
00175
00176 class GroupWidget : public GroupWidgetBase
00177 {
00178 public:
00179 GroupWidget(EditorGroupItem *parentItem)
00180 : GroupWidgetBase(parentItem->listView()->viewport())
00181 , m_parentItem(parentItem)
00182 {
00183 }
00184
00185 virtual bool isOpen() const
00186 {
00187 return m_parentItem->isOpen();
00188 }
00189
00190 protected:
00191 EditorGroupItem *m_parentItem;
00192 };
00193
00194 class GroupContainer::Private
00195 {
00196 public:
00197 Private() {}
00198 QVBoxLayout* lyr;
00199 GroupWidgetBase *groupWidget;
00200 QGuardedPtr<QWidget> contents;
00201 };
00202
00203 }
00204
00205 using namespace KoProperty;
00206
00207 GroupContainer::GroupContainer(const QString& title, QWidget* parent)
00208 : QWidget(parent)
00209 , d(new Private())
00210 {
00211 setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, 0, 1));
00212 d->lyr = new QVBoxLayout(this);
00213 d->groupWidget = new GroupWidgetBase(this);
00214 d->groupWidget->setText( title );
00215 d->lyr->addWidget(d->groupWidget);
00216 d->lyr->addSpacing(4);
00217 }
00218
00219 GroupContainer::~GroupContainer()
00220 {
00221 delete d;
00222 }
00223
00224 void GroupContainer::setContents( QWidget* contents )
00225 {
00226 if (d->contents) {
00227 d->contents->hide();
00228 d->lyr->remove(d->contents);
00229 delete d->contents;
00230 }
00231 d->contents = contents;
00232 if (d->contents) {
00233 d->lyr->addWidget(d->contents);
00234 d->contents->show();
00235 }
00236 update();
00237 }
00238
00239 bool GroupContainer::event( QEvent * e ) {
00240 if (e->type()==QEvent::MouseButtonPress) {
00241 QMouseEvent* me = static_cast<QMouseEvent*>(e);
00242 if (me->button() == Qt::LeftButton && d->contents && d->groupWidget->rect().contains(me->pos())) {
00243 d->groupWidget->setOpen(!d->groupWidget->isOpen());
00244 if (d->groupWidget->isOpen())
00245 d->contents->show();
00246 else
00247 d->contents->hide();
00248 d->lyr->invalidate();
00249 update();
00250 }
00251 }
00252 return QWidget::event(e);
00253 }
00254
00256
00257 EditorItem::EditorItem(Editor *editor, EditorItem *parent, Property *property, QListViewItem *after)
00258 : KListViewItem(parent, after,
00259 property->captionForDisplaying().isEmpty() ? property->name() : property->captionForDisplaying())
00260 {
00261 d = new EditorItemPrivate();
00262 d->property = property;
00263 d->editor = editor;
00264
00265 setMultiLinesEnabled(true);
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 }
00282
00283 EditorItem::EditorItem(KListView *parent)
00284 : KListViewItem(parent)
00285 {
00286 d = new EditorItemPrivate();
00287 d->property = 0;
00288 d->editor = 0;
00289 setMultiLinesEnabled(true);
00290 }
00291
00292 EditorItem::EditorItem(EditorItem *parent, const QString &text)
00293 : KListViewItem(parent, text)
00294 {
00295 d = new EditorItemPrivate();
00296 d->property = 0;
00297 d->editor = 0;
00298 setMultiLinesEnabled(true);
00299 }
00300
00301 EditorItem::EditorItem(EditorItem *parent, EditorItem *after, const QString &text)
00302 : KListViewItem(parent, after, text)
00303 {
00304 d = new EditorItemPrivate();
00305 d->property = 0;
00306 d->editor = 0;
00307 setMultiLinesEnabled(true);
00308 }
00309
00310 EditorItem::~EditorItem()
00311 {
00312 delete d;
00313 }
00314
00315 Property*
00316 EditorItem::property()
00317 {
00318 return d->property;
00319 }
00320
00321 void
00322 EditorItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align)
00323 {
00324
00325 if(!d->property)
00326 return;
00327
00328 if(column == 0)
00329 {
00330 QFont font = listView()->font();
00331 if(d->property->isModified())
00332 font.setBold(true);
00333 p->setFont(font);
00334 p->setBrush(cg.highlight());
00335 p->setPen(cg.highlightedText());
00336 KListViewItem::paintCell(p, cg, column, width, align);
00337 p->fillRect(parent() ? 0 : 50, 0, width, height()-1,
00338 QBrush(isSelected() ? cg.highlight() : backgroundColor()));
00339 p->setPen(isSelected() ? cg.highlightedText() : cg.text());
00340 int delta = -20+KPROPEDITOR_ITEM_MARGIN;
00341 if ((firstChild() && dynamic_cast<EditorGroupItem*>(parent()))) {
00342 delta = -KPROPEDITOR_ITEM_MARGIN-1;
00343 }
00344 if (dynamic_cast<EditorDummyItem*>(parent())) {
00345 delta = KPROPEDITOR_ITEM_MARGIN*2;
00346 }
00347 else if (parent() && dynamic_cast<EditorDummyItem*>(parent()->parent())) {
00348 if (dynamic_cast<EditorGroupItem*>(parent()))
00349 delta += KPROPEDITOR_ITEM_MARGIN*2;
00350 else
00351 delta += KPROPEDITOR_ITEM_MARGIN*5;
00352 }
00353 p->drawText(
00354 QRect(delta,2, width+listView()->columnWidth(1)-KPROPEDITOR_ITEM_MARGIN*2, height()),
00355 Qt::AlignLeft | Qt::AlignTop , text(0));
00356
00357 p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR );
00358 p->drawLine(width-1, 0, width-1, height()-1);
00359 p->drawLine(0, -1, width-1, -1);
00360
00361 p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR );
00362 if (dynamic_cast<EditorDummyItem*>(parent()))
00363 p->drawLine(0, 0, 0, height()-1 );
00364 }
00365 else if(column == 1)
00366 {
00367 QColorGroup icg(cg);
00368 icg.setColor(QColorGroup::Background, backgroundColor());
00369 p->setBackgroundColor(backgroundColor());
00370 Widget *widget = d->editor->createWidgetForProperty(d->property, false );
00371 if(widget) {
00372 QRect r(0, 0, d->editor->header()->sectionSize(1), height() - (widget->hasBorders() ? 0 : 1));
00373 p->setClipRect(r, QPainter::CoordPainter);
00374 p->setClipping(true);
00375 widget->drawViewer(p, icg, r, d->property->value());
00376 p->setClipping(false);
00377 }
00378 }
00379 p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR );
00380 p->drawLine(0, height()-1, width, height()-1 );
00381 }
00382
00383 void
00384 EditorItem::paintBranches(QPainter *p, const QColorGroup &cg, int w, int y, int h)
00385 {
00386 p->eraseRect(0,0,w,h);
00387 KListViewItem *item = static_cast<KListViewItem*>(firstChild());
00388 if(!item)
00389 return;
00390
00391 QColor backgroundColor;
00392 p->save();
00393 p->translate(0,y);
00394 QFont font = listView()->font();
00395 while(item)
00396 {
00397 if(item->isSelected())
00398 backgroundColor = cg.highlight();
00399 else {
00400 if (dynamic_cast<EditorGroupItem*>(item))
00401 backgroundColor = cg.base();
00402 else
00403 backgroundColor = item->backgroundColor();
00404 }
00405
00406 p->save();
00407 p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR );
00408 int delta = 0;
00409 int fillWidth = w;
00410 int x = 0;
00411 if (dynamic_cast<EditorGroupItem*>(item->parent())) {
00412 delta = 0;
00413 fillWidth += 19;
00414 }
00415 else {
00416 if (dynamic_cast<EditorGroupItem*>(item) || dynamic_cast<EditorDummyItem*>(item->parent()))
00417 x = 19;
00418 else
00419 x = -19;
00420 fillWidth += 19;
00421 }
00422 if (dynamic_cast<EditorDummyItem*>(item->parent())) {
00423 x = 19;
00424 }
00425 else if (item->parent() && dynamic_cast<EditorDummyItem*>(item->parent()->parent())) {
00426 x = 0;
00427 }
00428 p->fillRect(x+1, 0, fillWidth-1, item->height()-1, QBrush(backgroundColor));
00429 p->drawLine(x, item->height()-1, w, item->height()-1 );
00430 if (!dynamic_cast<EditorGroupItem*>(item))
00431 p->drawLine(x, 0, x, item->height()-1 );
00432 p->restore();
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 font.setBold( dynamic_cast<EditorGroupItem*>(item)
00443 || (static_cast<EditorItem*>(item)->property() && static_cast<EditorItem*>(item)->property()->isModified()) );
00444 p->setFont(font);
00445 p->setPen(item->isSelected() ? cg.highlightedText() : cg.text());
00446 if (item->firstChild() && dynamic_cast<EditorGroupItem*>(item->parent())) {
00447 delta = 19-KPROPEDITOR_ITEM_MARGIN-1;
00448 }
00449 else if (dynamic_cast<EditorDummyItem*>(item->parent())) {
00450 delta = 19;
00451 }
00452 if (item->parent() && dynamic_cast<EditorDummyItem*>(item->parent()->parent())) {
00453 if (dynamic_cast<EditorGroupItem*>(item->parent()))
00454 delta += KPROPEDITOR_ITEM_MARGIN*2;
00455 else
00456 delta += KPROPEDITOR_ITEM_MARGIN*5;
00457 }
00458
00459 if (!dynamic_cast<EditorDummyItem*>(item->parent()))
00460 p->drawText(QRect(delta+1,0, w+listView()->columnWidth(1), item->height()),
00461 Qt::AlignLeft | Qt::AlignVCenter , item->text(0));
00462
00463 if(item->firstChild()) {
00464 paintListViewExpander(p, listView(), item->height(),
00465 cg, item->isOpen());
00466 }
00467
00468
00469 EditorItem *editorItem = dynamic_cast<EditorItem*>(item);
00470 if (editorItem && editorItem->property() && !editorItem->property()->icon().isEmpty()) {
00471
00472 QPixmap pix = SmallIcon(editorItem->property()->icon());
00473 if (!pix.isNull())
00474 p->drawPixmap(-19+(19-pix.width())/2, (item->height() - pix.height()) / 2, pix);
00475 }
00476
00477 p->translate(0, item->totalHeight());
00478 item = (KListViewItem*)item->nextSibling();
00479 }
00480 p->restore();
00481 }
00482
00483 void
00484 EditorItem::paintFocus(QPainter *, const QColorGroup &, const QRect & )
00485 {
00486 }
00487
00488 int
00489 EditorItem::compare( QListViewItem *i, int col, bool ascending ) const
00490 {
00491 if (!ascending)
00492 return -QListViewItem::key( col, ascending ).localeAwareCompare( i->key( col, ascending ) );
00493
00494 if (d->property) {
00495
00496
00497
00498 return d->property->sortingKey()
00499 - ((dynamic_cast<EditorItem*>(i) && dynamic_cast<EditorItem*>(i)->property())
00500 ? dynamic_cast<EditorItem*>(i)->property()->sortingKey() : 0);
00501 }
00502
00503 return 0;
00504
00505 }
00506
00507 void
00508 EditorItem::setHeight( int height )
00509 {
00510 KListViewItem::setHeight(height);
00511 }
00512
00514
00515 EditorGroupItem::EditorGroupItem(EditorItem *parent, EditorItem *after, const QString &text, const QString &icon, int sortOrder)
00516 : EditorItem(parent, after, text)
00517 , m_label(0)
00518 , m_sortOrder(sortOrder)
00519 {
00520 init(icon);
00521 }
00522
00523 EditorGroupItem::EditorGroupItem(EditorItem *parent, const QString &text, const QString &icon, int sortOrder)
00524 : EditorItem(parent, text)
00525 , m_label(0)
00526 , m_sortOrder(sortOrder)
00527 {
00528 init(icon);
00529 }
00530
00531 EditorGroupItem::~EditorGroupItem()
00532 {
00533 delete m_label;
00534 }
00535
00536 QWidget* EditorGroupItem::label() const
00537 {
00538 return m_label;
00539 }
00540
00541 void EditorGroupItem::init(const QString &icon)
00542 {
00543 setOpen(true);
00544 setSelectable(false);
00545 m_label = new GroupWidget(this);
00546 m_label->setText(text(0));
00547 if (!icon.isEmpty())
00548 m_label->setIcon( SmallIcon(icon) );
00549 m_label->show();
00550 }
00551
00552 void
00553 EditorGroupItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int )
00554 {
00555 Q_UNUSED(p);
00556 Q_UNUSED(cg);
00557 Q_UNUSED(column);
00558 Q_UNUSED(width);
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 }
00583
00584 void
00585 EditorGroupItem::setup()
00586 {
00587 KListViewItem::setup();
00588 setHeight( height()+4 );
00589 }
00590
00591 int
00592 EditorGroupItem::compare( QListViewItem *i, int col, bool ascending ) const
00593 {
00594 Q_UNUSED(col);
00595 Q_UNUSED(ascending);
00596 if (dynamic_cast<EditorGroupItem*>(i)) {
00597 return m_sortOrder
00598 - dynamic_cast<EditorGroupItem*>(i)->m_sortOrder;
00599 }
00600 return 0;
00601 }
00602
00604
00605 EditorDummyItem::EditorDummyItem(KListView *listview)
00606 : EditorItem(listview)
00607 {
00608 setSelectable(false);
00609 setOpen(true);
00610 }
00611
00612 EditorDummyItem::~EditorDummyItem()
00613 {}
00614
00615 void
00616 EditorDummyItem::setup()
00617 {
00618 setHeight(0);
00619 }