+++ /dev/null
-/****************************************************************************
-**
-** 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.
-**
-** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
-**
-****************************************************************************/
-#include "qxtitemdelegate.h"
-#include "qxtitemdelegate_p.h"
-#include <QApplication>
-#include <QTreeView>
-#include <QPainter>
-
-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<QPixmap>());
- 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<QxtItemDelegate*>(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<QxtItemDelegate*>(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<QTreeView*>(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;
-}