File indexing completed on 2024-05-19 04:36:36
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 "ValueSpinBox.h" 0021 0022 namespace tikz { 0023 namespace ui { 0024 0025 class ValueSpinBoxPrivate 0026 { 0027 public: 0028 tikz::Unit unit = tikz::Unit::Millimeter; 0029 }; 0030 0031 ValueSpinBox::ValueSpinBox(QWidget * parent) 0032 : QDoubleSpinBox(parent) 0033 , d(new ValueSpinBoxPrivate()) 0034 { 0035 setFrame(false); 0036 connect(this, SIGNAL(valueChanged(double)), this, SLOT(slotValueChanged(double))); 0037 } 0038 0039 ValueSpinBox::~ValueSpinBox() 0040 { 0041 delete d; 0042 } 0043 0044 void ValueSpinBox::setUnit(tikz::Unit unit) 0045 { 0046 if (d->unit != unit) { 0047 d->unit = unit; 0048 } 0049 } 0050 0051 tikz::Value ValueSpinBox::valueWithUnit() const 0052 { 0053 return tikz::Value(value(), d->unit); 0054 } 0055 0056 void ValueSpinBox::setValueWithUnit(const tikz::Value & val) 0057 { 0058 const bool unitChange = d->unit != val.unit(); 0059 if (unitChange) { 0060 setUnit(val.unit()); 0061 } 0062 0063 if (unitChange || value() != val.value()) { 0064 setValue(val.value()); 0065 } 0066 } 0067 0068 void ValueSpinBox::slotValueChanged(double value) 0069 { 0070 Q_EMIT valueChanged(tikz::Value(value, d->unit)); 0071 } 0072 0073 QString ValueSpinBox::textFromValue(double value) const 0074 { 0075 return tikz::Value(value, d->unit).toString(); 0076 } 0077 0078 double ValueSpinBox::valueFromText(const QString &text) const 0079 { 0080 QString str = text; 0081 0082 static QRegularExpression re("(pt?|mm?|cm?|in?)"); 0083 QRegularExpressionMatch match = re.match(str); 0084 0085 // append unit to avoid fallback to pt in Value::fromString() 0086 if (! match.hasMatch()) { 0087 switch (d->unit) { 0088 case tikz::Unit::Point: break; 0089 case tikz::Unit::Millimeter: str += "mm"; break; 0090 case tikz::Unit::Centimeter: str += "cm"; break; 0091 case tikz::Unit::Inch: str += "in"; break; 0092 default: Q_ASSERT(false); 0093 } 0094 } 0095 0096 // convert to value 0097 tikz::Value val = tikz::Value::fromString(str); 0098 const bool unitChanged = d->unit != val.unit(); 0099 const_cast<ValueSpinBox*>(this)->setUnit(val.unit()); 0100 0101 // in case the number remains unchanged but the unit changed, manually emit 0102 // the signal, since QDoubleSpinBox does not do this. 0103 if (val.value() == value() && unitChanged) { 0104 const_cast<ValueSpinBox*>(this)->slotValueChanged(val.value()); 0105 } 0106 0107 return val.value(); 0108 } 0109 0110 void ValueSpinBox::fixup(QString & input) const 0111 { 0112 QDoubleSpinBox::fixup(input); 0113 } 0114 0115 QValidator::State ValueSpinBox::validate(QString & text, int & pos) const 0116 { 0117 static QRegularExpression re("([a-zA-Z]+)"); 0118 0119 QRegularExpressionMatch match = re.match(text); 0120 if (match.hasMatch()) { 0121 const QString unit = match.captured(1); 0122 if (unit == "p" || 0123 unit == "m" || 0124 unit == "c" || 0125 unit == "i") 0126 { 0127 return QValidator::Intermediate; 0128 } 0129 0130 if (unit == "pt" || 0131 unit == "mm" || 0132 unit == "cm" || 0133 unit == "in") 0134 { 0135 pos = match.capturedStart(1); 0136 QString str = text.left(pos); 0137 return QDoubleSpinBox::validate(str, pos); 0138 } 0139 } 0140 0141 return QDoubleSpinBox::validate(text, pos); 0142 } 0143 0144 } 0145 } 0146 0147 // kate: indent-width 4; replace-tabs on;