38 #include <boost/assign.hpp> 
   43 #include <QApplication> 
   44 #include <QItemSelection> 
   45 #include <unordered_map> 
   52 static const std::unordered_map<DisabledReason, const char*> LONG_REASONS_TO_STRING =
 
   53     boost::assign::map_list_of  
 
   54     ( 
NEVER, 
"Never in Collision" )
 
   55     ( 
DEFAULT, 
"Collision by Default" )
 
   57     ( 
ALWAYS, 
"Always in Collision" )
 
   58     ( 
USER, 
"User Disabled" )
 
   62 static const std::unordered_map<DisabledReason, QVariant> LONG_REASONS_TO_BRUSH =
 
   63     boost::assign::map_list_of  
 
   64     ( 
NEVER, QBrush(QColor(
"lightgreen")) )
 
   65     ( 
DEFAULT, QBrush(QColor(
"lightpink")) )
 
   66     ( 
ADJACENT, QBrush(QColor(
"powderblue")) )
 
   67     ( 
ALWAYS, QBrush(QColor(
"tomato")) )
 
   68     ( 
USER, QBrush(QColor(
"yellow")) )
 
   72   : QAbstractTableModel(parent), pairs(pairs), std_names(names)
 
   75   for (std::vector<std::string>::const_iterator it = names.begin(), end = names.end(); it != end; ++it, ++idx)
 
   77     visual_to_index << idx;
 
   78     q_names << QString::fromStdString(*it);
 
   83 LinkPairMap::iterator CollisionMatrixModel::item(
const QModelIndex& index)
 
   85   int r = visual_to_index[index.row()], 
c = visual_to_index[index.column()];
 
   90   if (std_names[
r] >= std_names[
c])
 
   93   return pairs.find(std::make_pair(std_names[
r], std_names[
c]));
 
   98   return visual_to_index.size();
 
  103   return visual_to_index.size();
 
  108   if (index.isValid() && index.row() == index.column() && role == Qt::BackgroundRole)
 
  109     return QApplication::palette().window();
 
  111   LinkPairMap::const_iterator item = this->item(index);
 
  112   if (item == pairs.end())
 
  117     case Qt::CheckStateRole:
 
  118       return item->second.disable_check ? Qt::Checked : Qt::Unchecked;
 
  119     case Qt::ToolTipRole:
 
  120       return LONG_REASONS_TO_STRING.at(item->second.reason);
 
  121     case Qt::BackgroundRole:
 
  122       return LONG_REASONS_TO_BRUSH.at(item->second.reason);
 
  129   LinkPairMap::const_iterator item = this->item(index);
 
  130   if (item == pairs.end())
 
  132   return item->second.reason;
 
  137   if (role == Qt::CheckStateRole)
 
  139     LinkPairMap::iterator item = this->item(index);
 
  140     if (item == pairs.end())
 
  143     bool new_value = (value.toInt() == Qt::Checked);
 
  144     if (item->second.disable_check == new_value)
 
  147     item->second.disable_check = new_value;
 
  150     if (item->second.disable_check && item->second.reason == 
NOT_DISABLED)
 
  151       item->second.reason = 
USER;
 
  154     else if (!item->second.disable_check && item->second.reason == 
USER)
 
  157     QModelIndex mirror = this->index(index.column(), index.row());
 
  158     Q_EMIT dataChanged(index, index);
 
  159     Q_EMIT dataChanged(mirror, mirror);
 
  168   QItemSelection changes;
 
  170   for (
const auto& range : selection)
 
  174     const QModelIndex& top_left = range.topLeft();
 
  175     const QModelIndex& bottom_right = range.bottomRight();
 
  176     changes.select(top_left, bottom_right);
 
  177     changes.select(createIndex(top_left.column(), top_left.row()),
 
  178                    createIndex(bottom_right.column(), bottom_right.row()));
 
  183   for (
const auto& range : changes)
 
  184     Q_EMIT dataChanged(range.topLeft(), range.bottomRight());
 
  189   for (
const auto idx : indexes)
 
  190     setData(idx, value ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
 
  196   QRegExp regexp(filter);
 
  197   visual_to_index.clear();
 
  198   for (
int idx = 0, end = q_names.size(); idx != end; ++idx)
 
  200     if (q_names[idx].contains(regexp))
 
  201       visual_to_index << idx;
 
  208   if (role == Qt::DisplayRole)
 
  209     return q_names[visual_to_index[section]];
 
  215   if (!index.isValid())
 
  216     return Qt::NoItemFlags;
 
  218   Qt::ItemFlags 
f = QAbstractTableModel::flags(index);
 
  219   if (index.row() != index.column())
 
  220     f |= Qt::ItemIsUserCheckable;
 
int columnCount(const QModelIndex &parent=QModelIndex()) const override
 
bool setData(const QModelIndex &, const QVariant &value, int role) override
 
CollisionMatrixModel(LinkPairMap &pairs, const std::vector< std::string > &names, QObject *parent=nullptr)
 
void setEnabled(const QItemSelection &selection, bool value)
 
DisabledReason reason(const QModelIndex &index) const
 
int rowCount(const QModelIndex &parent=QModelIndex()) const override
 
Qt::ItemFlags flags(const QModelIndex &index) const override
 
void setFilterRegExp(const QString &filter)
 
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
 
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
 
DisabledReason
Reasons for disabling link pairs. Append "in collision" for understanding. NOT_DISABLED means the lin...
 
std::map< std::pair< std::string, std::string >, LinkPairData > LinkPairMap
LinkPairMap is an adjacency list structure containing links in string-based form. Used for disabled l...