summaryrefslogtreecommitdiffstats
path: root/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2009-03-23 10:18:55 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2009-03-23 10:18:55 +0100
commite5fcad302d86d316390c6b0f62759a067313e8a9 (patch)
treec2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
Long live Qt 4.5!
Diffstat (limited to 'tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp')
-rw-r--r--tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp535
1 files changed, 535 insertions, 0 deletions
diff --git a/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
new file mode 100644
index 0000000000..d7c8f0b596
--- /dev/null
+++ b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
@@ -0,0 +1,535 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgroupboxpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+#include <QtCore/QTimer>
+#include <QtCore/QMap>
+
+#if QT_VERSION >= 0x040400
+QT_BEGIN_NAMESPACE
+#endif
+
+class QtGroupBoxPropertyBrowserPrivate
+{
+ QtGroupBoxPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser)
+public:
+
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+
+ void slotEditorDestroyed();
+ void slotUpdate();
+
+ struct WidgetItem
+ {
+ WidgetItem() : widget(0), label(0), widgetLabel(0),
+ groupBox(0), layout(0), line(0), parent(0) { }
+ QWidget *widget; // can be null
+ QLabel *label;
+ QLabel *widgetLabel;
+ QGroupBox *groupBox;
+ QGridLayout *layout;
+ QFrame *line;
+ WidgetItem *parent;
+ QList<WidgetItem *> children;
+ };
+private:
+ void updateLater();
+ void updateItem(WidgetItem *item);
+ void insertRow(QGridLayout *layout, int row) const;
+ void removeRow(QGridLayout *layout, int row) const;
+
+ bool hasHeader(WidgetItem *item) const;
+
+ QMap<QtBrowserItem *, WidgetItem *> m_indexToItem;
+ QMap<WidgetItem *, QtBrowserItem *> m_itemToIndex;
+ QMap<QWidget *, WidgetItem *> m_widgetToItem;
+ QGridLayout *m_mainLayout;
+ QList<WidgetItem *> m_children;
+ QList<WidgetItem *> m_recreateQueue;
+};
+
+void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent)
+{
+ m_mainLayout = new QGridLayout();
+ parent->setLayout(m_mainLayout);
+ QLayoutItem *item = new QSpacerItem(0, 0,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ m_mainLayout->addItem(item, 0, 0);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed()
+{
+ QWidget *editor = qobject_cast<QWidget *>(q_ptr->sender());
+ if (!editor)
+ return;
+ if (!m_widgetToItem.contains(editor))
+ return;
+ m_widgetToItem[editor]->widget = 0;
+ m_widgetToItem.remove(editor);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotUpdate()
+{
+ QListIterator<WidgetItem *> itItem(m_recreateQueue);
+ while (itItem.hasNext()) {
+ WidgetItem *item = itItem.next();
+
+ WidgetItem *par = item->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(item);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(item);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (item->widget) {
+ item->widget->setParent(w);
+ } else if (item->widgetLabel) {
+ item->widgetLabel->setParent(w);
+ } else {
+ item->widgetLabel = new QLabel(w);
+ }
+ int span = 1;
+ if (item->widget)
+ l->addWidget(item->widget, oldRow, 1, 1, 1);
+ else if (item->widgetLabel)
+ l->addWidget(item->widgetLabel, oldRow, 1, 1, 1);
+ else
+ span = 2;
+ item->label = new QLabel(w);
+ item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ l->addWidget(item->label, oldRow, 0, 1, span);
+
+ updateItem(item);
+ }
+ m_recreateQueue.clear();
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateLater()
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdate()));
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ WidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ WidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ WidgetItem *newItem = new WidgetItem();
+ newItem->parent = parentItem;
+
+ QGridLayout *layout = 0;
+ QWidget *parentWidget = 0;
+ int row = -1;
+ if (!afterItem) {
+ row = 0;
+ if (parentItem)
+ parentItem->children.insert(0, newItem);
+ else
+ m_children.insert(0, newItem);
+ } else {
+ if (parentItem) {
+ row = parentItem->children.indexOf(afterItem) + 1;
+ parentItem->children.insert(row, newItem);
+ } else {
+ row = m_children.indexOf(afterItem) + 1;
+ m_children.insert(row, newItem);
+ }
+ }
+ if (parentItem && hasHeader(parentItem))
+ row += 2;
+
+ if (!parentItem) {
+ layout = m_mainLayout;
+ parentWidget = q_ptr;;
+ } else {
+ if (!parentItem->groupBox) {
+ m_recreateQueue.removeAll(parentItem);
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+ parentItem->groupBox = new QGroupBox(w);
+ parentItem->layout = new QGridLayout();
+ parentItem->groupBox->setLayout(parentItem->layout);
+ if (parentItem->label) {
+ l->removeWidget(parentItem->label);
+ delete parentItem->label;
+ parentItem->label = 0;
+ }
+ if (parentItem->widget) {
+ l->removeWidget(parentItem->widget);
+ parentItem->widget->setParent(parentItem->groupBox);
+ parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2);
+ parentItem->line = new QFrame(parentItem->groupBox);
+ } else if (parentItem->widgetLabel) {
+ l->removeWidget(parentItem->widgetLabel);
+ delete parentItem->widgetLabel;
+ parentItem->widgetLabel = 0;
+ }
+ if (parentItem->line) {
+ parentItem->line->setFrameShape(QFrame::HLine);
+ parentItem->line->setFrameShadow(QFrame::Sunken);
+ parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2);
+ }
+ l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2);
+ updateItem(parentItem);
+ }
+ layout = parentItem->layout;
+ parentWidget = parentItem->groupBox;
+ }
+
+ newItem->label = new QLabel(parentWidget);
+ newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ newItem->widget = createEditor(index->property(), parentWidget);
+ if (!newItem->widget) {
+ newItem->widgetLabel = new QLabel(parentWidget);
+ } else {
+ QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed()));
+ m_widgetToItem[newItem->widget] = newItem;
+ }
+
+ insertRow(layout, row);
+ int span = 1;
+ if (newItem->widget)
+ layout->addWidget(newItem->widget, row, 1);
+ else if (newItem->widgetLabel)
+ layout->addWidget(newItem->widgetLabel, row, 1);
+ else
+ span = 2;
+ layout->addWidget(newItem->label, row, 0, 1, span);
+
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ updateItem(newItem);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+
+ WidgetItem *parentItem = item->parent;
+
+ int row = -1;
+
+ if (parentItem) {
+ row = parentItem->children.indexOf(item);
+ parentItem->children.removeAt(row);
+ if (hasHeader(parentItem))
+ row += 2;
+ } else {
+ row = m_children.indexOf(item);
+ m_children.removeAt(row);
+ }
+
+ if (item->widget)
+ delete item->widget;
+ if (item->label)
+ delete item->label;
+ if (item->widgetLabel)
+ delete item->widgetLabel;
+ if (item->groupBox)
+ delete item->groupBox;
+
+ if (!parentItem) {
+ removeRow(m_mainLayout, row);
+ } else if (parentItem->children.count() != 0) {
+ removeRow(parentItem->layout, row);
+ } else {
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (parentItem->widget) {
+ parentItem->widget->hide();
+ parentItem->widget->setParent(0);
+ } else if (parentItem->widgetLabel) {
+ parentItem->widgetLabel->hide();
+ parentItem->widgetLabel->setParent(0);
+ } else {
+ //parentItem->widgetLabel = new QLabel(w);
+ }
+ l->removeWidget(parentItem->groupBox);
+ delete parentItem->groupBox;
+ parentItem->groupBox = 0;
+ parentItem->line = 0;
+ parentItem->layout = 0;
+ if (!m_recreateQueue.contains(parentItem))
+ m_recreateQueue.append(parentItem);
+ updateLater();
+ }
+ m_recreateQueue.removeAll(item);
+
+ delete item;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r >= row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r > row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const
+{
+ if (item->widget)
+ return true;
+ return false;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ if (item->groupBox) {
+ QFont font = item->groupBox->font();
+ font.setUnderline(property->isModified());
+ item->groupBox->setFont(font);
+ item->groupBox->setTitle(property->propertyName());
+ item->groupBox->setToolTip(property->toolTip());
+ item->groupBox->setStatusTip(property->statusTip());
+ item->groupBox->setWhatsThis(property->whatsThis());
+ item->groupBox->setEnabled(property->isEnabled());
+ }
+ if (item->label) {
+ QFont font = item->label->font();
+ font.setUnderline(property->isModified());
+ item->label->setFont(font);
+ item->label->setText(property->propertyName());
+ item->label->setToolTip(property->toolTip());
+ item->label->setStatusTip(property->statusTip());
+ item->label->setWhatsThis(property->whatsThis());
+ item->label->setEnabled(property->isEnabled());
+ }
+ if (item->widgetLabel) {
+ QFont font = item->widgetLabel->font();
+ font.setUnderline(false);
+ item->widgetLabel->setFont(font);
+ item->widgetLabel->setText(property->valueText());
+ item->widgetLabel->setEnabled(property->isEnabled());
+ }
+ if (item->widget) {
+ QFont font = item->widget->font();
+ font.setUnderline(false);
+ item->widget->setFont(font);
+ item->widget->setEnabled(property->isEnabled());
+ item->widget->setToolTip(property->valueText());
+ }
+ //item->setIcon(1, property->valueIcon());
+}
+
+
+
+/*!
+ \class QtGroupBoxPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox
+ based property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtGroupBoxPropertyBrowser provides group boxes for all nested
+ properties, i.e. subproperties are enclosed by a group box with
+ the parent property's name as its title. For example:
+
+ \image qtgroupboxpropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtGroupBoxPropertyBrowser
+ class. The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent)
+{
+ d_ptr = new QtGroupBoxPropertyBrowserPrivate;
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser()
+{
+ const QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator icend = d_ptr->m_itemToIndex.constEnd();
+ for (QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it)
+ delete it.key();
+ delete d_ptr;
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+#if QT_VERSION >= 0x040400
+QT_END_NAMESPACE
+#endif
+
+#include "moc_qtgroupboxpropertybrowser.cpp"