File indexing completed on 2024-05-19 04:36:37

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "ValueSpinBoxFactory.h"
0021 #include "ValueSpinBox.h"
0022 
0023 namespace tikz {
0024 namespace ui {
0025 
0026 
0027 template <class Editor>
0028 class EditorFactoryPrivate
0029 {
0030 public:
0031 
0032     typedef QList<Editor *> EditorList;
0033     typedef QMap<QtProperty *, EditorList> PropertyToEditorListMap;
0034     typedef QMap<Editor *, QtProperty *> EditorToPropertyMap;
0035 
0036     Editor *createEditor(QtProperty *property, QWidget *parent);
0037     void initializeEditor(QtProperty *property, Editor *e);
0038     void slotEditorDestroyed(QObject *object);
0039 
0040     PropertyToEditorListMap  m_createdEditors;
0041     EditorToPropertyMap m_editorToProperty;
0042 };
0043 
0044 template <class Editor>
0045 Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property, QWidget *parent)
0046 {
0047     Editor *editor = new Editor(parent);
0048     initializeEditor(property, editor);
0049     return editor;
0050 }
0051 
0052 template <class Editor>
0053 void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property, Editor *editor)
0054 {
0055     typename PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
0056     if (it == m_createdEditors.end())
0057         it = m_createdEditors.insert(property, EditorList());
0058     it.value().append(editor);
0059     m_editorToProperty.insert(editor, property);
0060 }
0061 
0062 template <class Editor>
0063 void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
0064 {
0065     const typename EditorToPropertyMap::iterator ecend = m_editorToProperty.end();
0066     for (typename EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor !=  ecend; ++itEditor) {
0067         if (itEditor.key() == object) {
0068             Editor *editor = itEditor.key();
0069             QtProperty *property = itEditor.value();
0070             const typename PropertyToEditorListMap::iterator pit = m_createdEditors.find(property);
0071             if (pit != m_createdEditors.end()) {
0072                 pit.value().removeAll(editor);
0073                 if (pit.value().empty())
0074                     m_createdEditors.erase(pit);
0075             }
0076             m_editorToProperty.erase(itEditor);
0077             return;
0078         }
0079     }
0080 }
0081 
0082 class ValueSpinBoxFactoryPrivate : public EditorFactoryPrivate<ValueSpinBox>
0083 {
0084     ValueSpinBoxFactory *q_ptr;
0085     Q_DECLARE_PUBLIC(ValueSpinBoxFactory)
0086 public:
0087 
0088     void slotPropertyChanged(QtProperty *property, const tikz::Value & value);
0089     void slotRangeChanged(QtProperty *property, const tikz::Value & min, const tikz::Value & max);
0090     void slotSingleStepChanged(QtProperty *property, double step);
0091     void slotDecimalsChanged(QtProperty *property, int prec);
0092     void slotReadOnlyChanged(QtProperty *property, bool readOnly);
0093     void slotSetValue(const tikz::Value & value);
0094 };
0095 
0096 void ValueSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, const tikz::Value & value)
0097 {
0098     QList<ValueSpinBox *> editors = m_createdEditors[property];
0099     QListIterator<ValueSpinBox *> itEditor(m_createdEditors[property]);
0100     while (itEditor.hasNext()) {
0101         ValueSpinBox *editor = itEditor.next();
0102         if (editor->valueWithUnit() != value) {
0103             editor->blockSignals(true);
0104             editor->setValueWithUnit(value);
0105             editor->blockSignals(false);
0106         }
0107     }
0108 }
0109 
0110 void ValueSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
0111             const tikz::Value & min, const tikz::Value & max)
0112 {
0113     if (!m_createdEditors.contains(property))
0114         return;
0115 
0116     ValuePropertyManager *manager = q_ptr->propertyManager(property);
0117     if (!manager)
0118         return;
0119 
0120     QList<ValueSpinBox *> editors = m_createdEditors[property];
0121     QListIterator<ValueSpinBox *> itEditor(editors);
0122     while (itEditor.hasNext()) {
0123         ValueSpinBox *editor = itEditor.next();
0124         editor->blockSignals(true);
0125         editor->setRange(min.toPoint(), max.toPoint());
0126         editor->setValueWithUnit(manager->value(property));
0127         editor->blockSignals(false);
0128     }
0129 }
0130 
0131 void ValueSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step)
0132 {
0133     if (!m_createdEditors.contains(property))
0134         return;
0135 
0136     ValuePropertyManager *manager = q_ptr->propertyManager(property);
0137     if (!manager)
0138         return;
0139 
0140     QList<ValueSpinBox *> editors = m_createdEditors[property];
0141     QListIterator<ValueSpinBox *> itEditor(editors);
0142     while (itEditor.hasNext()) {
0143         ValueSpinBox *editor = itEditor.next();
0144         editor->blockSignals(true);
0145         editor->setSingleStep(step);
0146         editor->blockSignals(false);
0147     }
0148 }
0149 
0150 void ValueSpinBoxFactoryPrivate::slotReadOnlyChanged( QtProperty *property, bool readOnly)
0151 {
0152     if (!m_createdEditors.contains(property))
0153         return;
0154 
0155     ValuePropertyManager *manager = q_ptr->propertyManager(property);
0156     if (!manager)
0157         return;
0158 
0159     QListIterator<ValueSpinBox *> itEditor(m_createdEditors[property]);
0160     while (itEditor.hasNext()) {
0161         ValueSpinBox *editor = itEditor.next();
0162         editor->blockSignals(true);
0163         editor->setReadOnly(readOnly);
0164         editor->blockSignals(false);
0165     }
0166 }
0167 
0168 void ValueSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec)
0169 {
0170     if (!m_createdEditors.contains(property))
0171         return;
0172 
0173     ValuePropertyManager *manager = q_ptr->propertyManager(property);
0174     if (!manager)
0175         return;
0176 
0177     QList<ValueSpinBox *> editors = m_createdEditors[property];
0178     QListIterator<ValueSpinBox *> itEditor(editors);
0179     while (itEditor.hasNext()) {
0180         ValueSpinBox *editor = itEditor.next();
0181         editor->blockSignals(true);
0182         editor->setDecimals(prec);
0183         editor->setValueWithUnit(manager->value(property));
0184         editor->blockSignals(false);
0185     }
0186 }
0187 
0188 void ValueSpinBoxFactoryPrivate::slotSetValue(const tikz::Value & value)
0189 {
0190     QObject *object = q_ptr->sender();
0191     const QMap<ValueSpinBox *, QtProperty *>::ConstIterator itcend = m_editorToProperty.constEnd();
0192     for (QMap<ValueSpinBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) {
0193         if (itEditor.key() == object) {
0194             QtProperty *property = itEditor.value();
0195             ValuePropertyManager *manager = q_ptr->propertyManager(property);
0196             if (!manager)
0197                 return;
0198             manager->setValue(property, value);
0199             return;
0200         }
0201     }
0202 }
0203 
0204 /*! \class ValueSpinBoxFactory
0205 
0206     \brief The ValueSpinBoxFactory class provides ValueSpinBox
0207     widgets for properties created by ValuePropertyManager objects.
0208 
0209     \sa QtAbstractEditorFactory, ValuePropertyManager
0210 */
0211 
0212 /*!
0213     Creates a factory with the given \a parent.
0214 */
0215 ValueSpinBoxFactory::ValueSpinBoxFactory(QObject *parent)
0216     : QtAbstractEditorFactory<ValuePropertyManager>(parent)
0217 {
0218     d_ptr = new ValueSpinBoxFactoryPrivate();
0219     d_ptr->q_ptr = this;
0220 
0221 }
0222 
0223 /*!
0224     Destroys this factory, and all the widgets it has created.
0225 */
0226 ValueSpinBoxFactory::~ValueSpinBoxFactory()
0227 {
0228     qDeleteAll(d_ptr->m_editorToProperty.keys());
0229     delete d_ptr;
0230 }
0231 
0232 /*!
0233     \internal
0234 
0235     Reimplemented from the QtAbstractEditorFactory class.
0236 */
0237 void ValueSpinBoxFactory::connectPropertyManager(ValuePropertyManager *manager)
0238 {
0239     connect(manager, SIGNAL(valueChanged(QtProperty *, const tikz::Value &)),
0240                 this, SLOT(slotPropertyChanged(QtProperty *, const tikz::Value &)));
0241     connect(manager, SIGNAL(rangeChanged(QtProperty *, const tikz::Value &, const tikz::Value &)),
0242                 this, SLOT(slotRangeChanged(QtProperty *, const tikz::Value &, const tikz::Value &)));
0243     connect(manager, SIGNAL(singleStepChanged(QtProperty *, double)),
0244                 this, SLOT(slotSingleStepChanged(QtProperty *, double)));
0245     connect(manager, SIGNAL(decimalsChanged(QtProperty *, int)),
0246                 this, SLOT(slotDecimalsChanged(QtProperty *, int)));
0247     connect(manager, SIGNAL(readOnlyChanged(QtProperty *, bool)),
0248                 this, SLOT(slotReadOnlyChanged(QtProperty *, bool)));
0249 }
0250 
0251 /*!
0252     \internal
0253 
0254     Reimplemented from the QtAbstractEditorFactory class.
0255 */
0256 QWidget *ValueSpinBoxFactory::createEditor(ValuePropertyManager *manager,
0257         QtProperty *property, QWidget *parent)
0258 {
0259     ValueSpinBox *editor = d_ptr->createEditor(property, parent);
0260     editor->setSingleStep(manager->singleStep(property));
0261     editor->setDecimals(manager->decimals(property));
0262     editor->setRange(manager->minimum(property).toPoint(), manager->maximum(property).toPoint());
0263     editor->setValueWithUnit(manager->value(property));
0264     editor->setKeyboardTracking(false);
0265     editor->setReadOnly(manager->isReadOnly(property));
0266 
0267     connect(editor, SIGNAL(valueChanged(const tikz::Value &)), this, SLOT(slotSetValue(const tikz::Value &)));
0268     connect(editor, SIGNAL(destroyed(QObject *)),
0269                 this, SLOT(slotEditorDestroyed(QObject *)));
0270     return editor;
0271 }
0272 
0273 /*!
0274     \internal
0275 
0276     Reimplemented from the QtAbstractEditorFactory class.
0277 */
0278 void ValueSpinBoxFactory::disconnectPropertyManager(ValuePropertyManager *manager)
0279 {
0280     disconnect(manager, SIGNAL(valueChanged(QtProperty *, const tikz::Value &)),
0281                 this, SLOT(slotPropertyChanged(QtProperty *, const tikz::Value &)));
0282     disconnect(manager, SIGNAL(rangeChanged(QtProperty *, const tikz::Value &, const tikz::Value &)),
0283                 this, SLOT(slotRangeChanged(QtProperty *, const tikz::Value &, const tikz::Value &)));
0284     disconnect(manager, SIGNAL(singleStepChanged(QtProperty *, double)),
0285                 this, SLOT(slotSingleStepChanged(QtProperty *, double)));
0286     disconnect(manager, SIGNAL(decimalsChanged(QtProperty *, int)),
0287                 this, SLOT(slotDecimalsChanged(QtProperty *, int)));
0288     disconnect(manager, SIGNAL(readOnlyChanged(QtProperty *, bool)),
0289                 this, SLOT(slotReadOnlyChanged(QtProperty *, bool)));
0290 }
0291 
0292 }
0293 }
0294 
0295 #include "moc_ValueSpinBoxFactory.cpp"
0296 
0297 // kate: indent-width 4; replace-tabs on;