24 #include <ArmarXGui/gui-plugins/StatechartEditorPlugin/view/dialogs/ui_CloneGroupDialog.h>
26 #include <QFileDialog>
34 #include <QPushButton>
42 packageTool(packageTool),
44 groupCloner(groupCloner),
45 validGroupNameRegExp(
"([a-zA-Z][a-zA-Z0-9]*)"),
46 colorGreen(QColor::fromRgb(120, 255, 120)),
47 colorRed(QColor::fromRgb(255, 120, 120)),
48 colorYellow(QColor::fromRgb(255, 200, 0)),
49 alreadyChecking(false)
53 connect(ui->btnSelectPackageFolder, SIGNAL(clicked()),
this, SLOT(
selectPackagePath()));
55 connect(ui->editGroupPrefix, SIGNAL(textChanged(QString)),
this, SLOT(
requestPrefixUpdate(QString)));
56 connect(ui->groupsWidget, SIGNAL(itemChanged(QTableWidgetItem*)),
this, SLOT(
verifyName(QTableWidgetItem*)));
59 ui->editGroupPrefix->setEnabled(
false);
60 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
62 ui->editGroupPrefix->setValidator(
new QRegExpValidator(validGroupNameRegExp,
this));
64 timer =
new QTimer(
this);
66 timer->setSingleShot(
true);
82 return QString::fromUtf8(path.filename().c_str());
87 std::filesystem::path path = ui->editPackagePath->text().toUtf8().data();
88 std::filesystem::path cleanPath = path;
92 cleanPath = std::filesystem::canonical(path);
98 if (*cleanPath.string().rbegin() ==
'/' || *cleanPath.string().rbegin() ==
'\\')
100 cleanPath = cleanPath.remove_filename();
104 return QString::fromUtf8(cleanPath.c_str());
124 QVector<QPair<StatechartGroupPtr, QString>> result;
126 if (ui->groupsWidget->rowCount() == 0 || ui->groupsWidget->columnCount() < 2)
131 for (
const auto& g : groupsToClone)
133 for (
int i = 0; i < ui->groupsWidget->rowCount(); ++i)
135 const auto oldName = ui->groupsWidget->item(i, 0)->data(Qt::UserRole).toString();
137 if (oldName == g->getName())
139 const auto newName = ui->groupsWidget->item(i, 1)->text();
141 result.push_back({g, newName});
158 const int c = item->column();
160 if (
c == 0 || ui->groupsWidget->columnCount() < 2)
172 alreadyChecking =
true;
174 bool hasNameCollisions =
false;
176 for (
int i = 0; i < ui->groupsWidget->rowCount(); ++i)
178 const auto& itemTest = ui->groupsWidget->item(i, 1);
180 if (!itemTest || (!itemTest->flags().testFlag(Qt::ItemIsEditable)))
185 bool collision =
false;
187 for (
int j = 0; j < ui->groupsWidget->rowCount() && !collision; ++j)
189 const auto& itemL = ui->groupsWidget->item(j, 0);
190 const auto& itemR = ui->groupsWidget->item(j, 1);
192 collision |= itemL && itemTest->text() == itemL->text();
193 collision |= itemR && (i != j) && itemTest->text() == itemR->text();
196 itemTest->setBackgroundColor(collision ? colorRed : colorGreen);
197 hasNameCollisions |= collision;
200 bool validName = validGroupNameRegExp.exactMatch(item->text());
201 item->setBackgroundColor(!validName ? colorRed : item->backgroundColor());
203 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(validName && !hasNameCollisions);
204 alreadyChecking =
false;
214 groupPrefix = prefix;
223 void CloneGroupDialog::buildGroupList()
225 if (groupPrefix.size() == 0)
227 ui->groupsWidget->clear();
228 ui->groupsWidget->setColumnCount(0);
229 ui->groupsWidget->setRowCount(0);
232 updateGroupDependencies();
234 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!deps.empty() && !groupsToClone.empty() && groupPrefix.size() != 0);
236 if (deps.empty() || groupPrefix.size() == 0)
241 ui->groupsWidget->clear();
242 ui->groupsWidget->setRowCount(deps.size());
243 ui->groupsWidget->setColumnCount(2);
244 ui->groupsWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
245 ui->groupsWidget->setHorizontalHeaderLabels({
"Original StatechartGroup",
"Cloned StatechartGroup"});
247 for (
int i = 0; i < deps.size(); ++i)
249 const auto& g = deps[i];
251 QTableWidgetItem* item =
new QTableWidgetItem(g->getName() +
" [" + g->getPackageName() +
"]");
252 item->setData(Qt::UserRole, g->getName());
253 item->setFlags(item->flags() ^ Qt::ItemIsEditable);
254 QTableWidgetItem* renamed =
new QTableWidgetItem(groupPrefix + g->getName());
256 bool alreadyCloned = std::find_if(groupsToClone.constBegin(), groupsToClone.constEnd(), [&](
const StatechartGroupPtr & dep)
258 return g->getGroupPath() == dep->getGroupPath();
259 }) == groupsToClone.constEnd();
263 item->setBackgroundColor(colorGreen);
264 renamed->setBackgroundColor(colorGreen);
268 item->setBackgroundColor(colorYellow);
269 renamed->setBackgroundColor(colorYellow);
270 renamed->setFlags(renamed->flags() ^ Qt::ItemIsEditable);
274 renamed->setText(*newGroupName);
278 renamed->setText(
"<Error: Something went terribly wrong>");
279 renamed->setBackgroundColor(colorRed);
283 ui->groupsWidget->setItem(i, 0, item);
284 ui->groupsWidget->setItem(i, 1, renamed);
287 if (groupsToClone.empty())
289 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);
295 QFileDialog selectFolder(
this,
"Select Target Package Root Folder");
297 urls << QUrl::fromLocalFile(QDesktopServices::storageLocation(QDesktopServices::HomeLocation))
298 << QUrl::fromLocalFile(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation));
305 selectFolder.setSidebarUrls(urls);
307 selectFolder.setOption(QFileDialog::ReadOnly,
true);
308 selectFolder.setOption(QFileDialog::HideNameFilterDetails,
false);
309 selectFolder.setFileMode(QFileDialog::Directory);
311 if (selectFolder.exec() == QDialog::Accepted)
313 ui->editPackagePath->setText(*selectFolder.selectedFiles().begin());
317 void CloneGroupDialog::updateGroupDependencies()
319 deps = groupCloner->getGroupDependencies(group,
true);
320 if (!ui->checkBoxCloneRobotSkillTemplates->isChecked())
324 return g->getPackageName() ==
"RobotSkillTemplates";
326 deps.erase(it, deps.end());
329 QVector<StatechartGroupPtr> existingDeps = groupCloner->getMappedGroups(mapping);
331 groupsToClone.clear();
333 for (
const auto& g : deps)
335 bool alreadyCloned = std::find_if(existingDeps.constBegin(), existingDeps.constEnd(), [&](
const StatechartGroupPtr & dep)
337 return g->getGroupPath() == dep->getGroupPath();
338 }) != existingDeps.constEnd();
342 groupsToClone.push_back(g);
349 if (packageTool->checkPackagePath(ui->editPackagePath->text().toStdString()))
351 ui->labelPackageError->setText(
"Package path is valid.");
352 QPalette p(ui->labelPackageError->palette());
353 p.setColor(ui->labelPackageError->backgroundRole(), colorGreen);
355 ui->labelPackageError->setPalette(p);
365 updateGroupDependencies();
367 ui->editGroupPrefix->setEnabled(
true);
369 QString prefixSuggestion;
374 prefixSuggestion = QString(gm.newGroupName).replace(gm.groupName,
"");
377 ui->editGroupPrefix->setText(prefixSuggestion);
381 ui->labelPackageError->setText(
"Package path is not valid!");
382 QPalette p(ui->labelPackageError->palette());
383 p.setColor(ui->labelPackageError->backgroundRole(), colorRed);
384 ui->labelPackageError->setPalette(p);
385 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
false);