Files
qad/libs/piqt_widgets/pivariant_edit_widgets.cpp
2022-12-20 10:04:37 +03:00

396 lines
12 KiB
C++

#include "pivariant_edit_widgets.h"
#include "pivaluetree.h"
#include "pivariant_edit_enum.h"
#include "pivarianttypes.h"
#include <QEvent>
#include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox>
#include <QToolButton>
REGISTER_PIVARIANTEDITOR(bool, PIVariantEditors::Bool);
REGISTER_PIVARIANTEDITOR(short, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(ushort, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(int, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(uint, PIVariantEditors::Int);
REGISTER_PIVARIANTEDITOR(float, PIVariantEditors::Double);
REGISTER_PIVARIANTEDITOR(double, PIVariantEditors::Double);
REGISTER_PIVARIANTEDITOR(PIString, PIVariantEditors::String);
REGISTER_PIVARIANTEDITOR(PITime, PIVariantEditors::Time);
REGISTER_PIVARIANTEDITOR(PIDate, PIVariantEditors::Date);
REGISTER_PIVARIANTEDITOR(PIDateTime, PIVariantEditors::DateTime);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::Color, PIVariantEditors::Color);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::Enum, PIVariantEditors::Enum);
REGISTER_PIVARIANTEDITOR(PINetworkAddress, PIVariantEditors::NetworkAddress);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::File, PIVariantEditors::File);
REGISTER_PIVARIANTEDITOR(PIVariantTypes::Dir, PIVariantEditors::Dir);
using Attribute = PIValueTree::Attribute;
// PIVariantEditors::Int
PIVariantMap PIVariantEditors::Int::attributes() const {
return {
{Attribute::minimum, widget->minimum() },
{Attribute::maximum, widget->maximum() },
{Attribute::singleStep, widget->singleStep()},
{Attribute::prefix, prefix },
{Attribute::suffix, suffix },
};
}
PIVariantMap PIVariantEditors::Int::defaultAttributes() {
return {
{Attribute::minimum, -std::numeric_limits<int>::max()},
{Attribute::maximum, std::numeric_limits<int>::max() },
{Attribute::singleStep, 1. },
{Attribute::prefix, "" },
{Attribute::suffix, "" },
};
}
void PIVariantEditors::Int::retranslate() {
widget->setPrefix(PIVariantEditorBase::vtTr(prefix));
widget->setSuffix(PIVariantEditorBase::vtTr(suffix));
}
void PIVariantEditors::Int::applyAttributes(const PIVariantMap & a) {
prefix = a.value(Attribute::prefix).toString();
suffix = a.value(Attribute::suffix).toString();
widget->setRange(a.value(Attribute::minimum, widget->minimum()).toInt(), a.value(Attribute::maximum, widget->maximum()).toInt());
widget->setSingleStep(a.value(Attribute::singleStep, widget->singleStep()).toInt());
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
retranslate();
}
// PIVariantEditors::Double
PIVariantMap PIVariantEditors::Double::attributes() const {
return {
{Attribute::minimum, widget->minimum() },
{Attribute::maximum, widget->maximum() },
{Attribute::singleStep, widget->singleStep()},
{Attribute::decimals, widget->decimals() },
{Attribute::prefix, prefix },
{Attribute::suffix, suffix },
};
}
PIVariantMap PIVariantEditors::Double::defaultAttributes() {
return {
{Attribute::minimum, -std::numeric_limits<double>::max()},
{Attribute::maximum, std::numeric_limits<double>::max() },
{Attribute::singleStep, 1. },
{Attribute::decimals, 3 },
{Attribute::prefix, "" },
{Attribute::suffix, "" },
};
}
void PIVariantEditors::Double::retranslate() {
widget->setPrefix(PIVariantEditorBase::vtTr(prefix));
widget->setSuffix(PIVariantEditorBase::vtTr(suffix));
}
void PIVariantEditors::Double::applyAttributes(const PIVariantMap & a) {
prefix = a.value(Attribute::prefix).toString();
suffix = a.value(Attribute::suffix).toString();
widget->setRange(a.value(Attribute::minimum, widget->minimum()).toDouble(), a.value(Attribute::maximum, widget->maximum()).toDouble());
widget->setSingleStep(a.value(Attribute::singleStep, widget->singleStep()).toDouble());
widget->setDecimals(a.value(Attribute::decimals, widget->decimals()).toInt());
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
retranslate();
}
// PIVariantEditors::String
PIVariantMap PIVariantEditors::String::attributes() const {
return {};
}
PIVariantMap PIVariantEditors::String::defaultAttributes() {
return {};
}
void PIVariantEditors::String::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
}
// PIVariantEditors::Color
PIVariantMap PIVariantEditors::Color::attributes() const {
return {
{"useAlpha", widget->useAlphaChannel()},
};
}
PIVariantMap PIVariantEditors::Color::defaultAttributes() {
return {
{"useAlpha", true},
};
}
void PIVariantEditors::Color::applyAttributes(const PIVariantMap & a) {
widget->setUseAlphaChannel(a.value("useAlpha", widget->useAlphaChannel()).toBool());
widget->setEnabled(!a.value(Attribute::readOnly, !widget->isEnabled()).toBool());
}
// PIVariantEditors::Time
void PIVariantEditors::Time::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
}
// PIVariantEditors::Date
void PIVariantEditors::Date::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
}
// PIVariantEditors::DateTime
void PIVariantEditors::DateTime::applyAttributes(const PIVariantMap & a) {
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
}
// PIVariantEditors::Enum
PIVariantEditors::Enum::Enum() {
widget = new QComboBox();
layout()->addWidget(widget);
edit_widget = new QWidget();
edit_widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
edit_widget->setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
QMargins m = edit_widget->layout()->contentsMargins();
edit_widget->layout()->setContentsMargins(m.left(), 0, 0, 0);
auto * b = new QToolButton();
b->setIcon(QIcon(":/icons/document-edit.png"));
connect(b, &QToolButton::clicked, this, [this]() {
PIValueTreeEditEnum dlg;
if (!dlg.showFor(src)) return;
setValue(PIVariant(dlg.ret));
});
edit_widget->layout()->addWidget(b);
layout()->setSpacing(0);
layout()->addWidget(edit_widget);
setFullEditMode(false);
}
void PIVariantEditors::Enum::setValue(const PIVariant & v) {
src = v.toEnum();
int sv = src.selectedValue();
widget->clear();
for (const auto & e: src.enum_list) {
widget->addItem(PI2QString(e.name), e.value);
if (e.value == sv) widget->setCurrentIndex(widget->count() - 1);
}
}
PIVariant PIVariantEditors::Enum::value() const {
src.selectValue(widget->currentData().toInt());
return src;
}
void PIVariantEditors::Enum::applyAttributes(const PIVariantMap & a) {
widget->setEnabled(!a.value(Attribute::readOnly, !widget->isEnabled()).toBool());
}
void PIVariantEditors::Enum::setFullEditMode(bool on) {
edit_widget->setVisible(on);
}
// PIVariantEditors::NetworkAddress
PIVariantEditors::NetworkAddress::NetworkAddress() {
widget = new QLineEdit();
widget->setInputMask("000.000.000.000:00000;_");
layout()->addWidget(widget);
}
void PIVariantEditors::NetworkAddress::setValue(const PIVariant & v) {
if (has_port)
widget->setText(PI2QString(v.toNetworkAddress().toString()));
else
widget->setText(PI2QString(v.toNetworkAddress().ipString()));
}
PIVariant PIVariantEditors::NetworkAddress::value() const {
return PINetworkAddress(Q2PIString(widget->text()));
}
PIVariantMap PIVariantEditors::NetworkAddress::attributes() const {
return {
{"port", has_port}
};
}
PIVariantMap PIVariantEditors::NetworkAddress::defaultAttributes() {
return {
{"port", true}
};
}
void PIVariantEditors::NetworkAddress::applyAttributes(const PIVariantMap & a) {
has_port = a.value("port", true).toBool();
if (has_port)
widget->setInputMask("000.000.000.000:00000;_");
else
widget->setInputMask("000.000.000.000;_");
widget->setReadOnly(a.value(Attribute::readOnly, widget->isReadOnly()).toBool());
}
// PIVariantEditors::FileBase
PIVariantEditors::FileBase::FileBase() {
filter = "All files(*)";
widget = new CLineEdit();
layout()->addWidget(widget);
sel_widget = new QWidget();
sel_widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
sel_widget->setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
QMargins m = sel_widget->layout()->contentsMargins();
sel_widget->layout()->setContentsMargins(m.left(), 0, 0, 0);
auto * b = new QToolButton();
b->setIcon(QIcon(":/icons/document-open.png"));
b->setToolTip(tr("Choose") + " ...");
connect(b, &QToolButton::clicked, this, [this]() {
QString ret;
if (is_dir)
ret = QFileDialog::getExistingDirectory(this, tr("Select directory"), widget->text());
else {
if (is_save)
ret = QFileDialog::getSaveFileName(this, tr("Select file"), widget->text(), PIVariantEditorBase::vtTr(filter));
else
ret = QFileDialog::getOpenFileName(this, tr("Select file"), widget->text(), PIVariantEditorBase::vtTr(filter));
}
if (ret.isEmpty()) return;
if (!is_abs) ret = QDir::current().relativeFilePath(ret);
widget->setText(ret);
});
sel_widget->layout()->addWidget(b);
layout()->addWidget(sel_widget);
edit_widget = new QWidget();
edit_widget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
edit_widget->setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
m = edit_widget->layout()->contentsMargins();
edit_widget->layout()->setContentsMargins(m.left(), 0, 0, 0);
b = new QToolButton();
b->setIcon(QIcon(":/icons/document-edit.png"));
b->setPopupMode(QToolButton::InstantPopup);
b->setMenu(&edit_menu);
edit_widget->layout()->addWidget(b);
layout()->setSpacing(0);
layout()->addWidget(edit_widget);
setFullEditMode(false);
}
PIVariantMap PIVariantEditors::FileBase::attributes() const {
return {
{Attribute::filter, filter },
{Attribute::absolutePath, is_abs },
{Attribute::onlyExisting, !is_save}
};
}
PIVariantMap PIVariantEditors::FileBase::defaultAttributes() {
return {
{Attribute::filter, "" },
{Attribute::absolutePath, false},
{Attribute::onlyExisting, true }
};
}
void PIVariantEditors::FileBase::applyAttributes(const PIVariantMap & a) {
filter = a.value(Attribute::filter).toString();
is_abs = a.value(Attribute::absolutePath).toBool();
is_save = !a.value(Attribute::onlyExisting, true).toBool();
bool ro = a.value(Attribute::readOnly).toBool();
widget->setReadOnly(ro);
sel_widget->setHidden(ro);
if (act_abs) act_abs->setChecked(is_abs);
if (act_save) act_save->setChecked(!is_save);
}
void PIVariantEditors::FileBase::setFullEditMode(bool on) {
edit_widget->setVisible(on);
}
void PIVariantEditors::FileBase::createMenu() {
act_abs = edit_menu.addAction(tr("Absolute path"), this, [this](bool on) { is_abs = on; });
act_abs->setCheckable(true);
act_abs->setChecked(is_abs);
if (is_dir) return;
act_save = edit_menu.addAction(tr("Existing only"), this, [this](bool on) { is_save = !on; });
act_save->setCheckable(true);
act_save->setChecked(!is_save);
edit_menu.addAction(tr("Set filter ..."), this, [this]() {
bool ok = false;
QString nf = QInputDialog::getText(nullptr, tr("Select filter"), tr("Input filter:"), QLineEdit::Normal, PI2QString(filter), &ok);
if (!ok) return;
filter = Q2PIString(nf);
});
}
// PIVariantEditors::File
void PIVariantEditors::File::setValue(const PIVariant & v) {
widget->setText(PI2QString(v.toFile().file));
}
PIVariant PIVariantEditors::File::value() const {
PIVariantTypes::File v;
v.file = Q2PIString(widget->text());
return v;
}
// PIVariantEditors::Dir
void PIVariantEditors::Dir::setValue(const PIVariant & v) {
widget->setText(PI2QString(v.toDir().dir));
}
PIVariant PIVariantEditors::Dir::value() const {
PIVariantTypes::Dir v;
v.dir = Q2PIString(widget->text());
return v;
}