28 #include <QHeaderView>
30 #include <qabstractitemview.h>
35 #include <qhashfunctions.h>
36 #include <qheaderview.h>
39 #include <qnamespace.h>
40 #include <qobjectdefs.h>
56 QStringList columns{
"Name",
"X [mm]",
"Y [mm]",
"Yaw [\u00b0]"};
57 setColumnCount(columns.size());
58 setHorizontalHeaderLabels(columns);
59 horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
60 horizontalHeader()->setVisible(
true);
62 setEditTriggers(QAbstractItemView::NoEditTriggers);
63 setSortingEnabled(
true);
65 setAlternatingRowColors(
true);
71 setContextMenuPolicy(Qt::CustomContextMenu);
79 setSortingEnabled(
false);
81 QTableWidgetItem* result =
nullptr;
86 for (
int col = 0; col < 4; ++col)
89 QTableWidgetItem* item =
new QTableWidgetItem{};
90 setItem(row, col, item);
94 item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
104 setSortingEnabled(
true);
115 const int precision = 2;
118 setSortingEnabled(
false);
121 int row = this->row(vertex.attrib().tableWidgetItem);
123 QString displayName = QString::fromStdString(vertex.attrib().getName());
124 if (vertex.attrib().changed)
128 item(row, 0)->setText(displayName);
129 item(row, 0)->setData(Qt::UserRole, QString::fromStdString(vertex.attrib().getName()));
130 item(row, 1)->setText(QString::number(pose(0, 3), format, precision));
131 item(row, 2)->setText(QString::number(pose(1, 3), format, precision));
132 item(row, 3)->setText(QString::number(
getYawAngleDegree(pose), format, precision));
134 setSortingEnabled(
true);
138 font.setBold(vertex.attrib().highlighted);
139 for (
int col = 0; col < 4; ++col)
141 auto* item = this->item(row, col);
144 item->setData(Qt::BackgroundRole, bgColor);
152 if (currentItem() == vertex.attrib().tableWidgetItem)
154 setCurrentItem(
nullptr);
157 removeRow(row(vertex.attrib().tableWidgetItem));
158 vertex.attrib().tableWidgetItem =
nullptr;
161 QList<QTableWidgetItem*>
168 VertexTableWidget::_nameOf(QTableWidgetItem* item)
170 return item->data(Qt::UserRole).toString();
179 if (items.size() == 0)
181 QAction* action = menu.addSection(
"No locations selected");
182 action->setEnabled(
false);
186 if (items.size() == 2)
188 menu.addSection(
"Selected pair of locations");
191 std::sort(items.begin(),
193 [](QTableWidgetItem* first, QTableWidgetItem* second)
194 { return _nameOf(first) < _nameOf(second); });
195 QTableWidgetItem* first = items[0];
196 QTableWidgetItem* second = items[1];
198 connect(menu.addAction(
"Add edge '" + _nameOf(first) +
"' " +
utils::arrowRight +
" '" +
199 _nameOf(second) +
"'"),
202 connect(menu.addAction(
"Add edge '" + _nameOf(first) +
"' " +
utils::arrowLeft +
" '" +
203 _nameOf(second) +
"'"),
206 connect(menu.addAction(
"Add edges '" + _nameOf(first) +
"' " +
utils::arrowBoth +
" '" +
207 _nameOf(second) +
"'"),
209 [
this, first, second]()
214 if (items.size() > 0)
216 QString edges = items.size() == 1 ?
"edge" :
"edges";
217 QString desc = items.size() == 1 ?
"'" + _nameOf(items[0]) +
"'"
218 : QString::number(items.size()) +
" locations";
220 if (items.size() == 1)
223 menu.addSection(
"Selected single location " + desc);
227 menu.addSection(
"Selected bulk of " + desc);
230 using Item = QTableWidgetItem;
231 using ListOfEdges = QList<QPair<Item*, Item*>>;
233 std::function<void(ListOfEdges & edges, Item * selected, Item * action)>;
235 auto addBulkAddEdgeActions = [
this, &items](QMenu* submenu, AppendFunc appendFunc)
237 if (items.size() == rowCount())
239 QAction*
a = submenu->addAction(
"No other locations");
240 a->setDisabled(
true);
242 for (
int row = 0; row < rowCount(); ++row)
244 QTableWidgetItem* action = this->item(row, 0);
245 if (items.count(action) == 0)
247 QAction*
a = submenu->addAction(_nameOf(action));
251 [
this, items, action, appendFunc]()
253 QList<QPair<QTableWidgetItem*, QTableWidgetItem*>> edges;
254 for (
auto* selected : items)
256 appendFunc(edges, selected, action);
264 addBulkAddEdgeActions(
266 [](ListOfEdges& edges, Item* selected, Item* action)
267 { edges.append(QPair{selected, action}); });
268 addBulkAddEdgeActions(
269 menu.addMenu(
"Add " + edges +
" " + desc +
" " +
utils::arrowLeft +
" ..."),
270 [](ListOfEdges& edges, Item* selected, Item* action)
271 { edges.append(QPair{action, selected}); });
272 addBulkAddEdgeActions(
273 menu.addMenu(
"Add " + edges +
" " + desc +
" " +
utils::arrowBoth +
" ..."),
274 [](ListOfEdges& edges, Item* selected, Item* action)
276 edges.append(QPair{selected, action});
277 edges.append(QPair{action, selected});
281 auto connectBulkRemoveEdgeAction =
287 [
this, items, edgeDirection]()
288 { emit edgeRemovalRequested(items, edgeDirection); });
291 connectBulkRemoveEdgeAction(
293 utils::EdgeDirection::To);
294 connectBulkRemoveEdgeAction(
296 utils::EdgeDirection::From);
297 connectBulkRemoveEdgeAction(
299 utils::EdgeDirection::Bidirectional);
303 menu.addSection(
"Manage Locations");
304 connect(menu.addAction(
"Create new location ..."),
307 [
this]() { emit newVertexRequested(); });
309 menu.exec(mapToGlobal(pos));