X-Git-Url: https://git.quassel-irc.org/?a=blobdiff_plain;f=src%2Fcontrib%2Flibqxt-2007-10-24%2Fsrc%2Fgui%2Fqxtitemdelegate.cpp;fp=src%2Fcontrib%2Flibqxt-2007-10-24%2Fsrc%2Fgui%2Fqxtitemdelegate.cpp;h=ccb2d142d8abf45bcc1d6ba9cc103adf0e2dc22d;hb=a634acadbcf6017474f68a3eaf7cb632660e9e49;hp=0000000000000000000000000000000000000000;hpb=cd122ca8e0d2c0ffc5397e0a813c75d791a7e6e3;p=quassel.git diff --git a/src/contrib/libqxt-2007-10-24/src/gui/qxtitemdelegate.cpp b/src/contrib/libqxt-2007-10-24/src/gui/qxtitemdelegate.cpp new file mode 100644 index 00000000..ccb2d142 --- /dev/null +++ b/src/contrib/libqxt-2007-10-24/src/gui/qxtitemdelegate.cpp @@ -0,0 +1,347 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtGui module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ +#include "qxtitemdelegate.h" +#include "qxtitemdelegate_p.h" +#include +#include +#include + +static const int TOP_LEVEL_EXTENT = 2; + +QxtItemDelegatePrivate::QxtItemDelegatePrivate() : + textVisible(true), + progressFormat("%1%"), + elide(Qt::ElideMiddle), + style(Qxt::NoDecoration) +{} + +void QxtItemDelegatePrivate::paintButton(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const +{ + // draw the button + QStyleOptionButton buttonOption; + buttonOption.state = option.state; +#ifdef Q_WS_MAC + buttonOption.state |= QStyle::State_Raised; +#endif + buttonOption.state &= ~QStyle::State_HasFocus; + if (view->isExpanded(index)) + buttonOption.state |= QStyle::State_Sunken; + buttonOption.rect = option.rect; + buttonOption.palette = option.palette; + buttonOption.features = QStyleOptionButton::None; + view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view); + + // draw the branch indicator + static const int i = 9; + const QRect& r = option.rect; + if (index.model()->hasChildren(index)) + { + QStyleOption branchOption; + branchOption.initFrom(view); + if (branchOption.direction == Qt::LeftToRight) + branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i); + else + branchOption.rect = QRect(r.right() - i/2 - i, r.top() + (r.height() - i)/2, i, i); + branchOption.palette = option.palette; + branchOption.state = QStyle::State_Children; + if (view->isExpanded(index)) + branchOption.state |= QStyle::State_Open; + view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view); + } + + // draw the text + QRect textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height()); +#if QT_VERSION < 0x040200 + QString text = QItemDelegate::elidedText(option.fontMetrics, textrect.width(), elide, index.data().toString()); +#else // QT_VERSION >= 0x040200 + QString text = option.fontMetrics.elidedText(index.data().toString(), elide, textrect.width()); +#endif // QT_VERSION + view->style()->drawItemText(painter, textrect, Qt::AlignCenter, option.palette, view->isEnabled(), text); +} + +void QxtItemDelegatePrivate::paintMenu(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QTreeView* view) const +{ + // draw the menu bar item + QStyleOptionMenuItem menuOption; + menuOption.palette = view->palette(); + menuOption.fontMetrics = view->fontMetrics(); + menuOption.state = QStyle::State_None; + // QModelIndex::flags() was introduced in 4.2 + // => therefore "index.model()->flags(index)" + if (view->isEnabled() && index.model()->flags(index) & Qt::ItemIsEnabled) + menuOption.state |= QStyle::State_Enabled; + else + menuOption.palette.setCurrentColorGroup(QPalette::Disabled); + menuOption.state |= QStyle::State_Selected; + menuOption.state |= QStyle::State_Sunken; + menuOption.state |= QStyle::State_HasFocus; + menuOption.rect = option.rect; + menuOption.text = index.data().toString(); + menuOption.icon = QIcon(index.data(Qt::DecorationRole).value()); + view->style()->drawControl(QStyle::CE_MenuBarItem, &menuOption, painter, view); + + // draw the an arrow as a branch indicator + if (index.model()->hasChildren(index)) + { + QStyle::PrimitiveElement arrow; + if (view->isExpanded(index)) + arrow = QStyle::PE_IndicatorArrowUp; + else + arrow = QStyle::PE_IndicatorArrowDown; + static const int i = 9; + const QRect& r = option.rect; + menuOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i); + view->style()->drawPrimitive(arrow, &menuOption, painter, view); + } +} + +void QxtItemDelegatePrivate::paintProgress(QPainter* painter, const QStyleOptionViewItem& option, int progress) const +{ + QStyleOptionProgressBar opt; + opt.minimum = 0; + opt.maximum = 100; + opt.rect = option.rect; + opt.progress = progress; + opt.textVisible = textVisible; + opt.text = progressFormat.arg(progress); + QApplication::style()->drawControl(QStyle::CE_ProgressBar, &opt, painter, 0); +} + +void QxtItemDelegatePrivate::setCurrentEditor(QWidget* editor, const QModelIndex& index) const +{ + currentEditor = editor; + currentEdited = index; +} + +void QxtItemDelegatePrivate::closeEditor(QWidget* editor) +{ + if (currentEdited.isValid() && editor == currentEditor) + { + setCurrentEditor(0, QModelIndex()); + emit qxt_p().editingFinished(currentEdited); + } +} + +/*! + \class QxtItemDelegate QxtItemDelegate + \ingroup QxtGui + \brief An extended QItemDelegate with additional signals and optional decoration. + + QxtItemDelegate provides signals for starting and finishing of editing + and an optional decoration for top level indices in a QTreeView. + QxtItemDelegate can also draw a progress bar for indices providing + appropriate progress data. + */ + +/*! + \fn QxtItemDelegate::editingStarted(const QModelIndex& index) + + This signal is emitted after the editing of \a index has been started. + + \sa editingFinished() + */ + +/*! + \fn QxtItemDelegate::editingFinished(const QModelIndex& index) + + This signal is emitted after the editing of \a index has been finished. + + \sa editingStarted() + */ + +/*! + Constructs a new QxtItemDelegate with \a parent. + */ +QxtItemDelegate::QxtItemDelegate(QObject* parent) : QItemDelegate(parent) +{ + QXT_INIT_PRIVATE(QxtItemDelegate); + connect(this, SIGNAL(closeEditor(QWidget*)), &qxt_d(), SLOT(closeEditor(QWidget*))); +} + +/*! + Destructs the item delegate. + */ +QxtItemDelegate::~QxtItemDelegate() +{} + +/*! + \property QxtItemDelegate::decorationStyle + \brief This property holds the top level index decoration style + + Top level indices are decorated according to this property. + The default value is \b Qxt::NoDecoration. + + \note The property has effect only in case the delegate is installed + on a QTreeView. The view must be the parent of the delegate. + + \note Set \b QTreeView::rootIsDecorated to \b false to avoid + multiple branch indicators. + + \sa Qxt::DecorationStyle, QTreeView::rootIsDecorated + */ +Qxt::DecorationStyle QxtItemDelegate::decorationStyle() const +{ + return qxt_d().style; +} + +void QxtItemDelegate::setDecorationStyle(Qxt::DecorationStyle style) +{ + qxt_d().style = style; +} + +/*! + \property QxtItemDelegate::elideMode + \brief This property holds the text elide mode + + The text of a decorated top level index is elided according to this property. + The default value is \b Qt::ElideMiddle. + + \note The property has effect only for decorated top level indices. + + \sa decorationStyle, Qt::TextElideMode + */ +Qt::TextElideMode QxtItemDelegate::elideMode() const +{ + return qxt_d().elide; +} + +void QxtItemDelegate::setElideMode(Qt::TextElideMode mode) +{ + qxt_d().elide = mode; +} + +/*! + \property QxtItemDelegate::progressTextFormat + \brief This property holds the format of optional progress text + + The progress text is formatted according to this property. + The default value is \b "%1%". + + \note Progress bar is rendered for indices providing valid + numerical data for \b ProgressRole. + + \note \b \%1 is replaced by the progress percent. + + \sa progressTextVisible, ProgressRole + */ +QString QxtItemDelegate::progressTextFormat() const +{ + return qxt_d().progressFormat; +} + +void QxtItemDelegate::setProgressTextFormat(const QString& format) +{ + qxt_d().progressFormat = format; +} + +/*! + \property QxtItemDelegate::progressTextVisible + \brief This property holds whether progress text is visible + + The default value is \b true. + + \note Progress bar is rendered for indices providing valid + numerical data for \b ProgressRole. + + \sa progressTextFormat, ProgressRole + */ +bool QxtItemDelegate::isProgressTextVisible() const +{ + return qxt_d().textVisible; +} + +void QxtItemDelegate::setProgressTextVisible(bool visible) +{ + qxt_d().textVisible = visible; +} + +QWidget* QxtItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + QWidget* editor = QItemDelegate::createEditor(parent, option, index); + qxt_d().setCurrentEditor(editor, index); + emit const_cast(this)->editingStarted(index); + return editor; +} + +void QxtItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + QItemDelegate::setModelData(editor, model, index); + qxt_d().setCurrentEditor(0, QModelIndex()); + emit const_cast(this)->editingFinished(index); +} + +void QxtItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + const QAbstractItemModel* model = index.model(); + const QTreeView* tree = dynamic_cast(parent()); + const bool topLevel = !index.parent().isValid(); + + if (tree && model && topLevel && qxt_d().style != Qxt::NoDecoration) + { + QStyleOptionViewItem opt; + opt.QStyleOption::operator=(option); + opt.showDecorationSelected = false; + + QModelIndex valid = model->index(index.row(), 0); + QModelIndex sibling = valid; + while (sibling.isValid()) + { + opt.rect |= tree->visualRect(sibling); + sibling = sibling.sibling(sibling.row(), sibling.column() + 1); + } + + switch (qxt_d().style) + { + case Qxt::Buttonlike: + qxt_d().paintButton(painter, opt, valid, tree); + break; + case Qxt::Menulike: + qxt_d().paintMenu(painter, opt, valid, tree); + break; + default: + qWarning("QxtItemDelegate::paint() unknown decoration style"); + QItemDelegate::paint(painter, opt, valid); + break; + } + } + else + { + QItemDelegate::paint(painter, option, index); + + bool ok = false; + const QVariant data = index.data(ProgressRole); + const int progress = data.toInt(&ok); + if (data.isValid() && ok) + qxt_d().paintProgress(painter, option, progress); + } +} + +QSize QxtItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + // something slightly bigger for top level indices + QSize size = QItemDelegate::sizeHint(option, index); + if (!index.parent().isValid()) + size += QSize(TOP_LEVEL_EXTENT, TOP_LEVEL_EXTENT); + return size; +}