0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-25 00:54:39 +03:00
LimeReport/limereport/objectinspector/lrobjectitemmodel.cpp

518 lines
16 KiB
C++
Raw Normal View History

2016-02-17 10:11:00 +03:00
/***************************************************************************
* This file is part of the Lime Report project *
2021-08-18 20:21:36 +03:00
* Copyright (C) 2021 by Alexander Arin *
2016-02-17 10:11:00 +03:00
* 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 <http://www.gnu.org/licenses/>. *
* *
** 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 <http://www.gnu.org/licenses/>. *
* *
* 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 "lrobjectitemmodel.h"
2016-02-17 10:11:00 +03:00
#include <QDebug>
#include <QMessageBox>
#include <QMetaProperty>
#include <QPainter>
2016-02-17 10:11:00 +03:00
namespace LimeReport {
2016-02-17 10:28:27 +03:00
void QObjectPropertyModel::translatePropertyName()
{
tr("leftMargin");
tr("rightMargin");
tr("topMargin");
tr("bottomMargin");
tr("objectName");
tr("borders");
tr("geometry");
tr("itemAlign");
tr("pageOrientation");
tr("pageSize");
tr("TopLine");
tr("BottomLine");
tr("LeftLine");
tr("RightLine");
2016-02-17 10:39:17 +03:00
tr("reprintOnEachPage");
tr("borderLineSize");
tr("autoHeight");
tr("backgroundColor");
tr("columnCount");
tr("columnsFillDirection");
tr("datasource");
tr("keepBottomSpace");
tr("keepFooterTogether");
tr("keepSubdetailTogether");
tr("printIfEmpty");
tr("sliceLastRow");
tr("splittable");
tr("alignment");
tr("angle");
tr("autoWidth");
tr("backgroundMode");
tr("backgroundOpacity");
tr("content");
tr("font");
tr("fontColor");
tr("foregroundOpacity");
tr("itemLocation");
tr("margin");
tr("stretchToMaxHeight");
tr("trimValue");
tr("lineWidth");
tr("opacity");
tr("penStyle");
tr("shape");
tr("shapeBrush");
tr("shapeBrushColor");
tr("gridStep");
tr("fullPage");
tr("oldPrintMode");
tr("borderColor");
tr("resetPageNumber");
tr("alternateBackgroundColor");
tr("backgroundBrushStyle");
tr("columnCount");
tr("startFromNewPage");
tr("startNewPage");
tr("adaptFontToSize");
tr("allowHTML");
tr("allowHTMLInFields");
tr("backgroundBrushStyle");
tr("followTo");
tr("format");
tr("lineSpacing");
tr("textIndent");
tr("textLayoutDirection");
tr("underlineLineSize");
tr("underlines");
tr("valueType");
tr("securityLevel");
tr("testValue");
tr("whitespace");
tr("resourcePath");
tr("scale");
tr("cornerRadius");
tr("shapeColor");
tr("layoutType");
tr("barcodeType");
tr("barcodeWidth");
tr("foregroundColor");
tr("inputMode");
tr("pdf417CodeWords");
tr("autoSize");
tr("center");
tr("field");
tr("image");
tr("keepAspectRatio");
tr("columnsCount");
2017-06-29 00:55:16 +03:00
tr("useAlternateBackgroundColor");
tr("printBeforePageHeader");
tr("maxScalePercent");
tr("printOnFirstPage");
tr("printOnLastPage");
tr("printAlways");
tr("repeatOnEachRow");
tr("condition");
tr("groupFieldName");
tr("keepGroupTogether");
2017-12-11 00:29:36 +03:00
tr("endlessHeight");
tr("extendedHeight");
tr("isExtendedInDesignMode");
tr("pageIsTOC");
tr("setPageSizeToPrinter");
tr("fillInSecondPass");
tr("chartTitle");
tr("chartType");
tr("drawLegendBorder");
tr("labelsField");
2022-01-25 21:13:00 +03:00
tr("xAxisField");
2017-12-11 00:29:36 +03:00
tr("legendAlign");
tr("series");
tr("titleAlign");
2018-03-22 20:36:14 +03:00
tr("watermark");
2018-04-04 00:42:46 +03:00
tr("keepTopSpace");
2018-05-24 01:41:45 +03:00
tr("printable");
2018-05-24 14:31:10 +03:00
tr("variable");
tr("replaceCRwithBR");
2018-06-21 14:29:00 +03:00
tr("hideIfEmpty");
tr("hideEmptyItems");
2021-01-21 23:50:39 +03:00
tr("useExternalPainter");
2019-02-06 19:09:32 +03:00
tr("layoutSpacing");
tr("printerName");
tr("fontLetterSpacing");
2019-05-23 11:52:31 +03:00
tr("hideText");
tr("option3");
tr("units");
tr("geometryLocked");
tr("printBehavior");
2019-10-17 00:11:27 +03:00
tr("shiftItems");
tr("showLegend");
tr("seriesLineWidth");
tr("drawPoints");
tr("removeGap");
2021-01-21 23:50:39 +03:00
tr("dropPrinterMargins");
tr("notPrintIfEmpty");
2022-01-27 21:57:53 +03:00
tr("gridChartLines");
tr("horizontalAxisOnTop");
tr("mixWithPriorPage");
2023-08-16 14:15:01 +03:00
tr("shadow");
tr("borderStyle");
2016-02-17 10:28:27 +03:00
}
void QObjectPropertyModel::clearObjectsList() { m_objects.clear(); }
2016-02-17 10:11:00 +03:00
QObjectPropertyModel::QObjectPropertyModel(QObject* parent /*=0*/):
QAbstractItemModel(parent),
m_rootNode(0),
m_object(0),
m_dataChanging(false),
m_subclassesAsLevel(true),
m_validator(0),
m_translateProperties(true)
2016-02-17 10:11:00 +03:00
{
}
QObjectPropertyModel::~QObjectPropertyModel() { delete m_rootNode; }
2016-02-17 10:11:00 +03:00
void QObjectPropertyModel::initModel()
{
beginResetModel();
delete m_rootNode;
m_rootNode = 0;
2016-02-17 10:11:00 +03:00
if (m_object) {
connect(m_object, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)));
m_rootNode = new ObjectPropItem(0, 0, "root", "root", QVariant(), 0);
2016-02-17 10:11:00 +03:00
m_rootNode->setModel(this);
foreach (QObject* item, m_objects)
connect(item, SIGNAL(destroyed(QObject*)), this, SLOT(slotObjectDestroyed(QObject*)));
2016-02-17 10:11:00 +03:00
addObjectProperties(m_object->metaObject(), m_object, &m_objects);
}
endResetModel();
}
void QObjectPropertyModel::setObject(QObject* object)
2016-02-17 10:11:00 +03:00
{
m_objects.clear();
if (m_object != object) {
2016-02-17 10:11:00 +03:00
submit();
m_object = object;
2016-02-17 10:11:00 +03:00
initModel();
}
}
void QObjectPropertyModel::setMultiObjects(QList<QObject*>* list)
2016-02-17 10:11:00 +03:00
{
m_objects.clear();
submit();
2016-02-17 10:39:17 +03:00
2022-01-31 19:56:59 +03:00
if (list->isEmpty()) {
return;
}
if (!list->contains(m_object)) {
m_object = list->at(0);
2016-02-17 10:11:00 +03:00
list->removeAt(0);
2016-02-17 10:39:17 +03:00
} else {
list->removeOne(m_object);
2016-02-17 10:11:00 +03:00
}
2016-02-17 10:39:17 +03:00
foreach (QObject* item, *list)
2016-02-17 10:18:19 +03:00
m_objects.append(item);
// initModel();
2016-02-17 10:11:00 +03:00
}
void QObjectPropertyModel::slotObjectDestroyed(QObject* obj)
2016-02-17 10:11:00 +03:00
{
m_objects.removeOne(obj);
if (m_object == obj) {
m_object = 0;
initModel();
2016-02-17 10:11:00 +03:00
}
}
void QObjectPropertyModel::slotPropertyChanged(const QString& propertyName,
const QVariant& oldValue, const QVariant& newValue)
2016-02-17 10:11:00 +03:00
{
Q_UNUSED(oldValue);
Q_UNUSED(newValue);
if (m_object)
updateProperty(propertyName);
}
void QObjectPropertyModel::slotPropertyObjectNameChanged(const QString& oldName,
const QString& newName)
2016-02-17 10:11:00 +03:00
{
Q_UNUSED(oldName)
Q_UNUSED(newName)
if (m_object)
updateProperty("objectName");
}
int QObjectPropertyModel::columnCount(const QModelIndex& /*parent*/) const { return 2; }
2016-02-17 10:11:00 +03:00
QVariant QObjectPropertyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
if (section == 0)
return tr("Property Name");
else
return tr("Property value");
} else
return QVariant();
2016-02-17 10:11:00 +03:00
}
ObjectPropItem* QObjectPropertyModel::nodeFromIndex(const QModelIndex& index) const
2016-02-17 10:11:00 +03:00
{
if (index.isValid()) {
2016-02-17 10:11:00 +03:00
return static_cast<ObjectPropItem*>(index.internalPointer());
} else
return m_rootNode;
2016-02-17 10:11:00 +03:00
}
void QObjectPropertyModel::updateProperty(const QString& propertyName)
2016-02-17 10:11:00 +03:00
{
if (!m_dataChanging && m_rootNode) {
2016-02-17 10:11:00 +03:00
ObjectPropItem* propItem = m_rootNode->findPropertyItem(propertyName);
if (propItem)
propItem->updatePropertyValue();
2016-02-17 10:11:00 +03:00
}
}
void QObjectPropertyModel::setSubclassesAsLevel(bool value) { m_subclassesAsLevel = value; }
2016-02-17 10:11:00 +03:00
int QObjectPropertyModel::rowCount(const QModelIndex& parent) const
2016-02-17 10:11:00 +03:00
{
if (!m_rootNode)
return 0;
ObjectPropItem* parentNode;
2016-02-17 10:11:00 +03:00
if (parent.isValid())
parentNode = nodeFromIndex(parent);
else
parentNode = m_rootNode;
return parentNode->childCount();
}
QVariant QObjectPropertyModel::data(const QModelIndex& index, int role) const
2016-02-17 10:11:00 +03:00
{
ObjectPropItem* node = nodeFromIndex(index);
2016-02-17 10:11:00 +03:00
switch (role) {
case Qt::DisplayRole:
if (!node)
return QVariant();
node->setTranslateProperty(isTranslateProperties());
if (index.column() == 0) {
2016-02-17 10:11:00 +03:00
return node->displayName();
} else {
return node->displayValue();
}
case Qt::DecorationRole:
if (!node)
return QIcon();
if (index.column() == 1) {
2016-02-17 10:11:00 +03:00
return node->iconValue();
} else
return QIcon();
2019-02-14 00:21:57 +03:00
case Qt::UserRole:
return QVariant::fromValue(node);
2016-02-17 10:11:00 +03:00
default:
return QVariant();
}
}
QModelIndex QObjectPropertyModel::index(int row, int column, const QModelIndex& parent) const
2016-02-17 10:11:00 +03:00
{
if (!m_rootNode)
2016-02-17 10:11:00 +03:00
return QModelIndex();
if (!hasIndex(row, column, parent))
return QModelIndex();
ObjectPropItem* parentNode;
2016-02-17 10:11:00 +03:00
if (parent.isValid())
parentNode = nodeFromIndex(parent);
else
parentNode = m_rootNode;
ObjectPropItem* childItem = parentNode->child(row);
2016-02-17 10:11:00 +03:00
if (childItem) {
QModelIndex modelIndex = createIndex(row, column, childItem);
if (column == 1) {
if (childItem->modelIndex() != modelIndex) {
2016-02-17 10:11:00 +03:00
childItem->setModelIndex(modelIndex);
}
}
return modelIndex;
} else
return QModelIndex();
2016-02-17 10:11:00 +03:00
}
QModelIndex QObjectPropertyModel::parent(const QModelIndex& child) const
{
if (!child.isValid())
return QModelIndex();
2016-02-17 10:11:00 +03:00
ObjectPropItem* childNode = nodeFromIndex(child);
if (!childNode)
return QModelIndex();
2016-02-17 10:11:00 +03:00
ObjectPropItem* parentNode = childNode->parent();
if ((parentNode == m_rootNode) || (!parentNode))
return QModelIndex();
2016-02-17 10:11:00 +03:00
return createIndex(parentNode->row(), 0, parentNode);
2016-02-17 10:11:00 +03:00
}
Qt::ItemFlags QObjectPropertyModel::flags(const QModelIndex& index) const
2016-02-17 10:11:00 +03:00
{
if ((index.column() == 1) && (!nodeFromIndex(index)->isValueReadonly()))
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
else
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
2016-02-17 10:11:00 +03:00
}
CreatePropItem QObjectPropertyModel::propertyItemCreator(QMetaProperty prop)
{
CreatePropItem creator = 0;
creator = ObjectPropFactory::instance().objectCreator(
APropIdent(prop.name(), prop.enclosingMetaObject()->className()));
if (!creator) {
if (prop.isFlagType()) {
creator = ObjectPropFactory::instance().objectCreator(APropIdent("flags", ""));
if (creator) {
return creator;
2016-02-17 10:11:00 +03:00
} else {
qDebug() << "flags prop editor not found";
2016-02-17 10:11:00 +03:00
return 0;
}
}
if (prop.isEnumType()) {
creator = ObjectPropFactory::instance().objectCreator(APropIdent("enum", ""));
if (creator) {
2016-02-17 10:11:00 +03:00
return creator;
} else {
qDebug() << "enum prop editor not found";
2016-02-17 10:11:00 +03:00
return 0;
}
}
creator = ObjectPropFactory::instance().objectCreator(APropIdent(prop.typeName(), ""));
if (!creator) {
qDebug() << "Editor for propperty name = \"" << prop.name() << "\" & property type =\""
<< prop.typeName() << "\" not found!";
}
2016-02-17 10:11:00 +03:00
}
return creator;
}
ObjectPropItem* QObjectPropertyModel::createPropertyItem(QMetaProperty prop, QObject* object,
ObjectPropItem::ObjectsList* objects,
ObjectPropItem* parent)
2016-02-17 10:11:00 +03:00
{
ObjectPropItem* propertyItem = 0;
CreatePropItem creator = propertyItemCreator(prop);
2016-02-17 10:11:00 +03:00
if (creator) {
propertyItem = creator(object, objects, QString(prop.name()), QString(tr(prop.name())),
object->property(prop.name()), parent,
!(prop.isWritable() && prop.isDesignable()));
2016-02-17 10:11:00 +03:00
} else {
propertyItem = new ObjectPropItem(0, 0, QString(prop.name()), QString(tr(prop.name())),
object->property(prop.name()), parent);
2016-02-17 10:11:00 +03:00
}
return propertyItem;
}
bool QObjectPropertyModel::isTranslateProperties() const { return m_translateProperties; }
void QObjectPropertyModel::setTranslateProperties(bool translateProperties)
{
m_translateProperties = translateProperties;
}
ValidatorIntf* QObjectPropertyModel::validator() const { return m_validator; }
2016-02-17 10:11:00 +03:00
void QObjectPropertyModel::setValidator(ValidatorIntf* validator) { m_validator = validator; }
2016-02-17 10:11:00 +03:00
void QObjectPropertyModel::addObjectProperties(const QMetaObject* metaObject, QObject* object,
ObjectPropItem::ObjectsList* objects, int level)
2016-02-17 10:11:00 +03:00
{
if (metaObject->propertyCount() > metaObject->propertyOffset()) {
2016-02-17 10:11:00 +03:00
ObjectPropItem* objectNode;
if (m_subclassesAsLevel) {
objectNode = new ObjectPropItem(0, 0, metaObject->className(), metaObject->className(),
m_rootNode, true);
2016-02-17 10:11:00 +03:00
m_rootNode->appendItem(objectNode);
} else {
objectNode = m_rootNode;
}
for (int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); i++) {
if (metaObject->property(i).isDesignable()) {
ObjectPropItem* prop
= createPropertyItem(metaObject->property(i), object, objects, objectNode);
2016-02-17 10:11:00 +03:00
objectNode->appendItem(prop);
}
}
if (m_subclassesAsLevel) {
2016-02-17 10:11:00 +03:00
objectNode->setColorIndex(level);
objectNode->sortItem();
level++;
}
}
if (metaObject->superClass())
addObjectProperties(metaObject->superClass(), object, objects, level);
2016-02-17 10:11:00 +03:00
m_rootNode->sortItem();
}
bool QObjectPropertyModel::setData(const QModelIndex& index, const QVariant& value, int role)
2016-02-17 10:11:00 +03:00
{
if (index.isValid() && role == Qt::EditRole) {
m_dataChanging = true;
ObjectPropItem* propItem = nodeFromIndex(index);
if (propItem->propertyValue() != value) {
2016-02-17 10:11:00 +03:00
QString msg;
if (validator()
&& !validator()->validate(propItem->propertyName(), value.toString(), m_object,
msg)) {
QMessageBox::information(0, tr("Warning"), msg);
2016-02-17 10:11:00 +03:00
return true;
}
QVariant oldValue = propItem->propertyValue();
2016-02-17 10:11:00 +03:00
propItem->setPropertyValue(value);
emit dataChanged(index, index);
emit objectPropetyChanged(propItem->propertyName(), oldValue,
propItem->propertyValue());
2016-02-17 10:11:00 +03:00
}
m_dataChanging = false;
2016-02-17 10:11:00 +03:00
return true;
}
return false;
}
void QObjectPropertyModel::itemDataChanged(const QModelIndex& index)
2016-02-17 10:11:00 +03:00
{
emit dataChanged(index, index);
2016-02-17 10:11:00 +03:00
}
} // namespace LimeReport