ProfileDefaultValueEditWidget.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package ArmarX::
17* @author Valerij Wittenbeck (valerij.wittenbeck at student dot kit dot edu
18* @date 2015
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
25#include <QFileDialog>
26#include <QLineEdit>
27#include <QTextEdit>
28#include <QtGui>
29
36
37#include <ArmarXGui/gui-plugins/StatechartEditorPlugin/ui_ProfileDefaultValueEditWidget.h>
40
41using namespace armarx;
42
44 QString jsonValue,
45 Ice::CommunicatorPtr communicator,
46 QWidget* parent) :
47 QWidget(parent),
49 typeString(typeString),
50 jsonValue(jsonValue),
51 communicator(communicator),
52 editable(true)
53{
54 ui->setupUi(this);
55
56 QLineEdit* lineEdit = new QLineEdit;
57 ui->value->insertWidget(eLineEdit, lineEdit);
58
59 QPushButton* editButton = new QPushButton("Edit");
60 ui->value->insertWidget(eEditButton, editButton);
61 connect(editButton, SIGNAL(clicked()), this, SLOT(editDefaultButtonClicked()));
62
63 QPushButton* setButton = new QPushButton("Click to set");
64 setButton->setStyleSheet("color: #888;");
65 setButton->setFlat(true);
66 ui->value->insertWidget(eSetButton, setButton);
67 connect(setButton, SIGNAL(clicked()), this, SLOT(setButtonClicked()));
68
69 int typeId = Variant::hashTypeName(typeString.toStdString());
70
71 if (typeId == VariantType::String)
72 {
73 lineEdit->setValidator(NULL);
74 }
75 else if (typeId == VariantType::Int || typeId == VariantType::Long)
76 {
77 // do not use QIntValidator, accepts random stuff.
78 QRegExp rx("-?\\d+");
79 QValidator* validator = new QRegExpValidator(rx, this);
80 lineEdit->setValidator(validator);
81 }
82 else if (typeId == VariantType::Bool)
83 {
84 QRegExp rx("(true|false)");
85 QValidator* validator = new QRegExpValidator(rx, this);
86 lineEdit->setValidator(validator);
87 }
88 else if (typeId == VariantType::Float || typeId == VariantType::Double)
89 {
90 // do not use QDoubleValidator. QDoubleValidator is buggy. accepts: 1e16.5
91 // use JSON compliant regex. See class StructuralJsonParser.
92 QRegExp rx("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
93 QValidator* validator = new QRegExpValidator(rx, this);
94 lineEdit->setValidator(validator);
95 }
96
97 if (jsonValue.isEmpty())
98 {
99 lineEdit->setText("");
100 }
101 else
102 {
104 typeString.toUtf8().data()));
105 std::string compressedValue =
106 nav.isValue() ? nav.asValue()->rawValue() : nav.getData()->toJsonString(0);
107 lineEdit->setText(QString::fromUtf8(compressedValue.c_str()));
108 }
109
110
111 connect(ui->pushButtonDelete, SIGNAL(clicked()), this, SLOT(resetValue()));
112
113 if (jsonValue.size() == 0)
114 {
115 resetValue();
116 }
117 else
118 {
119 setButtonClicked();
120 }
121}
122
126
127QString
129{
130 return typeString;
131}
132
133void
135{
136 this->editable = editable;
137 ui->value->widget(eLineEdit)->setEnabled(editable);
138}
139
140std::optional<QString>
142{
143 if (ui->value->currentIndex() == Widget::eLineEdit)
144 {
145 return qobject_cast<QLineEdit*>(ui->value->currentWidget())->text();
146 }
147 else if (ui->value->currentIndex() == Widget::eEditButton)
148 {
149 return jsonValue;
150 }
151
152 return std::nullopt;
153}
154
155std::optional<QString>
157{
158 //JSONObjectPtr jsonObject = new JSONObject(communicator);
159 int index = ui->value->currentIndex();
160
161 if (index == Widget::eEditButton)
162 {
163 return jsonValue;
164 }
165 else if (index == Widget::eLineEdit)
166 {
167 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(ui->value->currentWidget());
168 std::string verboseJson = VariantJsonCompressor::DecompressBasicVariant(
169 valueEdit->text().toUtf8().data(), typeString.toStdString());
170 return QString::fromUtf8(verboseJson.c_str());
171 }
172
173 return std::nullopt;
174}
175
176VariantContainerBasePtr
178{
179 VariantContainerBasePtr result;
180
181 if (ui->value->currentIndex() == eLineEdit)
182 {
183 QLineEdit* valueEdit = qobject_cast<QLineEdit*>(ui->value->currentWidget());
184 int typeId = Variant::hashTypeName(typeString.toStdString());
185 Variant variant;
186
187 if (typeId == VariantType::Int)
188 {
189 variant.setInt(valueEdit->text().toInt());
190 }
191 else if (typeId == VariantType::Long)
192 {
193 variant.setLong(valueEdit->text().toLong());
194 }
195 else if (typeId == VariantType::Bool)
196 {
197 variant.setBool(valueEdit->text().compare("true", Qt::CaseInsensitive) == 0 ||
198 valueEdit->text() == "1");
199 }
200 else if (typeId == VariantType::Float)
201 {
202 variant.setFloat(valueEdit->text().toFloat());
203 }
204 else if (typeId == VariantType::Double)
205 {
206 variant.setDouble(valueEdit->text().toDouble());
207 }
208 else if (typeId == VariantType::String)
209 {
210 variant.setString(valueEdit->text().trimmed().toStdString());
211 }
212
213 result = new SingleVariant(variant);
214 }
215 else if (ui->value->currentIndex() == eEditButton)
216 {
217 if (jsonValue.isEmpty())
218 {
219 return result;
220 }
221
222 JSONObjectPtr jsonObject = new JSONObject(communicator);
223 // ARMARX_INFO_S << VAROUT(jsonValue.toUtf8().data());
224 jsonObject->fromString(jsonValue.toUtf8().data());
225
226 try
227 {
228 SerializablePtr obj = jsonObject->deserializeIceObject();
229 result = VariantContainerBasePtr::dynamicCast(obj);
230
231 if (!result)
232 {
233 // must be simple variant
234 result = new SingleVariant(Variant(VariantDataPtr::dynamicCast(obj)));
235 }
236 }
237 catch (std::exception& e)
238 {
239 ARMARX_WARNING_S << "JSON string for type " << typeString.toStdString()
240 << " could not be deserialized: " << e.what();
241 return result;
242 }
243 }
244
245 return result;
246}
247
248void
249ProfileDefaultValueEditWidget::resetValue()
250{
251 this->setFocus();
252 // ui->value->widget(eSetButton)->setFocus();
253 ui->value->setCurrentIndex(eSetButton);
254 ui->pushButtonDelete->setEnabled(false);
255 ui->pushButtonDelete->hide();
256 // ui->value->widget(eSetButton)->setFocus();
257 jsonValue.clear();
258 auto lineEdit = qobject_cast<QLineEdit*>(ui->value->widget(eLineEdit));
259 lineEdit->setText("");
260}
261
262void
263ProfileDefaultValueEditWidget::setButtonClicked()
264{
265 ui->pushButtonDelete->setEnabled(true);
266 ui->pushButtonDelete->show();
267 int variantId = Variant::hashTypeName(typeString.toStdString());
268
269 if (variantId == VariantType::String || variantId == VariantType::Int ||
270 variantId == VariantType::Long || variantId == VariantType::Bool ||
271 variantId == VariantType::Float || variantId == VariantType::Double)
272 {
273 ui->value->setCurrentIndex(eLineEdit);
274 }
275 else
276 {
277 initEditButton();
278 ui->value->setCurrentIndex(eEditButton);
279 }
280}
281
282void
283ProfileDefaultValueEditWidget::initEditButton()
284{
285 try
286 {
287 if (jsonValue.isEmpty())
288 {
289
290 auto variantContainerType = VariantContainerType::FromString(typeString.toStdString());
291 JSONObjectPtr jsonObject = new JSONObject(communicator);
292
293 // ARMARX_INFO_S << VAROUT(variantContainerType->typeId);
294
295 Ice::ValueFactoryPtr factory =
296 communicator->getValueFactoryManager()->find(variantContainerType->typeId);
297
298 if (!factory)
299 {
300 ARMARX_WARNING << "Could not get ObjectFactory for Variant "
301 << variantContainerType->typeId;
302 }
303 else
304 {
305 ARMARX_INFO_S << variantContainerType->typeId;
306 Ice::ValuePtr valPtr = factory->create(variantContainerType->typeId);
307 ARMARX_INFO_S << valPtr.get() << " " << SerializablePtr::dynamicCast(valPtr).get();
308
309 VariantContainerBasePtr container = VariantContainerBasePtr::dynamicCast(valPtr);
310
311 if (container)
312 {
313 // TODO: make better with dummy element function for all containers/variants?!
314 // ARMARX_INFO_S << VAROUT(variantContainerType->subType->typeId);
315 Ice::ValueFactoryPtr subfactory = communicator->getValueFactoryManager()->find(
316 variantContainerType->subType->typeId);
317
318 if (!subfactory)
319 {
320 // ARMARX_INFO_S << " no factory";
321 subfactory = IceInternal::factoryTable->getValueFactory(
322 variantContainerType->subType->typeId);
323 }
324
325 if (subfactory)
326 {
327 Ice::ValuePtr subObj =
328 subfactory->create(variantContainerType->subType->typeId);
329 VariantDataPtr var = VariantDataPtr::dynamicCast(subObj);
330
332 SingleTypeVariantListPtr::dynamicCast(valPtr);
333
334 if (var && list)
335 {
336 list->addVariant(Variant(var));
337 }
338
339 StringValueMapPtr map = StringValueMapPtr::dynamicCast(valPtr);
340
341 if (var && map)
342 {
343 map->addVariant("mykey", Variant(var));
344 }
345 }
346 else
347 {
348 ARMARX_INFO_S << " no base factory";
349 }
350 }
351 else
352 {
353 container = new SingleVariant(Variant(VariantDataPtr::dynamicCast(valPtr)));
354 }
355
356 jsonObject->serializeIceObject(container);
357 }
358
359 jsonValue = QString::fromStdString(jsonObject->asString(true));
360 }
361 }
362 catch (...)
363 {
365 ui->value->widget(eEditButton)->setEnabled(false);
366 }
367}
368
369void
370ProfileDefaultValueEditWidget::editDefaultButtonClicked()
371{
372 EditDefaultValueDialog d(jsonValue, typeString, communicator);
373 if (d.exec() == QDialog::Accepted)
374 {
375 jsonValue = d.getJson();
376 }
377}
uint8_t index
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition JSONObject.h:44
ProfileDefaultValueEditWidget(QString typeString, QString jsonValue, Ice::CommunicatorPtr communicator, QWidget *parent=0)
The SingleVariant class is required to store single Variant instances in VariantContainer subclasses.
static ContainerTypePtr FromString(const std::string &typeStr)
static JsonDataPtr CompressToJson(const std::string &json, const std::string &variantBaseTypeName)
static std::string DecompressBasicVariant(const std::string &value, const std::string &variantBaseTypeName)
The Variant class is described here: Variants.
Definition Variant.h:224
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition Variant.cpp:372
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition Variant.cpp:390
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition Variant.cpp:355
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition Variant.cpp:428
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition Variant.cpp:447
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition Variant.cpp:813
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition Variant.cpp:409
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
ArmarX Headers.
const VariantTypeId String
Definition Variant.h:921
const VariantTypeId Int
Definition Variant.h:917
const VariantTypeId Long
Definition Variant.h:918
const VariantTypeId Bool
Definition Variant.h:916
const VariantTypeId Double
Definition Variant.h:920
const VariantTypeId Float
Definition Variant.h:919
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< SingleTypeVariantList > SingleTypeVariantListPtr
void handleExceptions()
IceInternal::Handle< StringValueMap > StringValueMapPtr
IceInternal::Handle< JSONObject > JSONObjectPtr
Definition JSONObject.h:34