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 #include <ArmarXGui/gui-plugins/StatechartEditorPlugin/ui_ProfileDefaultValueEditWidget.h>
26 #include <QFileDialog>
27 
35 
36 #include <QtGui>
37 #include <QTextEdit>
38 #include <QLineEdit>
39 
40 using namespace armarx;
41 
42 
43 
44 ProfileDefaultValueEditWidget::ProfileDefaultValueEditWidget(QString typeString, QString jsonValue, Ice::CommunicatorPtr communicator, QWidget* parent) :
45  QWidget(parent),
47  typeString(typeString),
48  jsonValue(jsonValue),
49  communicator(communicator),
50  editable(true)
51 {
52  ui->setupUi(this);
53 
54  QLineEdit* lineEdit = new QLineEdit;
55  ui->value->insertWidget(eLineEdit, lineEdit);
56 
57  QPushButton* editButton = new QPushButton("Edit");
58  ui->value->insertWidget(eEditButton, editButton);
59  connect(editButton, SIGNAL(clicked()), this, SLOT(editDefaultButtonClicked()));
60 
61  QPushButton* setButton = new QPushButton("Click to set");
62  setButton->setStyleSheet("color: #888;");
63  setButton->setFlat(true);
64  ui->value->insertWidget(eSetButton, setButton);
65  connect(setButton, SIGNAL(clicked()), this, SLOT(setButtonClicked()));
66 
67  int typeId = Variant::hashTypeName(typeString.toStdString());
68 
69  if (typeId == VariantType::String)
70  {
71  lineEdit->setValidator(NULL);
72  }
73  else if (typeId == VariantType::Int || typeId == VariantType::Long)
74  {
75  // do not use QIntValidator, accepts random stuff.
76  QRegExp rx("-?\\d+");
77  QValidator* validator = new QRegExpValidator(rx, this);
78  lineEdit->setValidator(validator);
79  }
80  else if (typeId == VariantType::Bool)
81  {
82  QRegExp rx("(true|false)");
83  QValidator* validator = new QRegExpValidator(rx, this);
84  lineEdit->setValidator(validator);
85  }
86  else if (typeId == VariantType::Float || typeId == VariantType::Double)
87  {
88  // do not use QDoubleValidator. QDoubleValidator is buggy. accepts: 1e16.5
89  // use JSON compliant regex. See class StructuralJsonParser.
90  QRegExp rx("-?\\d+(\\.\\d+)?([eE][+-]?\\d+)?");
91  QValidator* validator = new QRegExpValidator(rx, this);
92  lineEdit->setValidator(validator);
93  }
94 
95  if (jsonValue.isEmpty())
96  {
97  lineEdit->setText("");
98  }
99  else
100  {
101  JPathNavigator nav(VariantJsonCompressor::CompressToJson(jsonValue.toUtf8().data(), typeString.toUtf8().data()));
102  std::string compressedValue = nav.isValue() ? nav.asValue()->rawValue() : nav.getData()->toJsonString(0);
103  lineEdit->setText(QString::fromUtf8(compressedValue.c_str()));
104  }
105 
106 
107 
108  connect(ui->pushButtonDelete, SIGNAL(clicked()), this, SLOT(resetValue()));
109 
110  if (jsonValue.size() == 0)
111  {
112  resetValue();
113  }
114  else
115  {
116  setButtonClicked();
117  }
118 }
119 
121 {
122 
123 }
124 
126 {
127  return typeString;
128 }
129 
131 {
132  this->editable = editable;
133  ui->value->widget(eLineEdit)->setEnabled(editable);
134 }
135 
137 {
138  if (ui->value->currentIndex() == Widget::eLineEdit)
139  {
140  return qobject_cast<QLineEdit*>(ui->value->currentWidget())->text();
141  }
142  else if (ui->value->currentIndex() == Widget::eEditButton)
143  {
144  return jsonValue;
145  }
146 
147  return std::nullopt;
148 }
149 
151 {
152  //JSONObjectPtr jsonObject = new JSONObject(communicator);
153  int index = ui->value->currentIndex();
154 
155  if (index == Widget::eEditButton)
156  {
157  return jsonValue;
158  }
159  else if (index == Widget::eLineEdit)
160  {
161  QLineEdit* valueEdit = qobject_cast<QLineEdit*>(ui->value->currentWidget());
162  std::string verboseJson = VariantJsonCompressor::DecompressBasicVariant(valueEdit->text().toUtf8().data(), typeString.toStdString());
163  return QString::fromUtf8(verboseJson.c_str());
164  }
165 
166  return std::nullopt;
167 }
168 
170 {
171  VariantContainerBasePtr result;
172 
173  if (ui->value->currentIndex() == eLineEdit)
174  {
175  QLineEdit* valueEdit = qobject_cast<QLineEdit*>(ui->value->currentWidget());
176  int typeId = Variant::hashTypeName(typeString.toStdString());
177  Variant variant;
178 
179  if (typeId == VariantType::Int)
180  {
181  variant.setInt(valueEdit->text().toInt());
182  }
183  else if (typeId == VariantType::Long)
184  {
185  variant.setLong(valueEdit->text().toLong());
186  }
187  else if (typeId == VariantType::Bool)
188  {
189  variant.setBool(valueEdit->text().compare("true", Qt::CaseInsensitive) == 0 || valueEdit->text() == "1");
190  }
191  else if (typeId == VariantType::Float)
192  {
193  variant.setFloat(valueEdit->text().toFloat());
194  }
195  else if (typeId == VariantType::Double)
196  {
197  variant.setDouble(valueEdit->text().toDouble());
198  }
199  else if (typeId == VariantType::String)
200  {
201  variant.setString(valueEdit->text().trimmed().toStdString());
202  }
203 
204  result = new SingleVariant(variant);
205  }
206  else if (ui->value->currentIndex() == eEditButton)
207  {
208  if (jsonValue.isEmpty())
209  {
210  return result;
211  }
212 
213  JSONObjectPtr jsonObject = new JSONObject(communicator);
214  // ARMARX_INFO_S << VAROUT(jsonValue.toUtf8().data());
215  jsonObject->fromString(jsonValue.toUtf8().data());
216 
217  try
218  {
219  SerializablePtr obj = jsonObject->deserializeIceObject();
220  result = VariantContainerBasePtr::dynamicCast(obj);
221 
222  if (!result)
223  {
224  // must be simple variant
225  result = new SingleVariant(Variant(VariantDataPtr::dynamicCast(obj)));
226  }
227  }
228  catch (std::exception& e)
229  {
230  ARMARX_WARNING_S << "JSON string for type " << typeString.toStdString() << " could not be deserialized: " << e.what();
231  return result;
232  }
233  }
234 
235  return result;
236 }
237 
238 void ProfileDefaultValueEditWidget::resetValue()
239 {
240  this->setFocus();
241  // ui->value->widget(eSetButton)->setFocus();
242  ui->value->setCurrentIndex(eSetButton);
243  ui->pushButtonDelete->setEnabled(false);
244  ui->pushButtonDelete->hide();
245  // ui->value->widget(eSetButton)->setFocus();
246  jsonValue.clear();
247  auto lineEdit = qobject_cast<QLineEdit*>(ui->value->widget(eLineEdit));
248  lineEdit->setText("");
249 }
250 
251 void ProfileDefaultValueEditWidget::setButtonClicked()
252 {
253  ui->pushButtonDelete->setEnabled(true);
254  ui->pushButtonDelete->show();
255  int variantId = Variant::hashTypeName(typeString.toStdString());
256 
257  if (variantId == VariantType::String || variantId == VariantType::Int || variantId == VariantType::Long || variantId == VariantType::Bool || variantId == VariantType::Float || variantId == VariantType::Double)
258  {
259  ui->value->setCurrentIndex(eLineEdit);
260  }
261  else
262  {
263  initEditButton();
264  ui->value->setCurrentIndex(eEditButton);
265  }
266 }
267 
268 void ProfileDefaultValueEditWidget::initEditButton()
269 {
270  try
271  {
272  if (jsonValue.isEmpty())
273  {
274 
275  auto variantContainerType = VariantContainerType::FromString(typeString.toStdString());
276  JSONObjectPtr jsonObject = new JSONObject(communicator);
277 
278  // ARMARX_INFO_S << VAROUT(variantContainerType->typeId);
279 
280  Ice::ValueFactoryPtr factory = communicator->getValueFactoryManager()->find(variantContainerType->typeId);
281 
282  if (!factory)
283  {
284  ARMARX_WARNING << "Could not get ObjectFactory for Variant " << variantContainerType->typeId;
285  }
286  else
287  {
288  ARMARX_INFO_S << variantContainerType->typeId;
289  Ice::ValuePtr valPtr = factory->create(variantContainerType->typeId);
290  ARMARX_INFO_S << valPtr.get() << " " << SerializablePtr::dynamicCast(valPtr).get();
291 
292  VariantContainerBasePtr container = VariantContainerBasePtr::dynamicCast(valPtr);
293 
294  if (container)
295  {
296  // TODO: make better with dummy element function for all containers/variants?!
297  // ARMARX_INFO_S << VAROUT(variantContainerType->subType->typeId);
298  Ice::ValueFactoryPtr subfactory = communicator->getValueFactoryManager()->find(variantContainerType->subType->typeId);
299 
300  if (!subfactory)
301  {
302  // ARMARX_INFO_S << " no factory";
303  subfactory = IceInternal::factoryTable->getValueFactory(variantContainerType->subType->typeId);
304  }
305 
306  if (subfactory)
307  {
308  Ice::ValuePtr subObj = subfactory->create(variantContainerType->subType->typeId);
309  VariantDataPtr var = VariantDataPtr::dynamicCast(subObj);
310 
311  SingleTypeVariantListPtr list = SingleTypeVariantListPtr::dynamicCast(valPtr);
312 
313  if (var && list)
314  {
315  list->addVariant(Variant(var));
316  }
317 
318  StringValueMapPtr map = StringValueMapPtr::dynamicCast(valPtr);
319 
320  if (var && map)
321  {
322  map->addVariant("mykey", Variant(var));
323  }
324  }
325  else
326  {
327  ARMARX_INFO_S << " no base factory";
328  }
329  }
330  else
331  {
332  container = new SingleVariant(Variant(VariantDataPtr::dynamicCast(valPtr)));
333  }
334 
335  jsonObject->serializeIceObject(container);
336  }
337 
338  jsonValue = QString::fromStdString(jsonObject->asString(true));
339  }
340  }
341  catch (...)
342  {
344  ui->value->widget(eEditButton)->setEnabled(false);
345  }
346 }
347 
348 void ProfileDefaultValueEditWidget::editDefaultButtonClicked()
349 {
350  EditDefaultValueDialog d(jsonValue, typeString, communicator);
351  if (d.exec() == QDialog::Accepted)
352  {
353  jsonValue = d.getJson();
354  }
355 }
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::ProfileDefaultValueEditWidget::getVariantContainer
VariantContainerBasePtr getVariantContainer()
Definition: ProfileDefaultValueEditWidget.cpp:169
armarx::ProfileDefaultValueEditWidget
Definition: ProfileDefaultValueEditWidget.h:42
SingleTypeVariantList.h
EditDefaultValueDialog.h
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::Variant::setLong
void setLong(long n, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to n.
Definition: Variant.cpp:290
armarx::ProfileDefaultValueEditWidget::getValueAsString
std::optional< QString > getValueAsString()
Definition: ProfileDefaultValueEditWidget.cpp:136
armarx::JPathNavigator::isValue
bool isValue() const
Definition: JPathNavigator.cpp:53
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:340
armarx::ProfileDefaultValueEditWidget::~ProfileDefaultValueEditWidget
~ProfileDefaultValueEditWidget() override
Definition: ProfileDefaultValueEditWidget.cpp:120
armarx::ProfileDefaultValueEditWidget::setEditable
void setEditable(bool editable)
Definition: ProfileDefaultValueEditWidget.cpp:130
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
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:274
IceInternal::Handle< ::Ice::Communicator >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
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:323
armarx::EditDefaultValueDialog
Definition: EditDefaultValueDialog.h:41
armarx::Variant::setBool
void setBool(bool b, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to b.
Definition: Variant.cpp:357
Ui
ArmarX Headers.
Definition: ArmarXMainWindow.h:58
armarx::SingleVariant
The SingleVariant class is required to store single Variant instances in VariantContainer subclasses.
Definition: VariantContainer.h:109
armarx::Variant::setFloat
void setFloat(float f, const Ice::Current &c=Ice::emptyCurrent) override
Sets the Variant's value to f.
Definition: Variant.cpp:306
armarx::ProfileDefaultValueEditWidget::getValueAsJson
std::optional< QString > getValueAsJson()
Definition: ProfileDefaultValueEditWidget.cpp:150
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
ProfileDefaultValueEditWidget.h
armarx::VariantJsonCompressor::CompressToJson
static JsonDataPtr CompressToJson(const std::string &json, const std::string &variantBaseTypeName)
Definition: VariantJsonCompressor.cpp:187
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::JPathNavigator::getData
JsonDataPtr getData() const
Definition: JPathNavigator.cpp:224
VariantJsonCompressor.h
armarx::VariantJsonCompressor::DecompressBasicVariant
static std::string DecompressBasicVariant(const std::string &value, const std::string &variantBaseTypeName)
Definition: VariantJsonCompressor.cpp:214
armarx::ProfileDefaultValueEditWidget::getType
QString getType()
Definition: ProfileDefaultValueEditWidget.cpp:125
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:699
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
Logging.h
armarx::ProfileDefaultValueEditWidget::ProfileDefaultValueEditWidget
ProfileDefaultValueEditWidget(QString typeString, QString jsonValue, Ice::CommunicatorPtr communicator, QWidget *parent=0)
Definition: ProfileDefaultValueEditWidget.cpp:44
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
armarx::JPathNavigator::asValue
JsonValuePtr asValue() const
Definition: JPathNavigator.cpp:192
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:920
Variant.h
armarx::VariantContainerType::FromString
static ContainerTypePtr FromString(const std::string &typeStr)
Definition: VariantContainer.cpp:262
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28