32 #include <boost/filesystem.hpp> 40 #include <QTextBrowser> 41 #include <QVBoxLayout> 42 #include <QDialogButtonBox> 43 #include <QPushButton> 47 #include <QHeaderView> 79 bool isSubtopic(
const std::string &base,
const std::string &topic )
93 std::string query = topic;
94 while ( query !=
"/" )
117 QList<PluginGroup> *groups,
118 QList<ros::master::TopicInfo> *unvisualizable )
123 ros::master::V_TopicInfo::iterator topic_it;
125 for ( topic_it = all_topics.begin(); topic_it != all_topics.end(); ++topic_it )
127 QString topic = QString::fromStdString( topic_it->name );
128 QString datatype = QString::fromStdString( topic_it->datatype );
130 if ( datatype_plugins.contains( datatype ) )
132 if ( groups->size() == 0 ||
133 !
isSubtopic(groups->back().base_topic.toStdString(),
134 topic.toStdString()) )
138 groups->append( pi );
142 QString topic_suffix(
"raw" );
146 topic_suffix = topic.right( topic.size() - group.
base_topic.size() - 1 );
149 const QList<QString> &plugin_names =
150 datatype_plugins.values( datatype );
151 for (
int i = 0; i < plugin_names.size(); ++i )
153 const QString &name = plugin_names[i];
161 unvisualizable->append( *topic_it );
168 const QString& object_type,
169 const QStringList& disallowed_display_names,
170 const QStringList& disallowed_class_lookup_names,
171 QString* lookup_name_output,
172 QString* display_name_output,
173 QString* topic_output,
174 QString* datatype_output,
177 , factory_( factory )
178 , disallowed_display_names_( disallowed_display_names )
179 , disallowed_class_lookup_names_( disallowed_class_lookup_names )
180 , lookup_name_output_( lookup_name_output )
181 , display_name_output_( display_name_output )
182 , topic_output_( topic_output )
183 , datatype_output_( datatype_output )
188 QGroupBox* type_box =
new QGroupBox(
"Create visualization" );
190 QLabel* description_label =
new QLabel(
"Description:" );
199 topic_widget->
fill(factory);
205 QVBoxLayout *type_layout =
new QVBoxLayout;
207 type_layout->addWidget( description_label );
210 type_box->setLayout( type_layout );
216 name_box =
new QGroupBox(
"Display Name" );
218 QVBoxLayout* name_layout =
new QVBoxLayout;
220 name_box->setLayout( name_layout );
224 button_box_ =
new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
227 QVBoxLayout* main_layout =
new QVBoxLayout;
228 main_layout->addWidget( type_box );
231 main_layout->addWidget( name_box );
234 setLayout( main_layout );
237 connect( display_tree, SIGNAL( itemChanged(
SelectionData* )),
239 connect( display_tree, SIGNAL( itemActivated( QTreeWidgetItem*,
int )),
242 connect( topic_widget, SIGNAL( itemChanged(
SelectionData* )),
244 connect( topic_widget, SIGNAL( itemActivated( QTreeWidgetItem*,
int )),
248 connect(
button_box_, SIGNAL( rejected() ),
this, SLOT( reject() ));
250 connect(
tab_widget_, SIGNAL( currentChanged(
int ) ),
254 connect(
name_editor_, SIGNAL( textEdited(
const QString& )),
263 return( QSize(500,660) );
300 QString html =
"<html><body>" + data->
whats_this +
"</body></html>";
319 setError(
"Select a Display type." );
325 if( display_name.size() == 0 )
327 setError(
"Enter a name for the display." );
332 setError(
"Name in use. Display names must be unique." );
342 button_box_->button( QDialogButtonBox::Ok )->setToolTip( error_text );
365 setHeaderHidden(
true );
367 connect(
this, SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
368 this, SLOT( onCurrentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )));
372 QTreeWidgetItem *prev)
376 if ( curr->parent() !=
NULL )
380 sd.
lookup_name = curr->data( 0, Qt::UserRole).toString();
383 Q_EMIT itemChanged( &sd );
388 QIcon default_package_icon =
loadPixmap(
"package://rviz/icons/default_package_icon.png" );
394 std::map<QString, QTreeWidgetItem*> package_items;
396 for(
int i = 0; i < classes.size(); i++ )
398 QString lookup_name = classes[ i ];
399 QString
package = factory->getClassPackage( lookup_name );
403 QTreeWidgetItem* package_item;
405 std::map<QString, QTreeWidgetItem*>::iterator mi;
406 mi = package_items.find(
package );
407 if( mi == package_items.end() )
409 package_item =
new QTreeWidgetItem(
this );
410 package_item->setText( 0,
package );
411 package_item->setIcon( 0, default_package_icon );
413 package_item->setExpanded(
true );
414 package_items[
package ] = package_item;
418 package_item = (*mi).second;
420 QTreeWidgetItem* class_item =
new QTreeWidgetItem( package_item );
422 class_item->setIcon( 0, factory->
getIcon( lookup_name ) );
424 class_item->setText( 0, name );
425 class_item->setWhatsThis( 0, description );
427 class_item->setData( 0, Qt::UserRole, lookup_name );
433 tree_ =
new QTreeWidget;
434 tree_->setHeaderHidden(
true );
435 tree_->setColumnCount( 2 );
437 tree_->header()->setStretchLastSection(
false );
438 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) 439 tree_->header()->setResizeMode( 0, QHeaderView::Stretch );
441 tree_->header()->setSectionResizeMode(0, QHeaderView::Stretch);
444 enable_hidden_box_ =
new QCheckBox(
"Show unvisualizable topics" );
445 enable_hidden_box_->setCheckState( Qt::Unchecked );
447 QVBoxLayout *layout =
new QVBoxLayout;
448 layout->setContentsMargins( QMargins( 0, 0, 0, 0 ) );
450 layout->addWidget( tree_ );
451 layout->addWidget( enable_hidden_box_ );
453 connect( tree_, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
454 this, SLOT(onCurrentItemChanged(QTreeWidgetItem*)));
456 connect( tree_, SIGNAL(itemActivated(QTreeWidgetItem*,
int)),
457 this, SIGNAL(itemActivated(QTreeWidgetItem*,
int)) );
460 connect( enable_hidden_box_, SIGNAL(stateChanged(
int)),
461 this, SLOT(stateChanged(
int)) );
470 if ( curr->data( 1, Qt::UserRole ).isValid() )
472 QTreeWidgetItem *parent = curr->parent();
475 sd.
topic = parent->data( 0, Qt::UserRole ).toString();
476 sd.
lookup_name = curr->data( 0, Qt::UserRole ).toString();
479 QComboBox *combo = qobject_cast<QComboBox*>( tree_->itemWidget( curr, 1 ) );
482 QString combo_text = combo->currentText();
483 if ( combo_text !=
"raw" )
485 sd.
topic +=
"/" + combo_text;
487 sd.
datatype = combo->itemData( combo->currentIndex() ).toString();
491 sd.
datatype = curr->data( 1, Qt::UserRole ).toString();
494 Q_EMIT itemChanged( &sd );
499 tree_->setCurrentItem( curr );
504 bool hide_disabled = state == Qt::Unchecked;
505 QTreeWidgetItemIterator it( tree_, QTreeWidgetItemIterator::Disabled );
508 QTreeWidgetItem *item = *it;
509 item->setHidden( hide_disabled );
515 findPlugins( factory );
517 QList<PluginGroup> groups;
518 QList<ros::master::TopicInfo> unvisualizable;
522 QList<PluginGroup>::const_iterator pg_it;
523 for( pg_it = groups.begin(); pg_it < groups.end(); ++pg_it)
527 QTreeWidgetItem *item = insertItem( pg.
base_topic,
false );
528 item->setData( 0, Qt::UserRole, pg.
base_topic );
530 QMap<QString, PluginGroup::Info>::const_iterator it;
533 const QString plugin_name = it.key();
535 QTreeWidgetItem *row =
new QTreeWidgetItem( item );
537 row->setText( 0, factory->
getClassName( plugin_name ) );
538 row->setIcon( 0, factory->
getIcon( plugin_name ) );
540 row->setData( 0, Qt::UserRole, plugin_name );
541 row->setData( 1, Qt::UserRole, info.
datatypes[0] );
546 connect( box, SIGNAL( itemClicked( QTreeWidgetItem*,
int )),
547 this, SLOT( onComboBoxClicked( QTreeWidgetItem* )));
552 tree_->setItemWidget( row, 1, box );
553 tree_->setColumnWidth( 1, std::max( tree_->columnWidth( 1 ), box->width() ));
559 for (
int i = 0; i < unvisualizable.size(); ++i )
562 QTreeWidgetItem *item = insertItem( QString::fromStdString( ti.
name ),
567 stateChanged( enable_hidden_box_->isChecked() );
575 QStringList::iterator it;
576 for (it = lookup_names.begin(); it != lookup_names.end(); ++it)
578 const QString &lookup_name = *it;
582 Q_FOREACH( QString topic_type, topic_types )
585 datatype_plugins_.insertMulti( topic_type, lookup_name );
593 QTreeWidgetItem *current = tree_->invisibleRootItem();;
594 QStringList parts = topic.split(
"/" );
596 for (
int part_ind = 1; part_ind < parts.size(); ++part_ind )
598 QString part =
"/" + parts[part_ind];
601 for (
int c = 0; c < current->childCount(); ++c )
603 QTreeWidgetItem *child = current->child( c );
604 if ( child->text( 0 ) == part && !child->data( 1, Qt::UserRole ).isValid() )
614 QTreeWidgetItem *new_child =
new QTreeWidgetItem( current );
616 new_child->setExpanded( 3 > part_ind );
617 new_child->setText( 0, part );
618 new_child->setDisabled( disabled );
QMap< QString, Info > plugins
AddDisplayDialog(DisplayFactory *factory, const QString &object_type, const QStringList &disallowed_display_names, const QStringList &disallowed_class_lookup_names, QString *lookup_name_output, QString *display_name_output=0, QString *topic_output=0, QString *datatype_output=0, QWidget *parent=0)
virtual QString getClassName(const QString &class_id) const =0
ROSCPP_DECL std::string parentNamespace(const std::string &name)
void fillTree(Factory *factory)
void onDisplaySelected(SelectionData *data)
SelectionData display_data_
ROSCPP_DECL bool getTopics(V_TopicInfo &topics)
ROSCPP_DECL bool validate(const std::string &name, std::string &error)
SelectionData topic_data_
virtual QString getClassName(const QString &class_id) const
virtual QIcon getIcon(const QString &class_id) const
std::vector< TopicInfo > V_TopicInfo
virtual QStringList getDeclaredClassIds()
virtual QSet< QString > getMessageTypes(const QString &class_id)
Get all supported message types for the given class id.
bool isSubtopic(const std::string &base, const std::string &topic)
QStringList topic_suffixes
virtual QString getClassDescription(const QString &class_id) const =0
const QStringList & disallowed_display_names_
void onCurrentItemChanged(QTreeWidgetItem *curr, QTreeWidgetItem *prev)
void onTopicSelected(SelectionData *data)
virtual QSize sizeHint() const
void onTabChanged(int index)
Abstract superclass representing the ability to get a list of class IDs and the ability to get name...
QTextBrowser * description_
virtual QString getClassDescription(const QString &class_id) const
QString * display_name_output_
QString * datatype_output_
void setError(const QString &error_text)
virtual QIcon getIcon(const QString &class_id) const =0
void getPluginGroups(const QMap< QString, QString > &datatype_plugins, QList< PluginGroup > *groups, QList< ros::master::TopicInfo > *unvisualizable)
#define ROS_ERROR_STREAM(args)
virtual QStringList getDeclaredClassIds()=0
QString * lookup_name_output_
QPixmap loadPixmap(QString url, bool fill_cache)
Widget for selecting a display by display type.
QDialogButtonBox * button_box_
bool operator()(const ros::master::TopicInfo &a, const ros::master::TopicInfo &b)