one_of_param_widget.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Christoph Rösmann
23  *********************************************************************/
24 
28 
29 #include <corbo-core/console.h>
30 #include <QVBoxLayout>
31 
32 #include <memory>
33 #include <string>
34 
35 namespace corbo {
36 namespace gui {
37 
38 OneOfParamWidget::OneOfParamWidget(const QString& label, ParameterCache* cache, QWidget* parent) : QWidget(parent), _param_cache(cache)
39 {
40  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
41 
42  _layout = new QVBoxLayout(this);
43  _layout->setContentsMargins(5, 5, 0, 0);
44  _layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
45 
46  _combobox = new LabelComboBoxWidget(label);
47 
48  _layout->addWidget(_combobox);
49 
50  connect(_combobox->widgetComboBox(), SIGNAL(currentTextChanged(const QString&)), this, SLOT(selectParameter(const QString&)));
51 }
52 
53 OneOfParamWidget::~OneOfParamWidget() {}
54 
55 QSize OneOfParamWidget::sizeHint() const { return QSize(200, 50); }
56 
57 void OneOfParamWidget::registerParameter(const QString& label, const MessageParser::FieldInformation& info)
58 {
59  _message = info.message_raw;
60  _fields.insert(label, info.field_raw);
61 
62  // check if the current parameter is active
63  // we also check if no one-of field is selected, then this field becomes active
64  bool selected_field = (info.field_raw == info.oneof_selected_field) || !info.oneof_selected_field;
65 
66  if (selected_field) _selected_item_parsed = true;
67 
68  _combobox->widgetComboBox()->addItem(label);
69  // this triggers selectParameter() if it is the first Item
70  // (-> we might expand and allocate a wrong protobuf message, hence we
71  // are keeping track of the selected value with member _selected_item_parsed.
72 
73  // if this parameter is active switch combobox item
74  if (selected_field)
75  {
76  _combobox->widgetComboBox()->setCurrentText(label); // should trigger selectParameter() callback
77  }
78 }
79 
80 void OneOfParamWidget::selectParameter(const QString& label)
81 {
82  // see descirption in registerParameter()
83  if (!_selected_item_parsed) return;
84 
85  // store old paramters (_selected_item)
86  addParametersToCache();
87  _selected_item = label;
88 
89  if (_param_widget)
90  {
91  _layout->removeWidget(_param_widget);
92  delete _param_widget;
93  _param_widget = nullptr;
94  }
95 
96  restoreParametersFromCache();
97 
98  auto field = _fields.find(label);
99  if (field != _fields.end())
100  {
101  ParameterWidget* params = new ParameterWidget(_param_cache);
102  // forward nested names in case they are required for reconstructing the full parameter path/name
103  params->nestedParentFieldNames() = _nested_field_name;
104  params->generateFromAllocatedField(_message, field.value());
105  if (params->hasParameters())
106  {
107  _layout->addWidget(params);
108  _param_widget = params;
109  params->connect(params, &ParameterWidget::signalUpdateRequested, [this]() { emit signalUpdateRequested(); });
110  params->connect(params, &ParameterWidget::updatedOneOfField, [this](const QString& name) { emit currentParameterChanged(name); });
111  }
112  else
113  {
114  delete params;
115  _param_widget = nullptr;
116  }
117 
118  emit currentParameterChanged(label);
119  }
120 }
121 
122 void OneOfParamWidget::addParametersToCache()
123 {
124  if (!_param_cache || _selected_item.isEmpty()) return;
125 
126  // store child oneof-fields as well
127  QList<OneOfParamWidget*> widgets = _param_widget->findChildren<OneOfParamWidget*>("", Qt::FindDirectChildrenOnly);
128  for (auto widget : widgets) widget->addParametersToCache();
129 
130  // store parameter of this one-if
131  std::string param_path = ParameterCache::nestedNameListToKey(_nested_field_name);
132  // add selected parameter
133  param_path += "/" + _selected_item.toStdString();
134  // store complete message, but we later only use the corresonding one-of-field
135  // TODO(roesmann) here is place for improving efficency and required memory size
136  _param_cache->toCache(param_path, *_message);
137 }
138 
139 bool OneOfParamWidget::restoreParametersFromCache()
140 {
141  std::string param_path = ParameterCache::nestedNameListToKey(_nested_field_name);
142  // add selected parameter
143  param_path += "/" + _selected_item.toStdString();
144 
145  std::unique_ptr<google::protobuf::Message> cache = _param_cache->fromCache(param_path);
146  if (!cache) return false;
147 
148  const google::protobuf::FieldDescriptor* current_field = _fields[_selected_item];
149 
150  // only copy the required one-of-field
151  _message->GetReflection()->SwapFields(_message, cache.get(), {current_field});
152  // _message->CopyFrom(*cache);
153  return true;
154 }
155 
156 std::string OneOfParamWidget::nestedFieldNameUnrolled(const std::string& delimiter)
157 {
158  auto it = _nested_field_name.begin();
159  std::string nnames = *it;
160  for (std::advance(it, 1); it != _nested_field_name.end(); ++it) nnames += delimiter + *it;
161  return nnames;
162 }
163 
164 void OneOfParamWidget::addDescription(const QString& description)
165 {
166  _layout->addWidget(new QLabel(description));
167 }
168 
169 } // namespace gui
170 } // namespace corbo
corbo::gui::ParameterWidget::nestedParentFieldNames
const std::list< std::string > & nestedParentFieldNames() const
Definition: parameter_widget.h:150
corbo
Definition: communication/include/corbo-communication/utilities.h:37
corbo::gui::ParameterWidget
Definition: parameter_widget.h:92
console.h
corbo::gui::ParameterWidget::hasParameters
bool hasParameters() const
Definition: parameter_widget.cpp:986
corbo::gui::ParameterWidget::generateFromAllocatedField
void generateFromAllocatedField(google::protobuf::Message *message, const google::protobuf::FieldDescriptor *field)
Definition: parameter_widget.cpp:931
info
else if n * info
Definition: cholesky.cpp:18
one_of_param_widget.h
parameter_widget.h
corbo::gui::OneOfParamWidget::OneOfParamWidget
OneOfParamWidget(ParameterCache *cache=nullptr, QWidget *parent=nullptr)
Definition: one_of_param_widget.h:116
if
if(UPLO(*uplo)==INVALID) *info
Definition: cholesky.cpp:60
corbo::gui::OneOfParamWidget
Definition: one_of_param_widget.h:89
corbo::gui::OneOfParamWidget::addParametersToCache
void addParametersToCache()
Definition: one_of_param_widget.cpp:166
message_parser.h


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Wed Mar 2 2022 00:05:58