| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <limits>
|
| |
|
| | #include <QAction>
|
| | #include <QApplication>
|
| | #include <QColorDialog>
|
| | #include <QCursor>
|
| | #include <QFileDialog>
|
| | #include <QHeaderView>
|
| | #include <QMenu>
|
| | #include <QMessageBox>
|
| | #include <QRegularExpression>
|
| | #include <QRegularExpressionMatch>
|
| | #include <QStyleOptionButton>
|
| | #include <QStylePainter>
|
| | #include <QToolTip>
|
| | #include <QtGui>
|
| |
|
| | #include "customwidgets.h"
|
| |
|
| | using namespace Gui;
|
| |
|
| |
|
| | UrlLabel::UrlLabel(QWidget* parent, Qt::WindowFlags f)
|
| | : QLabel("TextLabel", parent, f)
|
| | {
|
| | _url = "http://localhost";
|
| | setToolTip(this->_url);
|
| | setCursor(Qt::PointingHandCursor);
|
| | }
|
| |
|
| | UrlLabel::~UrlLabel()
|
| | {}
|
| |
|
| | void UrlLabel::mouseReleaseEvent(QMouseEvent*)
|
| | {
|
| | QMessageBox::information(this, "Browser", QString("This starts your browser with url %1").arg(_url));
|
| | }
|
| |
|
| | QString UrlLabel::url() const
|
| | {
|
| | return this->_url;
|
| | }
|
| |
|
| | void UrlLabel::setUrl(const QString& u)
|
| | {
|
| | this->_url = u;
|
| | setToolTip(this->_url);
|
| | }
|
| |
|
| | LocationWidget::LocationWidget(QWidget* parent)
|
| | : QWidget(parent)
|
| | {
|
| | box = new QGridLayout();
|
| |
|
| | xValue = new QDoubleSpinBox(this);
|
| | xValue->setMinimum(-2.14748e+09);
|
| | xValue->setMaximum(2.14748e+09);
|
| | xLabel = new QLabel(this);
|
| | box->addWidget(xLabel, 0, 0, 1, 1);
|
| | box->addWidget(xValue, 0, 1, 1, 1);
|
| |
|
| | yValue = new QDoubleSpinBox(this);
|
| | yValue->setMinimum(-2.14748e+09);
|
| | yValue->setMaximum(2.14748e+09);
|
| | yLabel = new QLabel(this);
|
| | box->addWidget(yLabel, 1, 0, 1, 1);
|
| | box->addWidget(yValue, 1, 1, 1, 1);
|
| |
|
| | zValue = new QDoubleSpinBox(this);
|
| | zValue->setMinimum(-2.14748e+09);
|
| | zValue->setMaximum(2.14748e+09);
|
| | zLabel = new QLabel(this);
|
| | box->addWidget(zLabel, 2, 0, 1, 1);
|
| | box->addWidget(zValue, 2, 1, 1, 1);
|
| |
|
| | dLabel = new QLabel(this);
|
| | dValue = new QComboBox(this);
|
| | dValue->setCurrentIndex(-1);
|
| | box->addWidget(dLabel, 3, 0, 1, 1);
|
| | box->addWidget(dValue, 3, 1, 1, 1);
|
| |
|
| | QGridLayout* gridLayout = new QGridLayout(this);
|
| | gridLayout->addLayout(box, 0, 0, 1, 2);
|
| |
|
| | retranslateUi();
|
| | }
|
| |
|
| | LocationWidget::~LocationWidget()
|
| | {}
|
| |
|
| | QSize LocationWidget::sizeHint() const
|
| | {
|
| | return QSize(150, 100);
|
| | }
|
| |
|
| | void LocationWidget::changeEvent(QEvent* e)
|
| | {
|
| | if (e->type() == QEvent::LanguageChange) {
|
| | this->retranslateUi();
|
| | }
|
| | QWidget::changeEvent(e);
|
| | }
|
| |
|
| | void LocationWidget::retranslateUi()
|
| | {
|
| | xLabel->setText(QApplication::translate("Gui::LocationWidget", "X:"));
|
| | yLabel->setText(QApplication::translate("Gui::LocationWidget", "Y:"));
|
| | zLabel->setText(QApplication::translate("Gui::LocationWidget", "Z:"));
|
| | dLabel->setText(QApplication::translate("Gui::LocationWidget", "Direction:"));
|
| | }
|
| |
|
| | FileChooser::FileChooser(QWidget* parent)
|
| | : QWidget(parent)
|
| | , md(File)
|
| | , _filter(QString())
|
| | {
|
| | QHBoxLayout* layout = new QHBoxLayout(this);
|
| | layout->setContentsMargins(0, 0, 0, 0);
|
| | layout->setSpacing(6);
|
| |
|
| | lineEdit = new QLineEdit(this);
|
| | layout->addWidget(lineEdit);
|
| |
|
| | connect(lineEdit, &QLineEdit::textChanged, this, &FileChooser::fileNameChanged);
|
| |
|
| | button = new QPushButton("...", this);
|
| | button->setFixedWidth(2 * button->fontMetrics().horizontalAdvance(" ... "));
|
| |
|
| | layout->addWidget(button);
|
| |
|
| | connect(button, &QPushButton::clicked, this, &FileChooser::chooseFile);
|
| |
|
| | setFocusProxy(lineEdit);
|
| | }
|
| |
|
| | FileChooser::~FileChooser()
|
| | {}
|
| |
|
| | QString FileChooser::fileName() const
|
| | {
|
| | return lineEdit->text();
|
| | }
|
| |
|
| | void FileChooser::setFileName(const QString& fn)
|
| | {
|
| | lineEdit->setText(fn);
|
| | }
|
| |
|
| | void FileChooser::chooseFile()
|
| | {
|
| | QFileDialog::Options dlgOpt = QFileDialog::DontUseNativeDialog;
|
| | QString fn;
|
| | if (mode() == File) {
|
| | fn = QFileDialog::getOpenFileName(this, tr("Select a file"), lineEdit->text(), _filter, 0, dlgOpt);
|
| | }
|
| | else {
|
| | QFileDialog::Options option = QFileDialog::ShowDirsOnly | dlgOpt;
|
| | fn = QFileDialog::getExistingDirectory(this, tr("Select a directory"), lineEdit->text(), option);
|
| | }
|
| |
|
| | if (!fn.isEmpty()) {
|
| | lineEdit->setText(fn);
|
| | Q_EMIT fileNameSelected(fn);
|
| | }
|
| | }
|
| |
|
| | FileChooser::Mode FileChooser::mode() const
|
| | {
|
| | return md;
|
| | }
|
| |
|
| | void FileChooser::setMode(Mode m)
|
| | {
|
| | md = m;
|
| | }
|
| |
|
| | QString FileChooser::filter() const
|
| | {
|
| | return _filter;
|
| | }
|
| |
|
| | void FileChooser::setFilter(const QString& filter)
|
| | {
|
| | _filter = filter;
|
| | }
|
| |
|
| | void FileChooser::setButtonText(const QString& txt)
|
| | {
|
| | button->setText(txt);
|
| |
|
| | int w1 = 2 * button->fontMetrics().horizontalAdvance(txt);
|
| | int w2 = 2 * button->fontMetrics().horizontalAdvance(" ... ");
|
| |
|
| | button->setFixedWidth((w1 > w2 ? w1 : w2));
|
| | }
|
| |
|
| | QString FileChooser::buttonText() const
|
| | {
|
| | return button->text();
|
| | }
|
| |
|
| |
|
| |
|
| | PrefFileChooser::PrefFileChooser(QWidget* parent)
|
| | : FileChooser(parent)
|
| | {}
|
| |
|
| | PrefFileChooser::~PrefFileChooser()
|
| | {}
|
| |
|
| | QByteArray PrefFileChooser::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefFileChooser::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefFileChooser::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefFileChooser::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | AccelLineEdit::AccelLineEdit(QWidget* parent)
|
| | : QLineEdit(parent)
|
| | {
|
| | setPlaceholderText(tr("Press a keyboard shortcut"));
|
| | setClearButtonEnabled(true);
|
| | keyPressedCount = 0;
|
| | }
|
| |
|
| | bool AccelLineEdit::isNone() const
|
| | {
|
| | return text().isEmpty();
|
| | }
|
| |
|
| | void AccelLineEdit::keyPressEvent(QKeyEvent* e)
|
| | {
|
| | if (isReadOnly()) {
|
| | QLineEdit::keyPressEvent(e);
|
| | return;
|
| | }
|
| |
|
| | QString txtLine = text();
|
| |
|
| | int key = e->key();
|
| | Qt::KeyboardModifiers state = e->modifiers();
|
| |
|
| |
|
| |
|
| |
|
| | switch (key) {
|
| | case Qt::Key_Backspace:
|
| | case Qt::Key_Delete:
|
| | if (state == Qt::NoModifier) {
|
| | keyPressedCount = 0;
|
| | if (isNone()) {
|
| | QKeySequence ks(key);
|
| | setText(ks.toString(QKeySequence::NativeText));
|
| | }
|
| | else {
|
| | clear();
|
| | }
|
| | }
|
| | case Qt::Key_Control:
|
| | case Qt::Key_Shift:
|
| | case Qt::Key_Alt:
|
| | case Qt::Key_Meta:
|
| | case Qt::Key_AltGr:
|
| | return;
|
| | default:
|
| | break;
|
| | }
|
| |
|
| | if (txtLine.isEmpty()) {
|
| |
|
| | keyPressedCount = 0;
|
| | }
|
| | else {
|
| |
|
| | switch (keyPressedCount) {
|
| | case 4:
|
| | keyPressedCount = 0;
|
| | txtLine.clear();
|
| | break;
|
| | case 0:
|
| | txtLine.clear();
|
| | break;
|
| | default:
|
| | txtLine += QString::fromLatin1(",");
|
| | break;
|
| | }
|
| | }
|
| |
|
| |
|
| | if ((state & Qt::ControlModifier) == Qt::ControlModifier) {
|
| | QKeySequence ks(Qt::CTRL);
|
| | txtLine += ks.toString(QKeySequence::NativeText);
|
| | }
|
| | if ((state & Qt::AltModifier) == Qt::AltModifier) {
|
| | QKeySequence ks(Qt::ALT);
|
| | txtLine += ks.toString(QKeySequence::NativeText);
|
| | }
|
| | if ((state & Qt::ShiftModifier) == Qt::ShiftModifier) {
|
| | QKeySequence ks(Qt::SHIFT);
|
| | txtLine += ks.toString(QKeySequence::NativeText);
|
| | }
|
| | if ((state & Qt::MetaModifier) == Qt::MetaModifier) {
|
| | QKeySequence ks(Qt::META);
|
| | txtLine += ks.toString(QKeySequence::NativeText);
|
| | }
|
| |
|
| |
|
| | QKeySequence ks(key);
|
| | txtLine += ks.toString(QKeySequence::NativeText);
|
| |
|
| | setText(txtLine);
|
| | keyPressedCount++;
|
| | }
|
| |
|
| |
|
| |
|
| | ActionSelector::ActionSelector(QWidget* parent)
|
| | : QWidget(parent)
|
| | {
|
| | addButton = new QPushButton(this);
|
| | addButton->setMinimumSize(QSize(30, 30));
|
| | QIcon icon;
|
| | icon.addFile(QString::fromUtf8(":/icons/button_right.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
| | addButton->setIcon(icon);
|
| | gridLayout = new QGridLayout(this);
|
| | gridLayout->addWidget(addButton, 1, 1, 1, 1);
|
| |
|
| | spacerItem = new QSpacerItem(33, 57, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
| | gridLayout->addItem(spacerItem, 5, 1, 1, 1);
|
| | spacerItem1 = new QSpacerItem(33, 58, QSizePolicy::Minimum, QSizePolicy::Expanding);
|
| | gridLayout->addItem(spacerItem1, 0, 1, 1, 1);
|
| |
|
| | removeButton = new QPushButton(this);
|
| | removeButton->setMinimumSize(QSize(30, 30));
|
| | QIcon icon1;
|
| | icon1.addFile(QString::fromUtf8(":/icons/button_left.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
| | removeButton->setIcon(icon1);
|
| | removeButton->setAutoDefault(true);
|
| | removeButton->setDefault(false);
|
| |
|
| | gridLayout->addWidget(removeButton, 2, 1, 1, 1);
|
| |
|
| | upButton = new QPushButton(this);
|
| | upButton->setMinimumSize(QSize(30, 30));
|
| | QIcon icon3;
|
| | icon3.addFile(QString::fromUtf8(":/icons/button_up.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
| | upButton->setIcon(icon3);
|
| |
|
| | gridLayout->addWidget(upButton, 3, 1, 1, 1);
|
| |
|
| | downButton = new QPushButton(this);
|
| | downButton->setMinimumSize(QSize(30, 30));
|
| | QIcon icon2;
|
| | icon2.addFile(QString::fromUtf8(":/icons/button_down.svg"), QSize(), QIcon::Normal, QIcon::Off);
|
| | downButton->setIcon(icon2);
|
| | downButton->setAutoDefault(true);
|
| |
|
| | gridLayout->addWidget(downButton, 4, 1, 1, 1);
|
| |
|
| | vboxLayout = new QVBoxLayout();
|
| | vboxLayout->setContentsMargins(0, 0, 0, 0);
|
| | labelAvailable = new QLabel(this);
|
| | vboxLayout->addWidget(labelAvailable);
|
| |
|
| | availableWidget = new QTreeWidget(this);
|
| | availableWidget->setRootIsDecorated(false);
|
| | availableWidget->setHeaderLabels(QStringList() << QString());
|
| | availableWidget->header()->hide();
|
| | vboxLayout->addWidget(availableWidget);
|
| |
|
| | gridLayout->addLayout(vboxLayout, 0, 0, 6, 1);
|
| |
|
| | vboxLayout1 = new QVBoxLayout();
|
| | vboxLayout1->setContentsMargins(0, 0, 0, 0);
|
| | labelSelected = new QLabel(this);
|
| | vboxLayout1->addWidget(labelSelected);
|
| |
|
| | selectedWidget = new QTreeWidget(this);
|
| | selectedWidget->setRootIsDecorated(false);
|
| | selectedWidget->setHeaderLabels(QStringList() << QString());
|
| | selectedWidget->header()->hide();
|
| | vboxLayout1->addWidget(selectedWidget);
|
| |
|
| | gridLayout->addLayout(vboxLayout1, 0, 2, 6, 1);
|
| |
|
| | addButton->setText(QString());
|
| | removeButton->setText(QString());
|
| | upButton->setText(QString());
|
| | downButton->setText(QString());
|
| |
|
| | labelAvailable->setText(QApplication::translate("Gui::ActionSelector", "Available:"));
|
| | labelSelected->setText(QApplication::translate("Gui::ActionSelector", "Selected:"));
|
| | addButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Add"));
|
| | removeButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Remove"));
|
| | upButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move up"));
|
| | downButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move down"));
|
| | }
|
| |
|
| | ActionSelector::~ActionSelector()
|
| | {}
|
| |
|
| |
|
| |
|
| | InputField::InputField(QWidget* parent)
|
| | : QLineEdit(parent)
|
| | , Value(0)
|
| | , Maximum(std::numeric_limits<int>::max())
|
| | , Minimum(-std::numeric_limits<int>::max())
|
| | , StepSize(1.0)
|
| | , HistorySize(5)
|
| | {}
|
| |
|
| | InputField::~InputField()
|
| | {}
|
| |
|
| |
|
| | void InputField::setParamGrpPath(const QByteArray& path)
|
| | {
|
| | m_sPrefGrp = path;
|
| | }
|
| |
|
| |
|
| | QByteArray InputField::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| |
|
| | void InputField::setValue(double quant)
|
| | {
|
| | Value = quant;
|
| | setText(QString("%1 %2").arg(Value).arg(UnitStr));
|
| | }
|
| |
|
| |
|
| | double InputField::getQuantity() const
|
| | {
|
| | return Value;
|
| | }
|
| |
|
| |
|
| | double InputField::singleStep(void) const
|
| | {
|
| | return StepSize;
|
| | }
|
| |
|
| |
|
| | void InputField::setSingleStep(double s)
|
| | {
|
| | StepSize = s;
|
| | }
|
| |
|
| |
|
| | double InputField::maximum(void) const
|
| | {
|
| | return Maximum;
|
| | }
|
| |
|
| |
|
| | void InputField::setMaximum(double m)
|
| | {
|
| | Maximum = m;
|
| | }
|
| |
|
| |
|
| | double InputField::minimum(void) const
|
| | {
|
| | return Minimum;
|
| | }
|
| |
|
| |
|
| | void InputField::setMinimum(double m)
|
| | {
|
| | Minimum = m;
|
| | }
|
| |
|
| | void InputField::setUnitText(QString str)
|
| | {
|
| | UnitStr = str;
|
| | setText(QString("%1 %2").arg(Value).arg(UnitStr));
|
| | }
|
| |
|
| | QString InputField::getUnitText(void)
|
| | {
|
| | return UnitStr;
|
| | }
|
| |
|
| |
|
| | int InputField::historySize(void) const
|
| | {
|
| | return HistorySize;
|
| | }
|
| |
|
| |
|
| | void InputField::setHistorySize(int i)
|
| | {
|
| | HistorySize = i;
|
| | }
|
| |
|
| |
|
| |
|
| | ExpressionLineEdit::ExpressionLineEdit(QWidget* parent)
|
| | : QLineEdit(parent)
|
| | , exactMatch {false}
|
| | {
|
| | completer = new QCompleter(this);
|
| | connect(this, &QLineEdit::textEdited, this, &ExpressionLineEdit::slotTextChanged);
|
| | }
|
| |
|
| | void ExpressionLineEdit::setExactMatch(bool enabled)
|
| | {
|
| | exactMatch = enabled;
|
| | if (completer) {
|
| | completer->setFilterMode(exactMatch ? Qt::MatchStartsWith : Qt::MatchContains);
|
| | }
|
| | }
|
| |
|
| | void ExpressionLineEdit::slotTextChanged(const QString& text)
|
| | {
|
| | Q_EMIT textChanged2(text, cursorPosition());
|
| | }
|
| |
|
| | void ExpressionLineEdit::slotCompleteText(const QString& completionPrefix, bool isActivated)
|
| | {
|
| | Q_UNUSED(completionPrefix)
|
| | Q_UNUSED(isActivated)
|
| | }
|
| |
|
| | void ExpressionLineEdit::slotCompleteTextHighlighted(const QString& completionPrefix)
|
| | {
|
| | slotCompleteText(completionPrefix, false);
|
| | }
|
| |
|
| | void ExpressionLineEdit::slotCompleteTextSelected(const QString& completionPrefix)
|
| | {
|
| | slotCompleteText(completionPrefix, true);
|
| | }
|
| |
|
| | void ExpressionLineEdit::keyPressEvent(QKeyEvent* e)
|
| | {
|
| | QLineEdit::keyPressEvent(e);
|
| | }
|
| |
|
| | void ExpressionLineEdit::contextMenuEvent(QContextMenuEvent* event)
|
| | {
|
| | QMenu* menu = createStandardContextMenu();
|
| |
|
| | if (completer) {
|
| | menu->addSeparator();
|
| | QAction* match = menu->addAction(tr("Exact match"));
|
| | match->setCheckable(true);
|
| | match->setChecked(completer->filterMode() == Qt::MatchStartsWith);
|
| | QObject::connect(match, &QAction::toggled, this, &Gui::ExpressionLineEdit::setExactMatch);
|
| | }
|
| | menu->setAttribute(Qt::WA_DeleteOnClose);
|
| |
|
| | menu->popup(event->globalPos());
|
| | }
|
| |
|
| |
|
| |
|
| | namespace Base
|
| | {
|
| |
|
| | Unit::Unit()
|
| | {}
|
| |
|
| | Unit::Unit(const QString& u)
|
| | : unit(u)
|
| | {}
|
| |
|
| | bool Unit::isEmpty() const
|
| | {
|
| | return unit.isEmpty();
|
| | }
|
| |
|
| | bool Unit::operator==(const Unit& that)
|
| | {
|
| | return this->unit == that.unit;
|
| | }
|
| |
|
| | bool Unit::operator!=(const Unit& that)
|
| | {
|
| | return this->unit != that.unit;
|
| | }
|
| |
|
| | const QString& Unit::getString() const
|
| | {
|
| | return unit;
|
| | }
|
| |
|
| | int QuantityFormat::defaultDenominator = 8;
|
| |
|
| |
|
| | QuantityFormat::QuantityFormat()
|
| | : option(OmitGroupSeparator | RejectGroupSeparator)
|
| | , format(Fixed)
|
| | , precision(4)
|
| | , denominator(defaultDenominator)
|
| | {}
|
| |
|
| | Quantity::Quantity()
|
| | : value(0)
|
| | , unit()
|
| | {}
|
| |
|
| | Quantity::Quantity(double v, const Unit& u)
|
| | : value(v)
|
| | , unit(u)
|
| | {}
|
| |
|
| | Quantity Quantity::parse(const QString& str)
|
| | {
|
| | bool ok;
|
| | QString txt = str;
|
| | QString unit;
|
| | while (!txt.isEmpty() && txt[txt.length() - 1].isLetter()) {
|
| | unit.prepend(txt[txt.length() - 1]);
|
| | txt.chop(1);
|
| | }
|
| |
|
| | double v = QLocale::system().toDouble(txt, &ok);
|
| |
|
| |
|
| | return Quantity(v, Unit(unit));
|
| | }
|
| |
|
| | void Quantity::setValue(double v)
|
| | {
|
| | value = v;
|
| | }
|
| |
|
| | double Quantity::getValue() const
|
| | {
|
| | return value;
|
| | }
|
| |
|
| | void Quantity::setUnit(const Unit& u)
|
| | {
|
| | unit = u;
|
| | }
|
| |
|
| | Unit Quantity::getUnit() const
|
| | {
|
| | return unit;
|
| | }
|
| |
|
| | QString Quantity::getUserString() const
|
| | {
|
| | QLocale Lc;
|
| | const QuantityFormat& format = getFormat();
|
| | if (format.option != QuantityFormat::None) {
|
| | uint opt = static_cast<uint>(format.option);
|
| | Lc.setNumberOptions(static_cast<QLocale::NumberOptions>(opt));
|
| | }
|
| |
|
| | QString Ln = Lc.toString(value, format.toFormat(), format.precision);
|
| | return QString::fromUtf8("%1 %2").arg(Ln, unit.getString());
|
| | }
|
| |
|
| | QString Quantity::getUserString(double& factor, QString& unitString) const
|
| | {
|
| | factor = 1;
|
| | unitString = unit.getString();
|
| |
|
| | QLocale Lc;
|
| | const QuantityFormat& format = getFormat();
|
| | if (format.option != QuantityFormat::None) {
|
| | uint opt = static_cast<uint>(format.option);
|
| | Lc.setNumberOptions(static_cast<QLocale::NumberOptions>(opt));
|
| | }
|
| |
|
| | QString Ln = Lc.toString(value, format.toFormat(), format.precision);
|
| | return QString::fromUtf8("%1 %2").arg(Ln, unit.getString());
|
| | }
|
| |
|
| | }
|
| |
|
| | namespace Gui
|
| | {
|
| |
|
| | class QuantitySpinBoxPrivate
|
| | {
|
| | public:
|
| | QuantitySpinBoxPrivate()
|
| | : validInput(true)
|
| | , pendingEmit(false)
|
| | , unitValue(0)
|
| | , maximum(std::numeric_limits<int>::max())
|
| | , minimum(-std::numeric_limits<int>::max())
|
| | , singleStep(1.0)
|
| | {}
|
| | ~QuantitySpinBoxPrivate()
|
| | {}
|
| |
|
| | QString stripped(const QString& t, int* pos) const
|
| | {
|
| | QString text = t;
|
| | const int s = text.size();
|
| | text = text.trimmed();
|
| | if (pos) {
|
| | (*pos) -= (s - text.size());
|
| | }
|
| | return text;
|
| | }
|
| |
|
| | bool validate(QString& input, Base::Quantity& result) const
|
| | {
|
| | bool success = false;
|
| | QString tmp = input;
|
| | int pos = 0;
|
| | QValidator::State state;
|
| | Base::Quantity res = validateAndInterpret(tmp, pos, state);
|
| | res.setFormat(quantity.getFormat());
|
| | if (state == QValidator::Acceptable) {
|
| | success = true;
|
| | result = res;
|
| | input = tmp;
|
| | }
|
| | else if (state == QValidator::Intermediate) {
|
| | tmp = tmp.trimmed();
|
| | tmp += QLatin1Char(' ');
|
| | tmp += unitStr;
|
| | Base::Quantity res2 = validateAndInterpret(tmp, pos, state);
|
| | res2.setFormat(quantity.getFormat());
|
| | if (state == QValidator::Acceptable) {
|
| | success = true;
|
| | result = res2;
|
| | input = tmp;
|
| | }
|
| | }
|
| |
|
| | return success;
|
| | }
|
| | Base::Quantity validateAndInterpret(QString& input, int& pos, QValidator::State& state) const
|
| | {
|
| | Base::Quantity res;
|
| | const double max = this->maximum;
|
| | const double min = this->minimum;
|
| |
|
| | QString copy = input;
|
| |
|
| | int len = copy.size();
|
| |
|
| | const bool plus = max >= 0;
|
| | const bool minus = min <= 0;
|
| |
|
| | switch (len) {
|
| | case 0:
|
| | state = max != min ? QValidator::Intermediate : QValidator::Invalid;
|
| | goto end;
|
| | case 1:
|
| | if (copy.at(0) == locale.decimalPoint()) {
|
| | state = QValidator::Intermediate;
|
| | copy.prepend(QLatin1Char('0'));
|
| | pos++;
|
| | len++;
|
| | goto end;
|
| | }
|
| | else if (copy.at(0) == QLatin1Char('+')) {
|
| |
|
| | state = QValidator::Invalid;
|
| | goto end;
|
| | }
|
| | else if (copy.at(0) == QLatin1Char('-')) {
|
| | if (minus) {
|
| | state = QValidator::Intermediate;
|
| | }
|
| | else {
|
| | state = QValidator::Invalid;
|
| | }
|
| | goto end;
|
| | }
|
| | break;
|
| | case 2:
|
| | if (copy.at(1) == locale.decimalPoint() && (plus && copy.at(0) == QLatin1Char('+'))) {
|
| | state = QValidator::Intermediate;
|
| | goto end;
|
| | }
|
| | if (copy.at(1) == locale.decimalPoint() && (minus && copy.at(0) == QLatin1Char('-'))) {
|
| | state = QValidator::Intermediate;
|
| | copy.insert(1, QLatin1Char('0'));
|
| | pos++;
|
| | len++;
|
| | goto end;
|
| | }
|
| | break;
|
| | default:
|
| | break;
|
| | }
|
| |
|
| | {
|
| | if (copy.at(0) == locale.groupSeparator()) {
|
| | state = QValidator::Invalid;
|
| | goto end;
|
| | }
|
| | else if (len > 1) {
|
| | bool decOccurred = false;
|
| | for (int i = 0; i < copy.size(); i++) {
|
| | if (copy.at(i) == locale.decimalPoint()) {
|
| |
|
| | if (decOccurred) {
|
| | state = QValidator::Invalid;
|
| | goto end;
|
| | }
|
| | decOccurred = true;
|
| | }
|
| |
|
| | else if (!(copy.at(i) == locale.groupSeparator() || copy.at(i).isDigit())) {
|
| | decOccurred = false;
|
| | }
|
| | }
|
| | }
|
| |
|
| | bool ok = false;
|
| | double value = min;
|
| |
|
| | QChar plus = QLatin1Char('+'), minus = QLatin1Char('-');
|
| |
|
| | if (locale.negativeSign() != minus) {
|
| | copy.replace(locale.negativeSign(), minus);
|
| | }
|
| | if (locale.positiveSign() != plus) {
|
| | copy.replace(locale.positiveSign(), plus);
|
| | }
|
| |
|
| | try {
|
| | QString copy2 = copy;
|
| | copy2.remove(locale.groupSeparator());
|
| |
|
| | res = Base::Quantity::parse(copy2);
|
| | value = res.getValue();
|
| | ok = true;
|
| | }
|
| | catch (Base::Exception&) {
|
| | }
|
| |
|
| | if (!ok) {
|
| |
|
| | state = QValidator::Intermediate;
|
| | }
|
| | else if (value >= min && value <= max) {
|
| | if (copy.endsWith(locale.decimalPoint())) {
|
| |
|
| | state = QValidator::Intermediate;
|
| | }
|
| | else if (res.getUnit().isEmpty() && !this->unit.isEmpty()) {
|
| |
|
| | state = QValidator::Intermediate;
|
| | }
|
| | else if (res.getUnit() != this->unit) {
|
| | state = QValidator::Invalid;
|
| | }
|
| | else {
|
| | state = QValidator::Acceptable;
|
| | }
|
| | }
|
| | else if (max == min) {
|
| |
|
| | state = QValidator::Invalid;
|
| | }
|
| | else {
|
| | if ((value >= 0 && value > max) || (value < 0 && value < min)) {
|
| | state = QValidator::Invalid;
|
| | }
|
| | else {
|
| | state = QValidator::Intermediate;
|
| | }
|
| | }
|
| | }
|
| | end:
|
| | if (state != QValidator::Acceptable) {
|
| | res.setValue(max > 0 ? min : max);
|
| | }
|
| |
|
| | input = copy;
|
| | return res;
|
| | }
|
| |
|
| | QLocale locale;
|
| | bool validInput;
|
| | bool pendingEmit;
|
| | QString validStr;
|
| | Base::Quantity quantity;
|
| | Base::Quantity cached;
|
| | Base::Unit unit;
|
| | double unitValue;
|
| | QString unitStr;
|
| | double maximum;
|
| | double minimum;
|
| | double singleStep;
|
| | };
|
| | }
|
| |
|
| | QuantitySpinBox::QuantitySpinBox(QWidget* parent)
|
| | : QAbstractSpinBox(parent)
|
| | , d_ptr(new QuantitySpinBoxPrivate())
|
| | {
|
| | d_ptr->locale = locale();
|
| | this->setContextMenuPolicy(Qt::DefaultContextMenu);
|
| | connect(lineEdit(), &QLineEdit::textChanged, this, &QuantitySpinBox::userInput);
|
| | connect(this, &QuantitySpinBox::editingFinished, this, &QuantitySpinBox::handlePendingEmit);
|
| | }
|
| |
|
| | QuantitySpinBox::~QuantitySpinBox()
|
| | {}
|
| |
|
| | void QuantitySpinBox::resizeEvent(QResizeEvent* event)
|
| | {
|
| | QAbstractSpinBox::resizeEvent(event);
|
| | }
|
| |
|
| | void Gui::QuantitySpinBox::keyPressEvent(QKeyEvent* event)
|
| | {
|
| | QAbstractSpinBox::keyPressEvent(event);
|
| | }
|
| |
|
| |
|
| | void QuantitySpinBox::updateText(const Base::Quantity& quant)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | double dFactor;
|
| | QString txt = getUserString(quant, dFactor, d->unitStr);
|
| | d->unitValue = quant.getValue() / dFactor;
|
| | lineEdit()->setText(txt);
|
| | handlePendingEmit();
|
| | }
|
| |
|
| | Base::Quantity QuantitySpinBox::value() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->quantity;
|
| | }
|
| |
|
| | double QuantitySpinBox::rawValue() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->quantity.getValue();
|
| | }
|
| |
|
| | void QuantitySpinBox::setValue(const Base::Quantity& value)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | d->quantity = value;
|
| |
|
| | if (d->quantity.getValue() > d->maximum) {
|
| | d->quantity.setValue(d->maximum);
|
| | }
|
| | if (d->quantity.getValue() < d->minimum) {
|
| | d->quantity.setValue(d->minimum);
|
| | }
|
| |
|
| | d->unit = value.getUnit();
|
| |
|
| | updateText(value);
|
| | }
|
| |
|
| | void QuantitySpinBox::setValue(double value)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | setValue(Base::Quantity(value, d->unit));
|
| | }
|
| |
|
| | bool QuantitySpinBox::hasValidInput() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->validInput;
|
| | }
|
| |
|
| |
|
| | void QuantitySpinBox::userInput(const QString& text)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | d->pendingEmit = true;
|
| |
|
| | QString tmp = text;
|
| | Base::Quantity res;
|
| | if (d->validate(tmp, res)) {
|
| | d->validStr = tmp;
|
| | d->validInput = true;
|
| | }
|
| | else {
|
| | d->validInput = false;
|
| | return;
|
| | }
|
| |
|
| | if (keyboardTracking()) {
|
| | d->cached = res;
|
| | handlePendingEmit();
|
| | }
|
| | else {
|
| | d->cached = res;
|
| | }
|
| | }
|
| |
|
| | void QuantitySpinBox::handlePendingEmit()
|
| | {
|
| | updateFromCache(true);
|
| | }
|
| |
|
| | void QuantitySpinBox::updateFromCache(bool notify)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | if (d->pendingEmit) {
|
| | double factor;
|
| | const Base::Quantity& res = d->cached;
|
| | QString text = getUserString(res, factor, d->unitStr);
|
| | d->unitValue = res.getValue() / factor;
|
| | d->quantity = res;
|
| |
|
| |
|
| | if (notify) {
|
| | d->pendingEmit = false;
|
| | valueChanged(res);
|
| | valueChanged(res.getValue());
|
| | textChanged(text);
|
| | }
|
| | }
|
| | }
|
| |
|
| | Base::Unit QuantitySpinBox::unit() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->unit;
|
| | }
|
| |
|
| | void QuantitySpinBox::setUnit(const Base::Unit& unit)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | d->unit = unit;
|
| | d->quantity.setUnit(unit);
|
| | updateText(d->quantity);
|
| | }
|
| |
|
| | void QuantitySpinBox::setUnitText(const QString& str)
|
| | {
|
| | try {
|
| | Base::Quantity quant = Base::Quantity::parse(str);
|
| | setUnit(quant.getUnit());
|
| | }
|
| | catch (const Base::Exception&) {
|
| | }
|
| | }
|
| |
|
| | QString QuantitySpinBox::unitText(void)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | return d->unitStr;
|
| | }
|
| |
|
| | double QuantitySpinBox::singleStep() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->singleStep;
|
| | }
|
| |
|
| | void QuantitySpinBox::setSingleStep(double value)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | if (value >= 0) {
|
| | d->singleStep = value;
|
| | }
|
| | }
|
| |
|
| | double QuantitySpinBox::minimum() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->minimum;
|
| | }
|
| |
|
| | void QuantitySpinBox::setMinimum(double minimum)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | d->minimum = minimum;
|
| | }
|
| |
|
| | double QuantitySpinBox::maximum() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->maximum;
|
| | }
|
| |
|
| | void QuantitySpinBox::setMaximum(double maximum)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | d->maximum = maximum;
|
| | }
|
| |
|
| | void QuantitySpinBox::setRange(double minimum, double maximum)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | d->minimum = minimum;
|
| | d->maximum = maximum;
|
| | }
|
| |
|
| | int QuantitySpinBox::decimals() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | return d->quantity.getFormat().precision;
|
| | }
|
| |
|
| | void QuantitySpinBox::setDecimals(int v)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | Base::QuantityFormat f = d->quantity.getFormat();
|
| | f.precision = v;
|
| | d->quantity.setFormat(f);
|
| | updateText(d->quantity);
|
| | }
|
| |
|
| | void QuantitySpinBox::clearSchema()
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | updateText(d->quantity);
|
| | }
|
| |
|
| | QString QuantitySpinBox::getUserString(const Base::Quantity& val, double& factor, QString& unitString) const
|
| | {
|
| | return val.getUserString(factor, unitString);
|
| | }
|
| |
|
| | QString QuantitySpinBox::getUserString(const Base::Quantity& val) const
|
| | {
|
| | return val.getUserString();
|
| | }
|
| |
|
| | QAbstractSpinBox::StepEnabled QuantitySpinBox::stepEnabled() const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| | if (isReadOnly() ) {
|
| | return StepNone;
|
| | }
|
| | if (wrapping()) {
|
| | return StepEnabled(StepUpEnabled | StepDownEnabled);
|
| | }
|
| | StepEnabled ret = StepNone;
|
| | if (d->quantity.getValue() < d->maximum) {
|
| | ret |= StepUpEnabled;
|
| | }
|
| | if (d->quantity.getValue() > d->minimum) {
|
| | ret |= StepDownEnabled;
|
| | }
|
| | return ret;
|
| | }
|
| |
|
| | void QuantitySpinBox::stepBy(int steps)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| | updateFromCache(false);
|
| |
|
| | double step = d->singleStep * steps;
|
| | double val = d->unitValue + step;
|
| | if (val > d->maximum) {
|
| | val = d->maximum;
|
| | }
|
| | else if (val < d->minimum) {
|
| | val = d->minimum;
|
| | }
|
| |
|
| | lineEdit()->setText(QString::fromUtf8("%L1 %2").arg(val).arg(d->unitStr));
|
| | updateFromCache(true);
|
| | update();
|
| | selectNumber();
|
| | }
|
| |
|
| | QSize QuantitySpinBox::sizeHint() const
|
| | {
|
| | ensurePolished();
|
| |
|
| | const QFontMetrics fm(fontMetrics());
|
| | int frameWidth = lineEdit()->style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth);
|
| | int iconHeight = fm.height() - frameWidth;
|
| | int h = lineEdit()->sizeHint().height();
|
| | int w = 0;
|
| |
|
| | QString s = QLatin1String("000000000000000000");
|
| | QString fixedContent = QLatin1String(" ");
|
| | s += fixedContent;
|
| |
|
| | w = fm.horizontalAdvance(s);
|
| | w += 2;
|
| | w += iconHeight;
|
| |
|
| | QStyleOptionSpinBox opt;
|
| | initStyleOption(&opt);
|
| | QSize hint(w, h);
|
| | QSize size = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
|
| | return size;
|
| | }
|
| |
|
| | QSize QuantitySpinBox::minimumSizeHint() const
|
| | {
|
| | ensurePolished();
|
| |
|
| | const QFontMetrics fm(fontMetrics());
|
| | int frameWidth = lineEdit()->style()->pixelMetric(QStyle::PM_SpinBoxFrameWidth);
|
| | int iconHeight = fm.height() - frameWidth;
|
| | int h = lineEdit()->minimumSizeHint().height();
|
| | int w = 0;
|
| |
|
| | QString s = QLatin1String("000000000000000000");
|
| | QString fixedContent = QLatin1String(" ");
|
| | s += fixedContent;
|
| |
|
| | w = fm.horizontalAdvance(s);
|
| | w += 2;
|
| | w += iconHeight;
|
| |
|
| | QStyleOptionSpinBox opt;
|
| | initStyleOption(&opt);
|
| | QSize hint(w, h);
|
| | QSize size = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
|
| | return size;
|
| | }
|
| |
|
| | void QuantitySpinBox::showEvent(QShowEvent* event)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | QAbstractSpinBox::showEvent(event);
|
| |
|
| | bool selected = lineEdit()->hasSelectedText();
|
| | updateText(d->quantity);
|
| | if (selected) {
|
| | selectNumber();
|
| | }
|
| | }
|
| |
|
| | void QuantitySpinBox::hideEvent(QHideEvent* event)
|
| | {
|
| | handlePendingEmit();
|
| | QAbstractSpinBox::hideEvent(event);
|
| | }
|
| |
|
| | void QuantitySpinBox::closeEvent(QCloseEvent* event)
|
| | {
|
| | handlePendingEmit();
|
| | QAbstractSpinBox::closeEvent(event);
|
| | }
|
| |
|
| |
|
| | void QuantitySpinBox::focusInEvent(QFocusEvent* event)
|
| | {
|
| | bool hasSel = lineEdit()->hasSelectedText();
|
| | QAbstractSpinBox::focusInEvent(event);
|
| |
|
| | if (event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason
|
| | || event->reason() == Qt::ShortcutFocusReason) {
|
| |
|
| | if (!hasSel) {
|
| | selectNumber();
|
| | }
|
| | }
|
| | }
|
| |
|
| | void QuantitySpinBox::focusOutEvent(QFocusEvent* event)
|
| | {
|
| | Q_D(QuantitySpinBox);
|
| |
|
| | int pos = 0;
|
| | QString text = lineEdit()->text();
|
| | QValidator::State state;
|
| | d->validateAndInterpret(text, pos, state);
|
| | if (state != QValidator::Acceptable) {
|
| | lineEdit()->setText(d->validStr);
|
| | }
|
| |
|
| | handlePendingEmit();
|
| |
|
| | QToolTip::hideText();
|
| | QAbstractSpinBox::focusOutEvent(event);
|
| | }
|
| |
|
| | void QuantitySpinBox::clear()
|
| | {
|
| | QAbstractSpinBox::clear();
|
| | }
|
| |
|
| | void QuantitySpinBox::selectNumber()
|
| | {
|
| | QString expr = QString::fromLatin1("^([%1%2]?[0-9\\%3]*)\\%4?([0-9]+(%5[%1%2]?[0-9]+)?)")
|
| | .arg(locale().negativeSign())
|
| | .arg(locale().positiveSign())
|
| | .arg(locale().groupSeparator())
|
| | .arg(locale().decimalPoint())
|
| | .arg(locale().exponential());
|
| | auto rmatch = QRegularExpression(expr).match(lineEdit()->text());
|
| | if (rmatch.hasMatch()) {
|
| | lineEdit()->setSelection(0, rmatch.capturedLength());
|
| | }
|
| | }
|
| |
|
| | QString QuantitySpinBox::textFromValue(const Base::Quantity& value) const
|
| | {
|
| | double factor;
|
| | QString unitStr;
|
| | QString str = getUserString(value, factor, unitStr);
|
| | if (qAbs(value.getValue()) >= 1000.0) {
|
| | str.remove(locale().groupSeparator());
|
| | }
|
| | return str;
|
| | }
|
| |
|
| | Base::Quantity QuantitySpinBox::valueFromText(const QString& text) const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| |
|
| | QString copy = text;
|
| | int pos = lineEdit()->cursorPosition();
|
| | QValidator::State state = QValidator::Acceptable;
|
| | Base::Quantity quant = d->validateAndInterpret(copy, pos, state);
|
| | if (state != QValidator::Acceptable) {
|
| | fixup(copy);
|
| | quant = d->validateAndInterpret(copy, pos, state);
|
| | }
|
| |
|
| | return quant;
|
| | }
|
| |
|
| | QValidator::State QuantitySpinBox::validate(QString& text, int& pos) const
|
| | {
|
| | Q_D(const QuantitySpinBox);
|
| |
|
| | QValidator::State state;
|
| | d->validateAndInterpret(text, pos, state);
|
| | return state;
|
| | }
|
| |
|
| | void QuantitySpinBox::fixup(QString& input) const
|
| | {
|
| | input.remove(locale().groupSeparator());
|
| | }
|
| |
|
| |
|
| |
|
| | PrefUnitSpinBox::PrefUnitSpinBox(QWidget* parent)
|
| | : QuantitySpinBox(parent)
|
| | {}
|
| |
|
| | PrefUnitSpinBox::~PrefUnitSpinBox()
|
| | {}
|
| |
|
| | QByteArray PrefUnitSpinBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefUnitSpinBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefUnitSpinBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefUnitSpinBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefQuantitySpinBox::PrefQuantitySpinBox(QWidget* parent)
|
| | : QuantitySpinBox(parent)
|
| | {}
|
| |
|
| | PrefQuantitySpinBox::~PrefQuantitySpinBox()
|
| | {}
|
| |
|
| | QByteArray PrefQuantitySpinBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefQuantitySpinBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefQuantitySpinBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefQuantitySpinBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | CommandIconView::CommandIconView(QWidget* parent)
|
| | : QListWidget(parent)
|
| | {
|
| | connect(this, &QListWidget::currentItemChanged, this, &CommandIconView::onSelectionChanged);
|
| | }
|
| |
|
| | CommandIconView::~CommandIconView()
|
| | {}
|
| |
|
| | void CommandIconView::startDrag(Qt::DropActions )
|
| | {
|
| | QList<QListWidgetItem*> items = selectedItems();
|
| | QByteArray itemData;
|
| | QDataStream dataStream(&itemData, QIODevice::WriteOnly);
|
| |
|
| | QPixmap pixmap;
|
| | dataStream << items.count();
|
| | for (QList<QListWidgetItem*>::ConstIterator it = items.begin(); it != items.end(); ++it) {
|
| | if (it == items.begin()) {
|
| | pixmap = ((*it)->data(Qt::UserRole)).value<QPixmap>();
|
| | }
|
| | dataStream << (*it)->text();
|
| | }
|
| |
|
| | QMimeData* mimeData = new QMimeData;
|
| | mimeData->setData("text/x-action-items", itemData);
|
| |
|
| | QDrag* drag = new QDrag(this);
|
| | drag->setMimeData(mimeData);
|
| | drag->setHotSpot(QPoint(pixmap.width() / 2, pixmap.height() / 2));
|
| | drag->setPixmap(pixmap);
|
| | drag->exec(Qt::MoveAction);
|
| | }
|
| |
|
| | void CommandIconView::onSelectionChanged(QListWidgetItem* item, QListWidgetItem*)
|
| | {
|
| | if (item) {
|
| | emitSelectionChanged(item->toolTip());
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | namespace Gui
|
| | {
|
| |
|
| | class UnsignedValidator: public QValidator
|
| | {
|
| | public:
|
| | UnsignedValidator(QObject* parent);
|
| | UnsignedValidator(uint minimum, uint maximum, QObject* parent);
|
| | ~UnsignedValidator();
|
| |
|
| | QValidator::State validate(QString&, int&) const;
|
| |
|
| | void setBottom(uint);
|
| | void setTop(uint);
|
| | virtual void setRange(uint bottom, uint top);
|
| |
|
| | uint bottom() const
|
| | {
|
| | return b;
|
| | }
|
| | uint top() const
|
| | {
|
| | return t;
|
| | }
|
| |
|
| | private:
|
| | uint b, t;
|
| | };
|
| |
|
| | UnsignedValidator::UnsignedValidator(QObject* parent)
|
| | : QValidator(parent)
|
| | {
|
| | b = 0;
|
| | t = std::numeric_limits<unsigned>::max();
|
| | }
|
| |
|
| | UnsignedValidator::UnsignedValidator(uint minimum, uint maximum, QObject* parent)
|
| | : QValidator(parent)
|
| | {
|
| | b = minimum;
|
| | t = maximum;
|
| | }
|
| |
|
| | UnsignedValidator::~UnsignedValidator()
|
| | {}
|
| |
|
| | QValidator::State UnsignedValidator::validate(QString& input, int&) const
|
| | {
|
| | QString stripped;
|
| | if (stripped.isEmpty()) {
|
| | return Intermediate;
|
| | }
|
| | bool ok;
|
| | uint entered = input.toUInt(&ok);
|
| | if (!ok) {
|
| | return Invalid;
|
| | }
|
| | else if (entered < b) {
|
| | return Intermediate;
|
| | }
|
| | else if (entered > t) {
|
| | return Invalid;
|
| | }
|
| |
|
| |
|
| | else {
|
| | return Acceptable;
|
| | }
|
| | }
|
| |
|
| | void UnsignedValidator::setRange(uint minimum, uint maximum)
|
| | {
|
| | b = minimum;
|
| | t = maximum;
|
| | }
|
| |
|
| | void UnsignedValidator::setBottom(uint bottom)
|
| | {
|
| | setRange(bottom, top());
|
| | }
|
| |
|
| | void UnsignedValidator::setTop(uint top)
|
| | {
|
| | setRange(bottom(), top);
|
| | }
|
| |
|
| | class UIntSpinBoxPrivate
|
| | {
|
| | public:
|
| | UnsignedValidator* mValidator;
|
| |
|
| | UIntSpinBoxPrivate()
|
| | : mValidator(0)
|
| | {}
|
| | unsigned mapToUInt(int v) const
|
| | {
|
| | using int_limits = std::numeric_limits<int>;
|
| | using uint_limits = std::numeric_limits<unsigned>;
|
| |
|
| | unsigned ui;
|
| | if (v == int_limits::min()) {
|
| | ui = 0;
|
| | }
|
| | else if (v == int_limits::max()) {
|
| | ui = uint_limits::max();
|
| | }
|
| | else if (v < 0) {
|
| | v -= int_limits::min();
|
| | ui = static_cast<unsigned>(v);
|
| | }
|
| | else {
|
| | ui = static_cast<unsigned>(v);
|
| | ui -= int_limits::min();
|
| | }
|
| | return ui;
|
| | }
|
| | int mapToInt(unsigned v) const
|
| | {
|
| | using int_limits = std::numeric_limits<int>;
|
| | using uint_limits = std::numeric_limits<unsigned>;
|
| |
|
| | int in;
|
| | if (v == uint_limits::max()) {
|
| | in = int_limits::max();
|
| | }
|
| | else if (v == 0) {
|
| | in = int_limits::min();
|
| | }
|
| | else if (v > int_limits::max()) {
|
| | v += int_limits::min();
|
| | in = static_cast<int>(v);
|
| | }
|
| | else {
|
| | in = v;
|
| | in += int_limits::min();
|
| | }
|
| | return in;
|
| | }
|
| | };
|
| |
|
| | }
|
| |
|
| |
|
| |
|
| | UIntSpinBox::UIntSpinBox(QWidget* parent)
|
| | : QSpinBox(parent)
|
| | {
|
| | d = new UIntSpinBoxPrivate;
|
| | d->mValidator = new UnsignedValidator(this->minimum(), this->maximum(), this);
|
| | connect(this, qOverload<int>(&QSpinBox::valueChanged), this, &UIntSpinBox::valueChange);
|
| | setRange(0, 99);
|
| | setValue(0);
|
| | updateValidator();
|
| | }
|
| |
|
| | UIntSpinBox::~UIntSpinBox()
|
| | {
|
| | delete d->mValidator;
|
| | delete d;
|
| | d = 0;
|
| | }
|
| |
|
| | void UIntSpinBox::setRange(uint minVal, uint maxVal)
|
| | {
|
| | int iminVal = d->mapToInt(minVal);
|
| | int imaxVal = d->mapToInt(maxVal);
|
| | QSpinBox::setRange(iminVal, imaxVal);
|
| | updateValidator();
|
| | }
|
| |
|
| | QValidator::State UIntSpinBox::validate(QString& input, int& pos) const
|
| | {
|
| | return d->mValidator->validate(input, pos);
|
| | }
|
| |
|
| | uint UIntSpinBox::value() const
|
| | {
|
| | return d->mapToUInt(QSpinBox::value());
|
| | }
|
| |
|
| | void UIntSpinBox::setValue(uint value)
|
| | {
|
| | QSpinBox::setValue(d->mapToInt(value));
|
| | }
|
| |
|
| | void UIntSpinBox::valueChange(int value)
|
| | {
|
| | unsignedChanged(d->mapToUInt(value));
|
| | }
|
| |
|
| | uint UIntSpinBox::minimum() const
|
| | {
|
| | return d->mapToUInt(QSpinBox::minimum());
|
| | }
|
| |
|
| | void UIntSpinBox::setMinimum(uint minVal)
|
| | {
|
| | uint maxVal = maximum();
|
| | if (maxVal < minVal) {
|
| | maxVal = minVal;
|
| | }
|
| | setRange(minVal, maxVal);
|
| | }
|
| |
|
| | uint UIntSpinBox::maximum() const
|
| | {
|
| | return d->mapToUInt(QSpinBox::maximum());
|
| | }
|
| |
|
| | void UIntSpinBox::setMaximum(uint maxVal)
|
| | {
|
| | uint minVal = minimum();
|
| | if (minVal > maxVal) {
|
| | minVal = maxVal;
|
| | }
|
| | setRange(minVal, maxVal);
|
| | }
|
| |
|
| | QString UIntSpinBox::textFromValue(int v) const
|
| | {
|
| | uint val = d->mapToUInt(v);
|
| | QString s;
|
| | s.setNum(val);
|
| | return s;
|
| | }
|
| |
|
| | int UIntSpinBox::valueFromText(const QString& text) const
|
| | {
|
| | bool ok;
|
| | QString s = text;
|
| | uint newVal = s.toUInt(&ok);
|
| | if (!ok && !(prefix().isEmpty() && suffix().isEmpty())) {
|
| | s = cleanText();
|
| | newVal = s.toUInt(&ok);
|
| | }
|
| |
|
| | return d->mapToInt(newVal);
|
| | }
|
| |
|
| | void UIntSpinBox::updateValidator()
|
| | {
|
| | d->mValidator->setRange(this->minimum(), this->maximum());
|
| | }
|
| |
|
| |
|
| |
|
| | IntSpinBox::IntSpinBox(QWidget* parent)
|
| | : QSpinBox(parent)
|
| | {}
|
| |
|
| | IntSpinBox::~IntSpinBox()
|
| | {}
|
| |
|
| |
|
| |
|
| | PrefSpinBox::PrefSpinBox(QWidget* parent)
|
| | : QSpinBox(parent)
|
| | {}
|
| |
|
| | PrefSpinBox::~PrefSpinBox()
|
| | {}
|
| |
|
| | QByteArray PrefSpinBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefSpinBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefSpinBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefSpinBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | DoubleSpinBox::DoubleSpinBox(QWidget* parent)
|
| | : QDoubleSpinBox(parent)
|
| | {}
|
| |
|
| | DoubleSpinBox::~DoubleSpinBox()
|
| | {}
|
| |
|
| |
|
| |
|
| | PrefDoubleSpinBox::PrefDoubleSpinBox(QWidget* parent)
|
| | : QDoubleSpinBox(parent)
|
| | {}
|
| |
|
| | PrefDoubleSpinBox::~PrefDoubleSpinBox()
|
| | {}
|
| |
|
| | QByteArray PrefDoubleSpinBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefDoubleSpinBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefDoubleSpinBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefDoubleSpinBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | ColorButton::ColorButton(QWidget* parent)
|
| | : QPushButton(parent)
|
| | , _allowChange(true)
|
| | , _allowTransparency(false)
|
| | , _drawFrame(true)
|
| | {
|
| | _col = palette().color(QPalette::Active, QPalette::Midlight);
|
| | connect(this, &ColorButton::clicked, this, &ColorButton::onChooseColor);
|
| | }
|
| |
|
| | ColorButton::~ColorButton()
|
| | {}
|
| |
|
| | void ColorButton::setColor(const QColor& c)
|
| | {
|
| | _col = c;
|
| | update();
|
| | }
|
| |
|
| | QColor ColorButton::color() const
|
| | {
|
| | return _col;
|
| | }
|
| |
|
| | void ColorButton::setAllowChangeColor(bool ok)
|
| | {
|
| | _allowChange = ok;
|
| | }
|
| |
|
| | bool ColorButton::allowChangeColor() const
|
| | {
|
| | return _allowChange;
|
| | }
|
| |
|
| | void ColorButton::setAllowTransparency(bool ok)
|
| | {
|
| | _allowTransparency = ok;
|
| | }
|
| |
|
| | bool ColorButton::allowTransparency() const
|
| | {
|
| | return _allowTransparency;
|
| | }
|
| |
|
| | void ColorButton::setDrawFrame(bool ok)
|
| | {
|
| | _drawFrame = ok;
|
| | }
|
| |
|
| | bool ColorButton::drawFrame() const
|
| | {
|
| | return _drawFrame;
|
| | }
|
| |
|
| | void ColorButton::paintEvent(QPaintEvent* e)
|
| | {
|
| |
|
| | QPushButton::paintEvent(e);
|
| |
|
| |
|
| | QPalette::ColorGroup group = isEnabled() ? hasFocus() ? QPalette::Active : QPalette::Inactive
|
| | : QPalette::Disabled;
|
| | QColor pen = palette().color(group, QPalette::ButtonText);
|
| | {
|
| | QPainter paint(this);
|
| | paint.setPen(pen);
|
| |
|
| | if (_drawFrame) {
|
| | paint.setBrush(QBrush(_col));
|
| | paint.drawRect(5, 5, width() - 10, height() - 10);
|
| | }
|
| | else {
|
| | paint.fillRect(5, 5, width() - 10, height() - 10, QBrush(_col));
|
| | }
|
| | }
|
| |
|
| |
|
| | QStyleOptionButton opt;
|
| | opt.initFrom(this);
|
| | opt.text = text();
|
| | opt.icon = icon();
|
| | opt.iconSize = iconSize();
|
| |
|
| | QStylePainter p(this);
|
| | p.drawControl(QStyle::CE_PushButtonLabel, opt);
|
| | }
|
| |
|
| | void ColorButton::onChooseColor()
|
| | {
|
| | if (!_allowChange) {
|
| | return;
|
| | }
|
| | QColor c = QColorDialog::getColor(_col, this);
|
| | if (c.isValid()) {
|
| | setColor(c);
|
| | Q_EMIT changed();
|
| | }
|
| | }
|
| |
|
| |
|
| |
|
| | PrefColorButton::PrefColorButton(QWidget* parent)
|
| | : ColorButton(parent)
|
| | {}
|
| |
|
| | PrefColorButton::~PrefColorButton()
|
| | {}
|
| |
|
| | QByteArray PrefColorButton::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefColorButton::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefColorButton::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefColorButton::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefLineEdit::PrefLineEdit(QWidget* parent)
|
| | : QLineEdit(parent)
|
| | {}
|
| |
|
| | PrefLineEdit::~PrefLineEdit()
|
| | {}
|
| |
|
| | QByteArray PrefLineEdit::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefLineEdit::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefLineEdit::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefLineEdit::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefComboBox::PrefComboBox(QWidget* parent)
|
| | : QComboBox(parent)
|
| | {
|
| | setEditable(false);
|
| | }
|
| |
|
| | PrefComboBox::~PrefComboBox()
|
| | {}
|
| |
|
| | QByteArray PrefComboBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefComboBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefComboBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefComboBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefCheckBox::PrefCheckBox(QWidget* parent)
|
| | : QCheckBox(parent)
|
| | {
|
| | setText("CheckBox");
|
| | }
|
| |
|
| | PrefCheckBox::~PrefCheckBox()
|
| | {}
|
| |
|
| | QByteArray PrefCheckBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefCheckBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefCheckBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefCheckBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefRadioButton::PrefRadioButton(QWidget* parent)
|
| | : QRadioButton(parent)
|
| | {
|
| | setText("RadioButton");
|
| | }
|
| |
|
| | PrefRadioButton::~PrefRadioButton()
|
| | {}
|
| |
|
| | QByteArray PrefRadioButton::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefRadioButton::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefRadioButton::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefRadioButton::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefSlider::PrefSlider(QWidget* parent)
|
| | : QSlider(parent)
|
| | {}
|
| |
|
| | PrefSlider::~PrefSlider()
|
| | {}
|
| |
|
| | QByteArray PrefSlider::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefSlider::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefSlider::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefSlider::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|
| |
|
| |
|
| | PrefFontBox::PrefFontBox(QWidget* parent)
|
| | : QFontComboBox(parent)
|
| | {}
|
| |
|
| | PrefFontBox::~PrefFontBox()
|
| | {}
|
| |
|
| | QByteArray PrefFontBox::entryName() const
|
| | {
|
| | return m_sPrefName;
|
| | }
|
| |
|
| | QByteArray PrefFontBox::paramGrpPath() const
|
| | {
|
| | return m_sPrefGrp;
|
| | }
|
| |
|
| | void PrefFontBox::setEntryName(const QByteArray& name)
|
| | {
|
| | m_sPrefName = name;
|
| | }
|
| |
|
| | void PrefFontBox::setParamGrpPath(const QByteArray& name)
|
| | {
|
| | m_sPrefGrp = name;
|
| | }
|
| |
|