TransitionDialog.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package
19 * @author
20 * @date
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "TransitionDialog.h"
25
26#include <QComboBox>
27#include <QFileDialog>
28#include <QLineEdit>
29#include <QMessageBox>
30
31#include <ArmarXGui/gui-plugins/StatechartEditorPlugin/view/dialogs/ui_TransitionDialog.h>
32
34
35namespace armarx
36{
37
40 QStringList profileNames,
42 VariantInfoPtr variantInfo,
43 QWidget* parent) :
44 QDialog(parent),
45 ui(new Ui::TransitionDialog),
46 transition(transition),
47 parentState(state),
48 ic(ic),
49 variantInfo(variantInfo),
50 profileNames(profileNames)
51 {
52 ui->setupUi(this);
53 setup();
54 }
55
57 {
58 delete ui;
59 }
60
63 {
64 return ui->inputTableMapping->getMapping();
65 }
66
69 {
70 return ui->parentLocalMapping->getMapping();
71 }
72
75 {
76 return ui->parentOutputMapping->getMapping();
77 }
78
79 size_t
80 TransitionDialog::LevenshteinEditDistance(const std::string& s1, const std::string& s2)
81 {
82 // from https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#C++
83 const std::size_t len1 = s1.size(), len2 = s2.size();
84 std::vector<std::vector<unsigned int>> d(len1 + 1, std::vector<unsigned int>(len2 + 1));
85
86 d[0][0] = 0;
87 for (unsigned int i = 1; i <= len1; ++i)
88 {
89 d[i][0] = i;
90 }
91 for (unsigned int i = 1; i <= len2; ++i)
92 {
93 d[0][i] = i;
94 }
95
96 for (unsigned int i = 1; i <= len1; ++i)
97 for (unsigned int j = 1; j <= len2; ++j)
98 // note that std::min({arg1, arg2, arg3}) works only in C++11,
99 // for C++98 use std::min(std::min(arg1, arg2), arg3)
100 d[i][j] = std::min({d[i - 1][j] + 1,
101 d[i][j - 1] + 1,
102 d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1)});
103 return d[len1][len2];
104 }
105
106 void
107 TransitionDialog::setup()
108 {
109 // ui->editEventName->setText(transition->eventName);
110 // ui->editEventName->setFocus();
111 ui->labelEventName->setText(transition->eventName);
112
113 if (!transition->destinationState)
114 {
115 ui->labelDestinationState->setText("Transition is detached");
116 return;
117 }
118
119
120 if (transition->sourceState)
121 {
122 ui->labelSourceState->setText(transition->sourceState->getInstanceName());
123 setWindowTitle("Edit Transition " + transition->eventName + " [" +
124 transition->sourceState->getInstanceName() + " -> " +
125 transition->destinationState->getInstanceName() + "]");
126 }
127 else
128 {
129 ui->labelSourceState->setText("This is the initial transition to the start state");
130 setWindowTitle("Edit Initial Transition -> " +
131 transition->destinationState->getInstanceName());
132 }
133
134 ui->labelDestinationState->setText(transition->destinationState->getInstanceName());
135
136
138
139 if (transition->destinationState->getType() != eFinalState)
140 {
141 if (transition->destinationState->getStateClass())
142 {
143 destDict = transition->destinationState->getStateClass()->getInputParameters();
144 }
145 else
146 {
147 QMessageBox::warning(this,
148 "Transition Editing Error",
149 "Transition editing not possible because destination state is "
150 "not loaded - load statechart group of destination state.");
151 return;
152 }
153 }
154 else
155 {
156 destDict = transition->destinationState->getParent()->getOutputParameters();
157 }
158
159 ui->inputTableMapping->setup(destDict,
160 transition->mappingToNextStatesInput,
161 transition,
162 parentState,
163 profileNames,
164 ic,
165 variantInfo);
166
167 if (transition->sourceState)
168 {
169 ui->tabWidget->setTabEnabled(1, true);
170 ui->tabWidget->setTabEnabled(2, true);
171 ui->parentLocalMapping->hideColumn(TransitionMappingTable::eMappingRequired);
172 ui->parentOutputMapping->hideColumn(TransitionMappingTable::eMappingRequired);
173 ui->parentLocalMapping->setup(parentState->getLocalParameters(),
174 transition->mappingToParentStatesLocal,
175 transition,
176 parentState,
177 profileNames,
178 ic,
179 variantInfo);
180 ui->parentOutputMapping->setup(parentState->getOutputParameters(),
181 transition->mappingToParentStatesOutput,
182 transition,
183 parentState,
184 profileNames,
185 ic,
186 variantInfo);
187 }
188 else
189 {
190 ui->tabWidget->setTabEnabled(1, false);
191 ui->tabWidget->setTabEnabled(2, false);
192 }
193 }
194
195
196} // namespace armarx
197
198void
199armarx::TransitionDialog::on_btnAutoMap_clicked()
200{
201 TransitionMappingTable* mapping;
202 if (ui->tabWidget->currentIndex() == 0)
203 {
204 mapping = ui->inputTableMapping;
205 }
206 else if (ui->tabWidget->currentIndex() == 1)
207 {
208 mapping = ui->parentLocalMapping;
209 }
210 else
211 {
212 mapping = ui->parentOutputMapping;
213 }
214
215
216 auto caseSensitive = [](QString s1, QString s2) { return std::make_pair(s1 == s2, 0.0f); };
217 auto caseInsensitive = [](QString s1, QString s2)
218 { return std::make_pair(s1.compare(s1, s2, Qt::CaseInsensitive) == 0, 0.0f); };
219 auto editDistance = [](QString s1, QString s2)
220 {
221 auto distance =
222 LevenshteinEditDistance(s1.toLower().toStdString(), s2.toLower().toStdString());
223 return std::make_pair(distance <= 3, (float)distance);
224 };
225
226 ARMARX_INFO << "Casesensitive";
227 auto mappedRows = mapping->mapByCriteria(caseSensitive);
228 // ARMARX_INFO << mappedRows.size() << " Caseinsensitive";
229 mappedRows.append(mapping->mapByCriteria(caseInsensitive));
230 // ARMARX_INFO << mappedRows.size() << " editdistance";
231 mappedRows.append(mapping->mapByCriteria(editDistance));
232 // ARMARX_INFO << mappedRows.size() << " after editdistance";
233 QString foundMappingsString;
234 for (auto& elem : mappedRows)
235 {
236 foundMappingsString += elem.first + " from " + elem.second + "\n";
237 }
238 if (!foundMappingsString.isEmpty())
239 {
240 foundMappingsString = ":\n" + foundMappingsString;
241 }
242 QMessageBox::information(this,
243 "Auto Mapping Results",
244 "Mapped " + QString::number(mappedRows.size()) +
245 (mappedRows.size() == 1 ? " entry" : " entries") +
246 foundMappingsString);
247}
TransitionDialog(statechartmodel::TransitionCPtr transition, statechartmodel::StatePtr parentState, QStringList profileNames, Ice::CommunicatorPtr ic=NULL, VariantInfoPtr variantInfo=VariantInfoPtr(), QWidget *parent=0)
statechartmodel::ParameterMappingList getMappingToParentStateLocal() const
statechartmodel::ParameterMappingList getMappingToNextStateInput() const
statechartmodel::ParameterMappingList getMappingToParentStateOutput() const
static size_t LevenshteinEditDistance(const std::string &s1, const std::string &s2)
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
ArmarX Headers.
std::shared_ptr< State > StatePtr
Definition State.h:48
QMap< QString, StateParameterPtr > StateParameterMap
QList< ParameterMappingPtr > ParameterMappingList
Definition XmlWriter.h:49
std::shared_ptr< const Transition > TransitionCPtr
Definition Transition.h:91
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< VariantInfo > VariantInfoPtr
Definition VariantInfo.h:39
double distance(const Point &a, const Point &b)
Definition point.hpp:95