38 #include <boost/unordered_map.hpp>
39 #include <boost/assign.hpp>
44 #include <QApplication>
45 #include <QItemSelection>
46 #include <QtCore/QRegularExpression>
50 boost::assign::map_list_of
60 : QAbstractTableModel(parent),
srdf(
srdf), std_names(names)
63 for (std::vector<std::string>::const_iterator it = names.begin(), end = names.end(); it != end; ++it, ++idx)
66 q_names << QString::fromStdString(*it);
82 PairMatcher(
const std::string& link1,
const std::string& link2)
83 :
search(link1 < link2 ?
std::make_pair(
std::cref(link1),
std::cref(link2)) :
84 std::make_pair(
std::cref(link2),
std::cref(link1)))
94 std::pair<const std::string&, const std::string&>
search;
97 template <
typename Container>
98 auto find(Container& pairs,
const std::string& link1,
const std::string& link2)
100 return std::find_if(pairs.begin(), pairs.end(),
PairMatcher(link1, link2));
105 for (
const auto&
name :
srdf->no_default_collision_links_)
113 static std::string enabled =
"Explicitly enabled";
114 static std::string disabled =
"Disabled by default";
115 static QBrush default_collision_brush(QColor(
"lightpink").darker(110));
121 case Qt::BackgroundRole:
122 return QApplication::palette().window();
128 const std::string* reason =
nullptr;
131 if (it !=
srdf->disabled_collision_pairs_.end())
132 reason = &it->reason_;
140 case Qt::CheckStateRole:
141 return (!reason || reason == &enabled) ? Qt::Unchecked : Qt::Checked;
142 case Qt::ToolTipRole:
143 return reason ? QString::fromStdString(*reason) : QString();
144 case Qt::BackgroundRole:
145 if (!reason || reason == &enabled)
147 else if (reason == &disabled)
148 return default_collision_brush;
157 if (role != Qt::CheckStateRole)
160 bool new_value = (
value.toInt() == Qt::Checked);
163 if (p.link1_ > p.link2_)
164 std::swap(p.link1_, p.link2_);
166 auto enabled =
find(
srdf->enabled_collision_pairs_, p.link1_, p.link2_);
167 auto disabled =
find(
srdf->disabled_collision_pairs_, p.link1_, p.link2_);
171 assert(disabled ==
srdf->disabled_collision_pairs_.end());
172 auto& pairs =
srdf->enabled_collision_pairs_;
175 if (enabled != pairs.end())
176 pairs.erase(std::remove_if(enabled, pairs.end(),
PairMatcher(p.link1_, p.link2_)), pairs.end());
183 if (enabled == pairs.end())
184 srdf->enabled_collision_pairs_.push_back(p);
191 assert(enabled ==
srdf->enabled_collision_pairs_.end());
192 auto& pairs =
srdf->disabled_collision_pairs_;
196 if (disabled == pairs.end())
203 if (disabled != pairs.end())
204 pairs.erase(std::remove_if(disabled, pairs.end(),
PairMatcher(p.link1_, p.link2_)), pairs.end());
212 QModelIndex mirror = this->index(
index.column(),
index.row());
214 Q_EMIT dataChanged(mirror, mirror);
222 QItemSelection changes;
224 for (
const auto& range : selection)
228 const QModelIndex& top_left = range.topLeft();
229 const QModelIndex& bottom_right = range.bottomRight();
230 changes.select(top_left, bottom_right);
231 changes.select(createIndex(top_left.column(), top_left.row()),
232 createIndex(bottom_right.column(), bottom_right.row()));
237 for (
const auto& range : changes)
238 Q_EMIT dataChanged(range.topLeft(), range.bottomRight());
243 for (
const auto idx : indexes)
244 setData(idx,
value ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
250 QRegularExpression regexp(filter);
252 for (
int idx = 0, end =
q_names.size(); idx != end; ++idx)
254 if (
q_names[idx].contains(regexp))
262 if (role == Qt::DisplayRole)
269 if (!
index.isValid())
270 return Qt::NoItemFlags;
272 Qt::ItemFlags
f = QAbstractTableModel::flags(
index);
274 f |= Qt::ItemIsUserCheckable;