/*************************************************************************** * This file is part of the Lime Report project * * Copyright (C) 2021 by Alexander Arin * * arin_a@bk.ru * * * ** GNU General Public License Usage ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * ** GNU Lesser General Public License ** * * * This library is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public * * License along with this library. * * If not, see . * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * ****************************************************************************/ #include "lrpropertydelegate.h" #include "lrglobal.h" #include "lrobjectinspectorwidget.h" #include "lrobjectitemmodel.h" #include #include #include LimeReport::PropertyDelegate::PropertyDelegate(QObject* parent): QStyledItemDelegate(parent), m_objectInspector(NULL), m_editingItem(0), m_isEditing(false) { } void LimeReport::PropertyDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!index.isValid()) return; #if QT_VERSION >= 0x050000 QStyleOptionViewItem opt = option; #else QStyleOptionViewItemV4 opt = option; #endif QStyle* style = opt.widget ? opt.widget->style() : QApplication::style(); LimeReport::ObjectPropItem* node = qvariant_cast(index.data(Qt::UserRole)); if (node) { if (!node->isHaveValue()) { if (index.column() == 0) { StyleOptionViewItem cellOpt = option; QTreeView const* tree = dynamic_cast(cellOpt.widget); QStyleOptionViewItem primitiveOpt = cellOpt; primitiveOpt.rect.setWidth(tree->indentation()); painter->save(); painter->setPen(option.palette.color(QPalette::HighlightedText)); painter->setBackground(QBrush(option.palette.color(QPalette::Highlight))); cellOpt.widget->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &primitiveOpt, painter); cellOpt.rect.adjust(primitiveOpt.rect.width(), 0, 0, 0); cellOpt.font.setBold(true); cellOpt.palette.setColor(QPalette::Text, cellOpt.palette.color(QPalette::BrightText)); cellOpt.text = LimeReport::extractClassName(node->propertyName()); style->drawControl(QStyle::CE_ItemViewItem, &cellOpt, painter, cellOpt.widget); painter->restore(); } } else { StyleOptionViewItem so = option; if ((node->isValueReadonly()) && (!node->isHaveChildren())) { so.palette.setColor(QPalette::Text, so.palette.color(QPalette::Dark)); } QColor backgroundColor = (so.features & StyleOptionViewItem::Alternate) ? so.palette.alternateBase().color() : so.palette.base().color(); qreal luma = 0.2126 * backgroundColor.red() + 0.7152 * backgroundColor.green() + 0.0722 * backgroundColor.blue(); if (luma < 128) so.palette.setColor(QPalette::Text, Qt::white); else so.palette.setColor(QPalette::Text, Qt::black); opt.text = ""; opt.rect.setHeight(opt.rect.height() - 1); style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget); if (!node->paint(painter, so, index)) { so.state &= ~QStyle::State_HasFocus; so.rect.adjust(0, 0, 0, -1); QStyledItemDelegate::paint(painter, so, index); } if (index.column() == 0) { QPointF start(option.rect.x() + option.rect.width() - 1, option.rect.y()); QPointF end(option.rect.x() + option.rect.width() - 1, option.rect.y() + option.rect.height()); painter->save(); QColor color = static_cast( QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &option)); painter->setPen(color); painter->drawLine(start, end); painter->restore(); } } } } QSize LimeReport::PropertyDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize size = option.rect.size(); size.setHeight(option.fontMetrics.height() + QApplication::style()->pixelMetric(QStyle::PM_ButtonMargin) #ifdef Q_OS_MAC + QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin) #endif + 4); // return size; QSize defaultSize = QStyledItemDelegate::sizeHint(option, index); return size.height() > defaultSize.height() ? size : defaultSize; } QWidget* LimeReport::PropertyDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { m_editingItem = qvariant_cast(index.data(Qt::UserRole)); connect(m_editingItem, SIGNAL(destroyed(QObject*)), this, SLOT(slotItemDeleted(QObject*))); QWidget* editor = m_editingItem->createProperyEditor(parent); if (editor) { m_isEditing = true; editor->setMaximumHeight(option.rect.height() - 1); editor->setGeometry(option.rect); if (editor->metaObject()->indexOfSignal("editingFinished()") != -1) connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); connect(editor, SIGNAL(destroyed()), this, SLOT(slotEditorDeleted())); } return editor; } void LimeReport::PropertyDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { if (m_editingItem) m_editingItem->setPropertyEditorData(editor, index); } void LimeReport::PropertyDelegate::commitAndCloseEditor() { QWidget* editor = qobject_cast(sender()); emit commitData(editor); emit closeEditor(editor); } void LimeReport::PropertyDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { if (m_editingItem) m_editingItem->setModelData(editor, model, index); } void LimeReport::PropertyDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (m_editingItem) m_editingItem->updateEditorGeometry(editor, option, index); } void LimeReport::PropertyDelegate::setObjectInspector(ObjectInspectorTreeView* objectInspector) { m_objectInspector = objectInspector; } void LimeReport::PropertyDelegate::slotEditorDeleted() { m_isEditing = false; } void LimeReport::PropertyDelegate::slotItemDeleted(QObject* item) { if (item == m_editingItem) m_editingItem = 0; } LimeReport::ObjectPropItem* LimeReport::PropertyDelegate::editingItem() { return m_editingItem; }