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;