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 
41 using 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  {
103  JPathNavigator nav(VariantJsonCompressor::CompressToJson(jsonValue.toUtf8().data(),
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 
124 {
125 }
126 
127 QString
129 {
130  return typeString;
131 }
132 
133 void
135 {
136  this->editable = editable;
137  ui->value->widget(eLineEdit)->setEnabled(editable);
138 }
139 
140 std::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 
155 std::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 
176 VariantContainerBasePtr
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 
248 void
249 ProfileDefaultValueEditWidget::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 
262 void
263 ProfileDefaultValueEditWidget::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 
282 void
283 ProfileDefaultValueEditWidget::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 
369 void
370 ProfileDefaultValueEditWidget::editDefaultButtonClicked()
371 {
372  EditDefaultValueDialog d(jsonValue, typeString, communicator);
373  if (d.exec() == QDialog::Accepted)
374  {
375  jsonValue = d.getJson();
376  }
377 }
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::ProfileDefaultValueEditWidget::getVariantContainer
VariantContainerBasePtr getVariantContainer()
Definition: ProfileDefaultValueEditWidget.cpp:177
armarx::ProfileDefaultValueEditWidget
Definition: ProfileDefaultValueEditWidget.h:43
SingleTypeVariantList.h
EditDefaultValueDialog.h
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
armarx::Variant::setLong
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:372
armarx::ProfileDefaultValueEditWidget::getValueAsString
std::optional< QString > getValueAsString()
Definition: ProfileDefaultValueEditWidget.cpp:141
armarx::JPathNavigator::isValue
bool isValue() const
Definition: JPathNavigator.cpp:55
JSONObject.h
index
uint8_t index
Definition: EtherCATFrame.h:59
VariantContainer.h
list
list(APPEND SOURCES ${QT_RESOURCES}) set(COMPONENT_LIBS ArmarXGui ArmarXCoreObservers ArmarXCoreEigen3Variants PlotterController $
Definition: CMakeLists.txt:49
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
armarx::Variant::setString
void setString(const std::string &s, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to s.
Definition: Variant.cpp:428
armarx::ProfileDefaultValueEditWidget::~ProfileDefaultValueEditWidget
~ProfileDefaultValueEditWidget() override
Definition: ProfileDefaultValueEditWidget.cpp:123
armarx::ProfileDefaultValueEditWidget::setEditable
void setEditable(bool editable)
Definition: ProfileDefaultValueEditWidget.cpp:134
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:916
armarx::JPathNavigator
Definition: JPathNavigator.h:35
armarx::Variant::setInt
void setInt(int n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:355
IceInternal::Handle<::Ice::Communicator >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:920
StringValueMap.h
armarx::Variant::setDouble
void setDouble(double d, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to d.
Definition: Variant.cpp:409
armarx::EditDefaultValueDialog
Definition: EditDefaultValueDialog.h:38
armarx::Variant::setBool
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition: Variant.cpp:447
Ui
ArmarX Headers.
Definition: ArmarXMainWindow.h:54
armarx::SingleVariant
The SingleVariant class is required to store single Variant instances in VariantContainer subclasses.
Definition: VariantContainer.h:107
armarx::Variant::setFloat
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition: Variant.cpp:390
armarx::ProfileDefaultValueEditWidget::getValueAsJson
std::optional< QString > getValueAsJson()
Definition: ProfileDefaultValueEditWidget.cpp:156
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
ProfileDefaultValueEditWidget.h
armarx::VariantJsonCompressor::CompressToJson
static JsonDataPtr CompressToJson(const std::string &json, const std::string &variantBaseTypeName)
Definition: VariantJsonCompressor.cpp:239
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::JPathNavigator::getData
JsonDataPtr getData() const
Definition: JPathNavigator.cpp:248
VariantJsonCompressor.h
armarx::VariantJsonCompressor::DecompressBasicVariant
static std::string DecompressBasicVariant(const std::string &value, const std::string &variantBaseTypeName)
Definition: VariantJsonCompressor.cpp:272
armarx::ProfileDefaultValueEditWidget::getType
QString getType()
Definition: ProfileDefaultValueEditWidget.cpp:128
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:917
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:813
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
Logging.h
armarx::ProfileDefaultValueEditWidget::ProfileDefaultValueEditWidget
ProfileDefaultValueEditWidget(QString typeString, QString jsonValue, Ice::CommunicatorPtr communicator, QWidget *parent=0)
Definition: ProfileDefaultValueEditWidget.cpp:43
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
armarx::JPathNavigator::asValue
JsonValuePtr asValue() const
Definition: JPathNavigator.cpp:212
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:921
Variant.h
armarx::VariantContainerType::FromString
static ContainerTypePtr FromString(const std::string &typeStr)
Definition: VariantContainer.cpp:281
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27