00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <QTimer>
00031 #include <QHBoxLayout>
00032 #include <QVBoxLayout>
00033 #include <QPushButton>
00034 #include <QInputDialog>
00035 #include <QApplication>
00036
00037 #include <boost/bind.hpp>
00038
00039 #include "rviz/display_factory.h"
00040 #include "rviz/display.h"
00041 #include "rviz/add_display_dialog.h"
00042 #include "rviz/properties/property.h"
00043 #include "rviz/properties/property_tree_widget.h"
00044 #include "rviz/properties/property_tree_with_help.h"
00045 #include "rviz/visualization_manager.h"
00046
00047 #include "rviz/displays_panel.h"
00048
00049 namespace rviz
00050 {
00051
00052 DisplaysPanel::DisplaysPanel( QWidget* parent )
00053 : Panel( parent )
00054 {
00055 tree_with_help_ = new PropertyTreeWithHelp;
00056 property_grid_ = tree_with_help_->getTree();
00057
00058 QPushButton* add_button = new QPushButton( "Add" );
00059 add_button->setShortcut( QKeySequence( QString( "Ctrl+N" )));
00060 add_button->setToolTip( "Add a new display, Ctrl+N" );
00061 duplicate_button_ = new QPushButton( "Duplicate" );
00062 duplicate_button_->setShortcut( QKeySequence( QString( "Ctrl+D" )));
00063 duplicate_button_->setToolTip( "Duplicate a display, Ctrl+D" );
00064 duplicate_button_->setEnabled( false );
00065 remove_button_ = new QPushButton( "Remove" );
00066 remove_button_->setShortcut( QKeySequence( QString( "Ctrl+X" )));
00067 remove_button_->setToolTip( "Remove displays, Ctrl+X" );
00068 remove_button_->setEnabled( false );
00069 rename_button_ = new QPushButton( "Rename" );
00070 rename_button_->setShortcut( QKeySequence( QString( "Ctrl+R" )));
00071 rename_button_->setToolTip( "Rename a display, Ctrl+R" );
00072 rename_button_->setEnabled( false );
00073
00074 QHBoxLayout* button_layout = new QHBoxLayout;
00075 button_layout->addWidget( add_button );
00076 button_layout->addWidget( duplicate_button_ );
00077 button_layout->addWidget( remove_button_ );
00078 button_layout->addWidget( rename_button_ );
00079 button_layout->setContentsMargins( 2, 0, 2, 2 );
00080
00081 QVBoxLayout* layout = new QVBoxLayout;
00082 layout->setContentsMargins( 0, 0, 0, 2 );
00083 layout->addWidget( tree_with_help_ );
00084 layout->addLayout( button_layout );
00085
00086 setLayout( layout );
00087
00088 connect( add_button, SIGNAL( clicked( bool )), this, SLOT( onNewDisplay() ));
00089 connect( duplicate_button_, SIGNAL( clicked( bool )), this, SLOT( onDuplicateDisplay() ));
00090 connect( remove_button_, SIGNAL( clicked( bool )), this, SLOT( onDeleteDisplay() ));
00091 connect( rename_button_, SIGNAL( clicked( bool )), this, SLOT( onRenameDisplay() ));
00092 connect( property_grid_, SIGNAL( selectionHasChanged() ), this, SLOT( onSelectionChanged() ));
00093 }
00094
00095 DisplaysPanel::~DisplaysPanel()
00096 {
00097 }
00098
00099 void DisplaysPanel::onInitialize()
00100 {
00101 property_grid_->setModel( vis_manager_->getDisplayTreeModel() );
00102 }
00103
00104 void DisplaysPanel::onNewDisplay()
00105 {
00106 QString lookup_name;
00107 QString display_name;
00108 QString topic;
00109 QString datatype;
00110
00111 QStringList empty;
00112
00113 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
00114 AddDisplayDialog* dialog = new AddDisplayDialog( vis_manager_->getDisplayFactory(),
00115 "Display",
00116 empty, empty,
00117 &lookup_name,
00118 &display_name,
00119 &topic,
00120 &datatype );
00121 QApplication::restoreOverrideCursor();
00122
00123 vis_manager_->stopUpdate();
00124 if( dialog->exec() == QDialog::Accepted )
00125 {
00126 Display *disp = vis_manager_->createDisplay( lookup_name, display_name, true );
00127 if ( !topic.isEmpty() && !datatype.isEmpty() )
00128 {
00129 disp->setTopic( topic, datatype );
00130 }
00131 }
00132 vis_manager_->startUpdate();
00133 activateWindow();
00134 delete dialog;
00135 }
00136
00137 void DisplaysPanel::onDuplicateDisplay()
00138 {
00139 QList<Display*> displays_to_duplicate = property_grid_->getSelectedObjects<Display>();
00140
00141 QList<Display*> duplicated_displays;
00142
00143 for( int i = 0; i < displays_to_duplicate.size(); i++ )
00144 {
00145
00146 QString lookup_name = displays_to_duplicate[ i ]->getClassId();
00147 QString display_name = displays_to_duplicate[ i ]->getName();
00148 Display *disp = vis_manager_->createDisplay( lookup_name, display_name, true );
00149
00150 Config config;
00151 displays_to_duplicate[ i ]->save(config);
00152 disp->load(config);
00153 duplicated_displays.push_back(disp);
00154 }
00155
00156 if (duplicated_displays.size() > 0) {
00157 QModelIndex first = property_grid_->getModel()->indexOf(duplicated_displays.front());
00158 QModelIndex last = property_grid_->getModel()->indexOf(duplicated_displays.back());
00159 QItemSelection selection(first, last);
00160 property_grid_->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
00161 }
00162 vis_manager_->startUpdate();
00163 activateWindow();
00164 }
00165
00166 void DisplaysPanel::onDeleteDisplay()
00167 {
00168 QList<Display*> displays_to_delete = property_grid_->getSelectedObjects<Display>();
00169
00170 QModelIndex new_selected;
00171
00172 for( int i = 0; i < displays_to_delete.size(); i++ )
00173 {
00174 if (i == 0) {
00175 QModelIndex first = property_grid_->getModel()->indexOf(displays_to_delete[i]);
00176
00177 new_selected = first.sibling(first.row() - 1, first.column());
00178 }
00179
00180
00181 displays_to_delete[ i ]->disconnect();
00182
00183 displays_to_delete[ i ]->deleteLater();
00184 }
00185
00186 QItemSelection selection(new_selected, new_selected);
00187 property_grid_->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
00188
00189 vis_manager_->notifyConfigChanged();
00190 }
00191
00192 void DisplaysPanel::onSelectionChanged()
00193 {
00194 QList<Display*> displays = property_grid_->getSelectedObjects<Display>();
00195
00196 int num_displays_selected = displays.size();
00197
00198 duplicate_button_->setEnabled( num_displays_selected > 0 );
00199 remove_button_->setEnabled( num_displays_selected > 0 );
00200 rename_button_->setEnabled( num_displays_selected == 1 );
00201 }
00202
00203 void DisplaysPanel::onRenameDisplay()
00204 {
00205 QList<Display*> displays = property_grid_->getSelectedObjects<Display>();
00206 if( displays.size() == 0 )
00207 {
00208 return;
00209 }
00210 Display* display_to_rename = displays[ 0 ];
00211
00212 if( !display_to_rename )
00213 {
00214 return;
00215 }
00216
00217 QString old_name = display_to_rename->getName();
00218 QString new_name = QInputDialog::getText( this, "Rename Display", "New Name?", QLineEdit::Normal, old_name );
00219
00220 if( new_name.isEmpty() || new_name == old_name )
00221 {
00222 return;
00223 }
00224
00225 display_to_rename->setName( new_name );
00226 }
00227
00228 void DisplaysPanel::save( Config config ) const
00229 {
00230 Panel::save( config );
00231 tree_with_help_->save( config );
00232 }
00233
00234 void DisplaysPanel::load( const Config& config )
00235 {
00236 Panel::load( config );
00237 tree_with_help_->load( config );
00238 }
00239
00240 }