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