visualization_frame.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <fstream>
31 
32 #include <QAction>
33 #include <QShortcut>
34 #include <QApplication>
35 #include <QCloseEvent>
36 #include <QDesktopServices>
37 #include <QDockWidget>
38 #include <QDir>
39 #include <QFileDialog>
40 #include <QMenu>
41 #include <QMenuBar>
42 #include <QMessageBox>
43 #include <QTimer>
44 #include <QToolBar>
45 #include <QToolButton>
46 #include <QUrl>
47 #include <QStatusBar>
48 #include <QLabel>
49 #include <QToolButton>
50 #include <QHBoxLayout>
51 #include <QTabBar>
52 
53 #include <boost/algorithm/string/split.hpp>
54 #include <boost/algorithm/string/trim.hpp>
55 #include <boost/bind.hpp>
56 #include <boost/filesystem.hpp>
57 
58 #include <ros/console.h>
59 #include <ros/package.h>
60 #include <ros/init.h>
61 
62 #include <OgreRenderWindow.h>
63 #include <OgreMeshManager.h>
64 
66 
67 #include "rviz/displays_panel.h"
68 #include "rviz/env_config.h"
69 #include "rviz/failed_panel.h"
70 #include "rviz/help_panel.h"
71 #include "rviz/loading_dialog.h"
72 #include "rviz/new_object_dialog.h"
73 #include "rviz/panel_dock_widget.h"
74 #include "rviz/panel_factory.h"
75 #include "rviz/render_panel.h"
76 #include "rviz/screenshot_dialog.h"
78 #include "rviz/selection_panel.h"
79 #include "rviz/splash_screen.h"
80 #include "rviz/time_panel.h"
81 #include "rviz/tool.h"
82 #include "rviz/tool_manager.h"
84 #include "rviz/views_panel.h"
87 #include "rviz/load_resource.h"
90 
92 
93 namespace fs = boost::filesystem;
94 
95 #define CONFIG_EXTENSION "rviz"
96 #define CONFIG_EXTENSION_WILDCARD "*." CONFIG_EXTENSION
97 #define RECENT_CONFIG_COUNT 10
98 
99 #if BOOST_FILESYSTEM_VERSION == 3
100 #define BOOST_FILENAME_STRING filename().string
101 #define BOOST_FILE_STRING string
102 #else
103 #define BOOST_FILENAME_STRING filename
104 #define BOOST_FILE_STRING file_string
105 #endif
106 
107 namespace rviz
108 {
109 
111  : QMainWindow( parent )
112  , app_(NULL)
113  , render_panel_(NULL)
114  , show_help_action_(NULL)
115  , file_menu_(NULL)
116  , recent_configs_menu_(NULL)
117  , toolbar_(NULL)
118  , manager_(NULL)
119  , splash_( NULL )
120  , toolbar_actions_( NULL )
121  , show_choose_new_master_option_( false )
122  , add_tool_action_( NULL )
123  , remove_tool_menu_( NULL )
124  , initialized_( false )
125  , geom_change_detector_( new WidgetGeometryChangeDetector( this ))
126  , loading_( false )
127  , post_load_timer_( new QTimer( this ))
128  , frame_count_(0)
129  , toolbar_visible_(true)
130 {
132 
133  installEventFilter( geom_change_detector_ );
134  connect( geom_change_detector_, SIGNAL( changed() ), this, SLOT( setDisplayConfigModified() ));
135 
136  post_load_timer_->setSingleShot( true );
137  connect( post_load_timer_, SIGNAL( timeout() ), this, SLOT( markLoadingDone() ));
138 
140  help_path_ = QString::fromStdString( (fs::path(package_path_) / "help/help.html").BOOST_FILE_STRING() );
141  splash_path_ = QString::fromStdString( (fs::path(package_path_) / "images/splash.png").BOOST_FILE_STRING() );
142 
143  QToolButton* reset_button = new QToolButton( );
144  reset_button->setText( "Reset" );
145  reset_button->setContentsMargins(0,0,0,0);
146  statusBar()->addPermanentWidget( reset_button, 0 );
147  connect( reset_button, SIGNAL( clicked( bool )), this, SLOT( reset() ));
148 
149  status_label_ = new QLabel("");
150  statusBar()->addPermanentWidget( status_label_, 1 );
151  connect( this, SIGNAL( statusUpdate( const QString& )), status_label_, SLOT( setText( const QString& )));
152 
153  fps_label_ = new QLabel("");
154  fps_label_->setMinimumWidth(40);
155  fps_label_->setAlignment(Qt::AlignRight);
156  statusBar()->addPermanentWidget( fps_label_, 0 );
157  original_status_bar_ = statusBar();
158 
159  setWindowTitle( "RViz[*]" );
160 }
161 
163 {
164  delete render_panel_;
165  delete manager_;
166 
167  for( int i = 0; i < custom_panels_.size(); i++ )
168  {
169  delete custom_panels_[ i ].dock;
170  }
171 
172  delete panel_factory_;
173 }
174 
175 void VisualizationFrame::setApp( QApplication * app )
176 {
177  app_ = app;
178 }
179 
180 void VisualizationFrame::setStatus( const QString & message )
181 {
182  Q_EMIT statusUpdate( message );
183 }
184 
186 {
187  frame_count_ ++;
189 
190  if ( wall_diff.toSec() > 1.0 )
191  {
192  float fps = frame_count_ / wall_diff.toSec();
193  frame_count_ = 0;
195  if ( original_status_bar_ == statusBar() )
196  {
197  fps_label_->setText( QString::number(int(fps)) + QString(" fps") );
198  }
199  }
200 }
201 
202 void VisualizationFrame::closeEvent( QCloseEvent* event )
203 {
204  if( prepareToExit() )
205  {
206  event->accept();
207  }
208  else
209  {
210  event->ignore();
211  }
212 }
213 
214 void VisualizationFrame::leaveEvent ( QEvent * event )
215 {
216  setStatus("");
217 }
218 
220 {
221  Ogre::MeshManager::getSingleton().removeAll();
222  manager_->resetTime();
223 }
224 
226 {
227  if( prepareToExit() )
228  {
229  QApplication::exit( 255 );
230  }
231 }
232 
234 {
236 }
237 
238 void VisualizationFrame::setHelpPath( const QString& help_path )
239 {
240  help_path_ = help_path;
242 }
243 
244 void VisualizationFrame::setSplashPath( const QString& splash_path )
245 {
246  splash_path_ = splash_path;
247 }
248 
249 void VisualizationFrame::initialize(const QString& display_config_file )
250 {
251  initConfigs();
252 
254 
255  QIcon app_icon( QString::fromStdString( (fs::path(package_path_) / "icons/package.png").BOOST_FILE_STRING() ) );
256  setWindowIcon( app_icon );
257 
258  if( splash_path_ != "" )
259  {
260  QPixmap splash_image( splash_path_ );
261  splash_ = new SplashScreen( splash_image );
262  splash_->show();
263  connect( this, SIGNAL( statusUpdate( const QString& )), splash_, SLOT( showMessage( const QString& )));
264  }
265  Q_EMIT statusUpdate( "Initializing" );
266 
267  // Periodically process events for the splash screen.
268  // See: http://doc.qt.io/qt-5/qsplashscreen.html#details
269  if (app_) app_->processEvents();
270 
271  if( !ros::isInitialized() )
272  {
273  int argc = 0;
274  ros::init( argc, 0, "rviz", ros::init_options::AnonymousName );
275  }
276 
277  // Periodically process events for the splash screen.
278  if (app_) app_->processEvents();
279 
280  QWidget* central_widget = new QWidget(this);
281  QHBoxLayout* central_layout = new QHBoxLayout;
282  central_layout->setSpacing(0);
283  central_layout->setMargin(0);
284 
285  render_panel_ = new RenderPanel( central_widget );
286 
287  hide_left_dock_button_ = new QToolButton();
288  hide_left_dock_button_->setContentsMargins(0,0,0,0);
289  hide_left_dock_button_->setArrowType( Qt::LeftArrow );
290  hide_left_dock_button_->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
291  hide_left_dock_button_->setFixedWidth(16);
292  hide_left_dock_button_->setAutoRaise(true);
293  hide_left_dock_button_->setCheckable(true);
294 
295  connect(hide_left_dock_button_, SIGNAL(toggled(bool)), this, SLOT(hideLeftDock(bool)));
296 
297  hide_right_dock_button_ = new QToolButton();
298  hide_right_dock_button_->setContentsMargins(0,0,0,0);
299  hide_right_dock_button_->setArrowType( Qt::RightArrow );
300  hide_right_dock_button_->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
301  hide_right_dock_button_->setFixedWidth(16);
302  hide_right_dock_button_->setAutoRaise(true);
303  hide_right_dock_button_->setCheckable(true);
304 
305  connect(hide_right_dock_button_, SIGNAL(toggled(bool)), this, SLOT(hideRightDock(bool)));
306 
307  central_layout->addWidget( hide_left_dock_button_, 0 );
308  central_layout->addWidget( render_panel_, 1 );
309  central_layout->addWidget( hide_right_dock_button_, 0 );
310 
311  central_widget->setLayout( central_layout );
312 
313  // Periodically process events for the splash screen.
314  if (app_) app_->processEvents();
315 
316  initMenus();
317 
318  // Periodically process events for the splash screen.
319  if (app_) app_->processEvents();
320 
321  initToolbars();
322 
323  // Periodically process events for the splash screen.
324  if (app_) app_->processEvents();
325 
326  setCentralWidget( central_widget );
327 
328  // Periodically process events for the splash screen.
329  if (app_) app_->processEvents();
330 
333 
334  // Periodically process events for the splash screen.
335  if (app_) app_->processEvents();
336 
338 
339  // Periodically process events for the splash screen.
340  if (app_) app_->processEvents();
341 
342  ToolManager* tool_man = manager_->getToolManager();
343 
344  connect( manager_, SIGNAL( configChanged() ), this, SLOT( setDisplayConfigModified() ));
345  connect( tool_man, SIGNAL( toolAdded( Tool* )), this, SLOT( addTool( Tool* )));
346  connect( tool_man, SIGNAL( toolRemoved( Tool* )), this, SLOT( removeTool( Tool* )));
347  connect( tool_man, SIGNAL( toolRefreshed( Tool* )), this, SLOT( refreshTool( Tool* )));
348  connect( tool_man, SIGNAL( toolChanged( Tool* )), this, SLOT( indicateToolIsCurrent( Tool* )));
349 
350  manager_->initialize();
351 
352  // Periodically process events for the splash screen.
353  if (app_) app_->processEvents();
354 
355  if( display_config_file != "" )
356  {
357  loadDisplayConfig( display_config_file );
358  }
359  else
360  {
361  loadDisplayConfig( QString::fromStdString( default_display_config_file_ ));
362  }
363 
364  // Periodically process events for the splash screen.
365  if (app_) app_->processEvents();
366 
367  delete splash_;
368  splash_ = 0;
369 
371  initialized_ = true;
372  Q_EMIT statusUpdate( "RViz is ready." );
373 
374  connect( manager_, SIGNAL( preUpdate() ), this, SLOT( updateFps() ) );
375  connect( manager_, SIGNAL( statusUpdate( const QString& )), this, SIGNAL( statusUpdate( const QString& )));
376 }
377 
379 {
380  home_dir_ = QDir::toNativeSeparators( QDir::homePath() ).toStdString();
381 
382  config_dir_ = (fs::path(home_dir_) / ".rviz").BOOST_FILE_STRING();
383  persistent_settings_file_ = (fs::path(config_dir_) / "persistent_settings").BOOST_FILE_STRING();
385 
386  if( fs::is_regular_file( config_dir_ ))
387  {
388  ROS_ERROR("Moving file [%s] out of the way to recreate it as a directory.", config_dir_.c_str());
389  std::string backup_file = config_dir_ + ".bak";
390 
391  fs::rename(config_dir_, backup_file);
392  fs::create_directory(config_dir_);
393  }
394  else if (!fs::exists(config_dir_))
395  {
396  fs::create_directory(config_dir_);
397  }
398 }
399 
401 {
402  YamlConfigReader reader;
403  Config config;
404  reader.readFile( config, QString::fromStdString( persistent_settings_file_ ));
405  if( !reader.error() )
406  {
407  QString last_config_dir, last_image_dir;
408  if( config.mapGetString( "Last Config Dir", &last_config_dir ) &&
409  config.mapGetString( "Last Image Dir", &last_image_dir ))
410  {
411  last_config_dir_ = last_config_dir.toStdString();
412  last_image_dir_ = last_image_dir.toStdString();
413  }
414 
415  Config recent_configs_list = config.mapGetChild( "Recent Configs" );
416  recent_configs_.clear();
417  int num_recent = recent_configs_list.listLength();
418  for( int i = 0; i < num_recent; i++ )
419  {
420  recent_configs_.push_back( recent_configs_list.listChildAt( i ).getValue().toString().toStdString() );
421  }
422  }
423  else
424  {
425  ROS_ERROR( "%s", qPrintable( reader.errorMessage() ));
426  }
427 }
428 
430 {
431  Config config;
432  config.mapSetValue( "Last Config Dir", QString::fromStdString( last_config_dir_ ));
433  config.mapSetValue( "Last Image Dir", QString::fromStdString( last_image_dir_ ));
434  Config recent_configs_list = config.mapMakeChild( "Recent Configs" );
435  for( D_string::iterator it = recent_configs_.begin(); it != recent_configs_.end(); ++it )
436  {
437  recent_configs_list.listAppendNew().setValue( QString::fromStdString( *it ));
438  }
439 
440  YamlConfigWriter writer;
441  writer.writeFile( config, QString::fromStdString( persistent_settings_file_ ));
442 
443  if( writer.error() )
444  {
445  ROS_ERROR( "%s", qPrintable( writer.errorMessage() ));
446  }
447 }
448 
450 {
451  file_menu_ = menuBar()->addMenu( "&File" );
452 
453  QAction * file_menu_open_action = file_menu_->addAction( "&Open Config", this, SLOT( onOpen() ), QKeySequence( "Ctrl+O" ));
454  this->addAction(file_menu_open_action);
455  QAction * file_menu_save_action = file_menu_->addAction( "&Save Config", this, SLOT( onSave() ), QKeySequence( "Ctrl+S" ));
456  this->addAction(file_menu_save_action);
457  QAction * file_menu_save_as_action = file_menu_->addAction( "Save Config &As", this, SLOT( onSaveAs() ), QKeySequence( "Ctrl+Shift+S"));
458  this->addAction(file_menu_save_as_action);
459 
460  recent_configs_menu_ = file_menu_->addMenu( "&Recent Configs" );
461  file_menu_->addAction( "Save &Image", this, SLOT( onSaveImage() ));
463  {
464  file_menu_->addSeparator();
465  file_menu_->addAction( "Change &Master", this, SLOT( changeMaster() ));
466  }
467  file_menu_->addSeparator();
468 
469  QAction * file_menu_quit_action = file_menu_->addAction( "&Quit", this, SLOT( close() ), QKeySequence( "Ctrl+Q" ));
470  this->addAction(file_menu_quit_action);
471 
472  view_menu_ = menuBar()->addMenu( "&Panels" );
473  view_menu_->addAction( "Add &New Panel", this, SLOT( openNewPanelDialog() ));
474  delete_view_menu_ = view_menu_->addMenu( "&Delete Panel" );
475  delete_view_menu_->setEnabled( false );
476 
477  QAction * fullscreen_action = view_menu_->addAction("&Fullscreen", this, SLOT( setFullScreen(bool) ), Qt::Key_F11);
478  fullscreen_action->setCheckable(true);
479  this->addAction(fullscreen_action); // Also add to window, or the shortcut doest work when the menu is hidden.
480  connect(this, SIGNAL( fullScreenChange( bool ) ), fullscreen_action, SLOT( setChecked( bool ) ) );
481  new QShortcut(Qt::Key_Escape, this, SLOT( exitFullScreen() ));
482  view_menu_->addSeparator();
483 
484  QMenu* help_menu = menuBar()->addMenu( "&Help" );
485  help_menu->addAction( "Show &Help panel", this, SLOT( showHelpPanel() ));
486  help_menu->addAction( "Open rviz wiki in browser", this, SLOT( onHelpWiki() ));
487  help_menu->addSeparator();
488  help_menu->addAction( "&About", this, SLOT( onHelpAbout() ));
489 }
490 
492 {
493  QFont font;
494  font.setPointSize( font.pointSizeF()*0.9 );
495 
496  // make toolbar with plugin tools
497 
498  toolbar_ = addToolBar( "Tools" );
499  toolbar_->setFont( font );
500  toolbar_->setContentsMargins(0,0,0,0);
501  toolbar_->setObjectName( "Tools" );
502  toolbar_->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
503  toolbar_actions_ = new QActionGroup( this );
504  connect( toolbar_actions_, SIGNAL( triggered( QAction* )), this, SLOT( onToolbarActionTriggered( QAction* )));
505  view_menu_->addAction( toolbar_->toggleViewAction() );
506 
507  add_tool_action_ = toolbar_->addSeparator();
508 
509  QToolButton* add_tool_button = new QToolButton();
510  add_tool_button->setToolTip( "Add a new tool" );
511  add_tool_button->setIcon( loadPixmap( "package://rviz/icons/plus.png" ) );
512  toolbar_->addWidget( add_tool_button );
513  connect(add_tool_button, SIGNAL(clicked()), this, SLOT(openNewToolDialog()));
514 
515  remove_tool_menu_ = new QMenu();
516  QToolButton* remove_tool_button = new QToolButton();
517  remove_tool_button->setMenu( remove_tool_menu_ );
518  remove_tool_button->setPopupMode( QToolButton::InstantPopup );
519  remove_tool_button->setToolTip( "Remove a tool from the toolbar" );
520  remove_tool_button->setIcon( loadPixmap( "package://rviz/icons/minus.png" ) );
521  toolbar_->addWidget( remove_tool_button );
522  connect( remove_tool_menu_, SIGNAL( triggered( QAction* )), this, SLOT( onToolbarRemoveTool( QAction* )));
523 
524  QMenu* button_style_menu = new QMenu();
525  QAction* action_tool_button_icon_only = new QAction( "Icon only", toolbar_actions_ );
526  action_tool_button_icon_only->setData(Qt::ToolButtonIconOnly);
527  button_style_menu->addAction(action_tool_button_icon_only);
528  QAction* action_tool_button_text_only = new QAction( "Text only", toolbar_actions_ );
529  action_tool_button_text_only->setData(Qt::ToolButtonTextOnly);
530  button_style_menu->addAction(action_tool_button_text_only);
531  QAction* action_tool_button_text_beside_icon = new QAction( "Text beside icon", toolbar_actions_ );
532  action_tool_button_text_beside_icon->setData(Qt::ToolButtonTextBesideIcon);
533  button_style_menu->addAction(action_tool_button_text_beside_icon);
534  QAction* action_tool_button_text_under_icon = new QAction( "Text under icon", toolbar_actions_ );
535  action_tool_button_text_under_icon->setData(Qt::ToolButtonTextUnderIcon);
536  button_style_menu->addAction(action_tool_button_text_under_icon);
537 
538  QToolButton* button_style_button = new QToolButton();
539  button_style_button->setMenu( button_style_menu );
540  button_style_button->setPopupMode( QToolButton::InstantPopup );
541  button_style_button->setToolTip( "Set toolbar style" );
542  button_style_button->setIcon( loadPixmap( "package://rviz/icons/visibility.svg" ) );
543  toolbar_->addWidget( button_style_button );
544  connect( button_style_menu, SIGNAL( triggered( QAction* )), this, SLOT( onButtonStyleTool( QAction* )));
545 }
546 
547 void VisualizationFrame::hideDockImpl( Qt::DockWidgetArea area, bool hide )
548 {
549  QList<PanelDockWidget *> dock_widgets = findChildren<PanelDockWidget *>();
550 
551  for ( QList<PanelDockWidget *>::iterator it=dock_widgets.begin(); it!=dock_widgets.end(); it++ )
552  {
553  Qt::DockWidgetArea curr_area = dockWidgetArea ( *it );
554  if ( area == curr_area )
555  {
556  (*it)->setCollapsed(hide);
557  }
558  // allow/disallow docking to this area for all widgets
559  if ( hide )
560  {
561  (*it)->setAllowedAreas( (*it)->allowedAreas() & ~area );
562  }
563  else
564  {
565  (*it)->setAllowedAreas( (*it)->allowedAreas() | area );
566  }
567  }
568 }
569 
571 {
572  hide_left_dock_button_->setVisible( visible );
573  hide_right_dock_button_->setVisible( visible );
574 }
575 
577 {
578  hideDockImpl( Qt::LeftDockWidgetArea, hide );
579  hide_left_dock_button_->setArrowType( hide ? Qt::RightArrow : Qt::LeftArrow );
580 }
581 
583 {
584  hideDockImpl( Qt::RightDockWidgetArea, hide );
585  hide_right_dock_button_->setArrowType( hide ? Qt::LeftArrow : Qt::RightArrow );
586 }
587 
589 {
590  // if a dock widget becomes visible and is resting inside the
591  // left or right dock area, we want to unhide the whole area
592  if ( visible )
593  {
594  QDockWidget* dock_widget = dynamic_cast<QDockWidget*>( sender() );
595  if ( dock_widget )
596  {
597  Qt::DockWidgetArea area = dockWidgetArea( dock_widget );
598  if ( area == Qt::LeftDockWidgetArea )
599  {
600  hide_left_dock_button_->setChecked( false );
601  }
602  if ( area == Qt::RightDockWidgetArea )
603  {
604  hide_right_dock_button_->setChecked( false );
605  }
606  }
607  }
608 
609 }
610 
612 {
613  QString class_id;
614  QString display_name;
615  QStringList empty;
616 
618  "Panel",
619  empty,
620  empty,
621  &class_id,
622  &display_name,
623  this );
624  manager_->stopUpdate();
625  if( dialog->exec() == QDialog::Accepted )
626  {
627  QDockWidget *dock = addPanelByName( display_name, class_id );
628  if ( dock )
629  {
630  connect( dock, SIGNAL( dockLocationChanged( Qt::DockWidgetArea )), this, SLOT( onDockPanelChange() ) );
631  }
632  }
634 }
635 
637 {
638  QString class_id;
639  QStringList empty;
640  ToolManager* tool_man = manager_->getToolManager();
641 
642  NewObjectDialog* dialog = new NewObjectDialog( tool_man->getFactory(),
643  "Tool",
644  empty,
645  tool_man->getToolClasses(),
646  &class_id );
647  manager_->stopUpdate();
648  if( dialog->exec() == QDialog::Accepted )
649  {
650  tool_man->addTool( class_id );
651  }
653  activateWindow(); // Force keyboard focus back on main window.
654 }
655 
657 {
658  recent_configs_menu_->clear();
659 
660  D_string::iterator it = recent_configs_.begin();
661  D_string::iterator end = recent_configs_.end();
662  for (; it != end; ++it)
663  {
664  if( *it != "" )
665  {
666  std::string display_name = *it;
667  if( display_name == default_display_config_file_ )
668  {
669  display_name += " (default)";
670  }
671  if( display_name.find( home_dir_ ) == 0 )
672  {
673  display_name = ("~" / fs::path( display_name.substr( home_dir_.size() ))).BOOST_FILE_STRING();
674  }
675  QString qdisplay_name = QString::fromStdString( display_name );
676  QAction* action = new QAction( qdisplay_name, this );
677  action->setData( QString::fromStdString( *it ));
678  connect( action, SIGNAL( triggered() ), this, SLOT( onRecentConfigSelected() ));
679  recent_configs_menu_->addAction( action );
680  }
681  }
682 }
683 
684 void VisualizationFrame::markRecentConfig( const std::string& path )
685 {
686  D_string::iterator it = std::find( recent_configs_.begin(), recent_configs_.end(), path );
687  if( it != recent_configs_.end() )
688  {
689  recent_configs_.erase( it );
690  }
691 
692  recent_configs_.push_front( path );
693 
694  if( recent_configs_.size() > RECENT_CONFIG_COUNT )
695  {
696  recent_configs_.pop_back();
697  }
698 
700 }
701 
702 void VisualizationFrame::loadDisplayConfig( const QString& qpath )
703 {
704  std::string path = qpath.toStdString();
705  std::string actual_load_path = path;
706  if( !fs::exists( path ) || fs::is_directory( path ) || fs::is_empty( path ))
707  {
708  actual_load_path = (fs::path(package_path_) / "default.rviz").BOOST_FILE_STRING();
709  if( !fs::exists( actual_load_path ))
710  {
711  ROS_ERROR( "Default display config '%s' not found. RViz will be very empty at first.", actual_load_path.c_str() );
712  return;
713  }
714  }
715 
716  // Check if we have unsaved changes to the current config the same
717  // as we do during exit, with the same option to cancel.
718  if( !prepareToExit() )
719  {
720  return;
721  }
722 
723  setWindowModified( false );
724  loading_ = true;
725 
726  LoadingDialog* dialog = NULL;
727  if( initialized_ )
728  {
729  dialog = new LoadingDialog( this );
730  dialog->show();
731  connect( this, SIGNAL( statusUpdate( const QString& )), dialog, SLOT( showMessage( const QString& )));
732  }
733 
734  YamlConfigReader reader;
735  Config config;
736  reader.readFile( config, QString::fromStdString( actual_load_path ));
737  if( !reader.error() )
738  {
739  load( config );
740  }
741 
742  markRecentConfig( path );
743 
744  setDisplayConfigFile( path );
745 
746  last_config_dir_ = fs::path( path ).parent_path().BOOST_FILE_STRING();
747 
748  delete dialog;
749 
750  post_load_timer_->start( 1000 );
751 }
752 
754 {
755  loading_ = false;
756 }
757 
758 void VisualizationFrame::setImageSaveDirectory( const QString& directory )
759 {
760  last_image_dir_ = directory.toStdString();
761 }
762 
764 {
765  if( !loading_ )
766  {
767  if( !isWindowModified() )
768  {
769  setWindowModified( true );
770  }
771  }
772 }
773 
774 void VisualizationFrame::setDisplayConfigFile( const std::string& path )
775 {
776  display_config_file_ = path;
777 
778  std::string title;
779  if( path == default_display_config_file_ )
780  {
781  title = "RViz[*]";
782  }
783  else
784  {
785  title = fs::path( path ).BOOST_FILENAME_STRING() + "[*] - RViz";
786  }
787  setWindowTitle( QString::fromStdString( title ));
788 }
789 
790 bool VisualizationFrame::saveDisplayConfig( const QString& path )
791 {
792  Config config;
793  save( config );
794 
795  YamlConfigWriter writer;
796  writer.writeFile( config, path );
797 
798  if( writer.error() )
799  {
800  ROS_ERROR( "%s", qPrintable( writer.errorMessage() ));
801  error_message_ = writer.errorMessage();
802  return false;
803  }
804  else
805  {
806  setWindowModified( false );
807  error_message_ = "";
808  return true;
809  }
810 }
811 
813 {
814  manager_->save( config.mapMakeChild( "Visualization Manager" ));
815  savePanels( config.mapMakeChild( "Panels" ));
816  saveWindowGeometry( config.mapMakeChild( "Window Geometry" ));
817  saveToolbars( config.mapMakeChild( "Toolbars" ));
818 }
819 
820 void VisualizationFrame::load( const Config& config )
821 {
822  manager_->load( config.mapGetChild( "Visualization Manager" ));
823  loadPanels( config.mapGetChild( "Panels" ));
824  loadWindowGeometry( config.mapGetChild( "Window Geometry" ));
825  configureToolbars( config.mapGetChild( "Toolbars" ));
826 }
827 
829 {
830  int x, y;
831  if( config.mapGetInt( "X", &x ) &&
832  config.mapGetInt( "Y", &y ))
833  {
834  move( x, y );
835  }
836 
837  int width, height;
838  if( config.mapGetInt( "Width", &width ) &&
839  config.mapGetInt( "Height", &height ))
840  {
841  resize( width, height );
842  }
843 
844  QString main_window_config;
845  if( config.mapGetString( "QMainWindow State", &main_window_config ))
846  {
847  restoreState( QByteArray::fromHex( qPrintable( main_window_config )));
848  }
849 
850  // load panel dock widget states (collapsed or not)
851  QList<PanelDockWidget *> dock_widgets = findChildren<PanelDockWidget *>();
852 
853  for ( QList<PanelDockWidget *>::iterator it=dock_widgets.begin(); it!=dock_widgets.end(); it++ )
854  {
855  Config itConfig = config.mapGetChild((*it)->windowTitle());
856 
857  if (itConfig.isValid())
858  {
859  (*it)->load(itConfig);
860  }
861  }
862 
863  bool b;
864  config.mapGetBool( "Hide Left Dock", &b );
865  hide_left_dock_button_->setChecked( b );
866  hideLeftDock(b);
867  config.mapGetBool( "Hide Right Dock", &b );
868  hideRightDock(b);
869  hide_right_dock_button_->setChecked( b );
870 }
871 
873 {
874  int tool_button_style;
875  if ( config.mapGetInt( "toolButtonStyle", &tool_button_style) )
876  {
877  toolbar_->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(tool_button_style));
878  }
879 }
880 
882 {
883  config.mapSetValue( "toolButtonStyle", static_cast<int>(toolbar_->toolButtonStyle()) );
884 }
885 
887 {
888  config.mapSetValue( "X", x() );
889  config.mapSetValue( "Y", y() );
890  config.mapSetValue( "Width", width() );
891  config.mapSetValue( "Height", height() );
892 
893  QByteArray window_state = saveState().toHex();
894  config.mapSetValue( "QMainWindow State", window_state.constData() );
895 
896  config.mapSetValue( "Hide Left Dock", hide_left_dock_button_->isChecked() );
897  config.mapSetValue( "Hide Right Dock", hide_right_dock_button_->isChecked() );
898 
899  // save panel dock widget states (collapsed or not)
900  QList<PanelDockWidget *> dock_widgets = findChildren<PanelDockWidget *>();
901 
902  for ( QList<PanelDockWidget *>::iterator it=dock_widgets.begin(); it!=dock_widgets.end(); it++ )
903  {
904  (*it)->save(config.mapMakeChild( (*it)->windowTitle() ));
905  }
906 }
907 
909 {
910  // First destroy any existing custom panels.
911  for( int i = 0; i < custom_panels_.size(); i++ )
912  {
913  delete custom_panels_[ i ].dock;
914  delete custom_panels_[ i ].delete_action;
915  }
916  custom_panels_.clear();
917 
918  // Then load the ones in the config.
919  int num_custom_panels = config.listLength();
920  for( int i = 0; i < num_custom_panels; i++ )
921  {
922  Config panel_config = config.listChildAt( i );
923 
924  QString class_id, name;
925  if( panel_config.mapGetString( "Class", &class_id ) &&
926  panel_config.mapGetString( "Name", &name ))
927  {
928  QDockWidget* dock = addPanelByName( name, class_id );
929  // This is kind of ridiculous - should just be something like
930  // createPanel() and addPanel() so I can do load() without this
931  // qobject_cast.
932  if( dock )
933  {
934  connect(dock, SIGNAL( dockLocationChanged( Qt::DockWidgetArea )), this, SLOT( onDockPanelChange() ) );
935  Panel* panel = qobject_cast<Panel*>( dock->widget() );
936  if( panel )
937  {
938  panel->load( panel_config );
939  }
940  }
941  }
942  }
943 
945 }
946 
948 {
949  config.setType( Config::List ); // Not really necessary, but gives an empty list if there are no entries, instead of an Empty config node.
950 
951  for( int i = 0; i < custom_panels_.size(); i++ )
952  {
953  custom_panels_[ i ].panel->save( config.listAppendNew() );
954  }
955 }
956 
958 {
959  if( !initialized_ )
960  {
961  return true;
962  }
963 
965 
966  if( isWindowModified() )
967  {
968  QMessageBox box( this );
969  box.setText( "There are unsaved changes." );
970  box.setInformativeText( QString::fromStdString( "Save changes to " + display_config_file_ + "?" ));
971  box.setStandardButtons( QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel );
972  box.setDefaultButton( QMessageBox::Save );
973  manager_->stopUpdate();
974  int result = box.exec();
976  switch( result )
977  {
978  case QMessageBox::Save:
979  if( saveDisplayConfig( QString::fromStdString( display_config_file_ )))
980  {
981  return true;
982  }
983  else
984  {
985  QMessageBox box( this );
986  box.setWindowTitle( "Failed to save." );
987  box.setText( getErrorMessage() );
988  box.setInformativeText( QString::fromStdString( "Save copy of " + display_config_file_ + " to another file?" ));
989  box.setStandardButtons( QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel );
990  box.setDefaultButton( QMessageBox::Save );
991  int result = box.exec();
992  switch( result )
993  {
994  case QMessageBox::Save:
995  onSaveAs();
996  return true;
997  case QMessageBox::Discard:
998  return true;
999  default:
1000  return false;
1001  }
1002 
1003  }
1004  case QMessageBox::Discard:
1005  return true;
1006  default:
1007  return false;
1008  }
1009  }
1010  else
1011  {
1012  return true;
1013  }
1014 }
1015 
1017 {
1018  manager_->stopUpdate();
1019  QString filename = QFileDialog::getOpenFileName( this, "Choose a file to open",
1020  QString::fromStdString( last_config_dir_ ),
1021  "RViz config files (" CONFIG_EXTENSION_WILDCARD ")" );
1022  manager_->startUpdate();
1023 
1024  if( !filename.isEmpty() )
1025  {
1026  std::string path = filename.toStdString();
1027 
1028  if( !fs::exists( path ))
1029  {
1030  QString message = filename + " does not exist!";
1031  QMessageBox::critical( this, "Config file does not exist", message );
1032  return;
1033  }
1034 
1035  loadDisplayConfig( filename );
1036  }
1037 }
1038 
1040 {
1041  if( !initialized_ )
1042  {
1043  return;
1044  }
1045 
1047 
1048  if( !saveDisplayConfig( QString::fromStdString( display_config_file_ )))
1049  {
1050  manager_->stopUpdate();
1051  QMessageBox box( this );
1052  box.setWindowTitle( "Failed to save." );
1053  box.setText( getErrorMessage() );
1054  box.setInformativeText( QString::fromStdString( "Save copy of " + display_config_file_ + " to another file?" ));
1055  box.setStandardButtons( QMessageBox::Save | QMessageBox::Cancel );
1056  box.setDefaultButton( QMessageBox::Save );
1057  if( box.exec() == QMessageBox::Save )
1058  {
1059  onSaveAs();
1060  }
1061  manager_->startUpdate();
1062  }
1063 }
1064 
1066 {
1067  manager_->stopUpdate();
1068  QString q_filename = QFileDialog::getSaveFileName( this, "Choose a file to save to",
1069  QString::fromStdString( last_config_dir_ ),
1070  "RViz config files (" CONFIG_EXTENSION_WILDCARD ")" );
1071  manager_->startUpdate();
1072 
1073  if( !q_filename.isEmpty() )
1074  {
1075  std::string filename = q_filename.toStdString();
1076  fs::path path( filename );
1077  if( path.extension() != "." CONFIG_EXTENSION )
1078  {
1079  filename += "." CONFIG_EXTENSION;
1080  }
1081 
1082  if( !saveDisplayConfig( QString::fromStdString( filename )))
1083  {
1084  QMessageBox::critical( this, "Failed to save.", getErrorMessage() );
1085  }
1086 
1087  markRecentConfig( filename );
1088  last_config_dir_ = fs::path( filename ).parent_path().BOOST_FILE_STRING();
1089  setDisplayConfigFile( filename );
1090  }
1091 }
1092 
1094 {
1095  ScreenshotDialog* dialog = new ScreenshotDialog( this, render_panel_, QString::fromStdString( last_image_dir_ ));
1096  connect( dialog, SIGNAL( savedInDirectory( const QString& )),
1097  this, SLOT( setImageSaveDirectory( const QString& )));
1098  dialog->show();
1099 }
1100 
1102 {
1103  QAction* action = dynamic_cast<QAction*>( sender() );
1104  if( action )
1105  {
1106  std::string path = action->data().toString().toStdString();
1107  if( !path.empty() )
1108  {
1109  if( !fs::exists( path ))
1110  {
1111  QString message = QString::fromStdString( path ) + " does not exist!";
1112  QMessageBox::critical( this, "Config file does not exist", message );
1113  return;
1114  }
1115 
1116  loadDisplayConfig( QString::fromStdString( path ));
1117  }
1118  }
1119 }
1120 
1122 {
1123  QAction* action = new QAction( tool->getName(), toolbar_actions_ );
1124  action->setIcon( tool->getIcon() );
1125  action->setIconText( tool->getName() );
1126  action->setCheckable( true );
1127  toolbar_->insertAction(add_tool_action_, action);
1128  action_to_tool_map_[ action ] = tool;
1129  tool_to_action_map_[ tool ] = action;
1130 
1131  remove_tool_menu_->addAction( tool->getName() );
1132 }
1133 
1135 {
1136  Tool* tool = action_to_tool_map_[ action ];
1137 
1138  if( tool )
1139  {
1141  }
1142 }
1143 
1144 void VisualizationFrame::onToolbarRemoveTool( QAction* remove_tool_menu_action )
1145 {
1146  QString name = remove_tool_menu_action->text();
1147  for( int i = 0; i < manager_->getToolManager()->numTools(); i++ )
1148  {
1149  Tool* tool = manager_->getToolManager()->getTool( i );
1150  if( tool->getName() == name )
1151  {
1153  return;
1154  }
1155  }
1156 }
1157 
1158 void VisualizationFrame::onButtonStyleTool( QAction* button_style_tool_menu_action )
1159 {
1160  toolbar_->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(button_style_tool_menu_action->data().toInt()));
1161 }
1162 
1164 {
1165  QAction* action = tool_to_action_map_[ tool ];
1166  if( action )
1167  {
1168  toolbar_actions_->removeAction( action );
1169  toolbar_->removeAction( action );
1170  tool_to_action_map_.erase( tool );
1171  action_to_tool_map_.erase( action );
1172  }
1173  QString tool_name = tool->getName();
1174  QList<QAction*> remove_tool_actions = remove_tool_menu_->actions();
1175  for( int i = 0; i < remove_tool_actions.size(); i++ )
1176  {
1177  QAction* removal_action = remove_tool_actions.at( i );
1178  if( removal_action->text() == tool_name )
1179  {
1180  remove_tool_menu_->removeAction( removal_action );
1181  break;
1182  }
1183  }
1184 }
1185 
1187 {
1188  QAction* action = tool_to_action_map_[ tool ];
1189  action->setIcon( tool->getIcon() );
1190  action->setIconText( tool->getName() );
1191 }
1192 
1194 {
1195  QAction* action = tool_to_action_map_[ tool ];
1196  if( action )
1197  {
1198  action->setChecked( true );
1199  }
1200 }
1201 
1203 {
1204  if( !show_help_action_ )
1205  {
1206  QDockWidget* dock = addPanelByName( "Help", "rviz/Help" );
1207  show_help_action_ = dock->toggleViewAction();
1208  connect( dock, SIGNAL( destroyed( QObject* )), this, SLOT( onHelpDestroyed() ));
1209  }
1210  else
1211  {
1212  // show_help_action_ is a toggle action, so trigger() changes its
1213  // state. Therefore we must force it to the opposite state from
1214  // what we want before we call trigger(). (I think.)
1215  show_help_action_->setChecked( false );
1216  show_help_action_->trigger();
1217  }
1218 }
1219 
1221 {
1223 }
1224 
1226 {
1227  QDesktopServices::openUrl( QUrl( "http://www.ros.org/wiki/rviz" ));
1228 }
1229 
1231 {
1232  QString about_text = QString(
1233  "This is RViz version %1 (%2).\n"
1234  "\n"
1235  "Compiled against Qt version %3."
1236  "\n"
1237  "Compiled against OGRE version %4.%5.%6%7 (%8)."
1238  )
1239  .arg(get_version().c_str())
1240  .arg(get_distro().c_str())
1241  .arg(QT_VERSION_STR)
1242  .arg(OGRE_VERSION_MAJOR)
1243  .arg(OGRE_VERSION_MINOR)
1244  .arg(OGRE_VERSION_PATCH)
1245  .arg(OGRE_VERSION_SUFFIX)
1246  .arg(OGRE_VERSION_NAME);
1247 
1248  QMessageBox::about(QApplication::activeWindow(), "About", about_text);
1249 }
1250 
1252 {
1253 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
1254  QList<QTabBar *> tab_bars = findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly);
1255 #else
1256  QList<QTabBar *> tab_bars = findChildren<QTabBar *>(QString());
1257 #endif
1258 
1259  for ( QList<QTabBar *>::iterator it = tab_bars.begin(); it != tab_bars.end(); it++ )
1260  {
1261 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1262  if((*it)->parent() == this)
1263 #endif
1264  {
1265  (*it)->setElideMode( Qt::ElideNone );
1266  }
1267  }
1268 }
1269 
1271 {
1272  return this;
1273 }
1274 
1276 {
1277  // This should only be called as a SLOT from a QAction in the
1278  // "delete panel" submenu, so the sender will be one of the QActions
1279  // stored as "delete_action" in a PanelRecord. This code looks for
1280  // a delete_action in custom_panels_ matching sender() and removes
1281  // the panel associated with it.
1282  if( QAction* action = qobject_cast<QAction*>( sender() ))
1283  {
1284  for( int i = 0; i < custom_panels_.size(); i++ )
1285  {
1286  if( custom_panels_[ i ].delete_action == action )
1287  {
1288  delete custom_panels_[ i ].dock;
1289  custom_panels_.removeAt( i );
1291  action->deleteLater();
1292  if( delete_view_menu_->actions().size() == 1 &&
1293  delete_view_menu_->actions().first() == action )
1294  {
1295  delete_view_menu_->setEnabled( false );
1296  }
1297  return;
1298  }
1299  }
1300  }
1301 }
1302 
1303 void VisualizationFrame::setFullScreen( bool full_screen )
1304 {
1305  Qt::WindowStates state = windowState();
1306  if (full_screen == state.testFlag(Qt::WindowFullScreen))
1307  return;
1308  Q_EMIT( fullScreenChange( full_screen ) );
1309 
1310  // when switching to fullscreen, remember visibility state of toolbar
1311  if (full_screen)
1312  toolbar_visible_ = toolbar_->isVisible();
1313  menuBar()->setVisible(!full_screen);
1314  toolbar_->setVisible(!full_screen && toolbar_visible_);
1315  statusBar()->setVisible(!full_screen);
1316  setHideButtonVisibility(!full_screen);
1317 
1318  if (full_screen)
1319  setWindowState(state | Qt::WindowFullScreen);
1320  else
1321  setWindowState(state & ~Qt::WindowFullScreen);
1322  show();
1323 }
1324 
1326 {
1327  setFullScreen( false );
1328 }
1329 
1330 QDockWidget* VisualizationFrame::addPanelByName( const QString& name,
1331  const QString& class_id,
1332  Qt::DockWidgetArea area,
1333  bool floating )
1334 {
1335  QString error;
1336  Panel* panel = panel_factory_->make( class_id, &error );
1337  if( !panel )
1338  {
1339  panel = new FailedPanel( class_id, error );
1340  }
1341  panel->setName( name );
1342  connect( panel, SIGNAL( configChanged() ), this, SLOT( setDisplayConfigModified() ));
1343 
1344  PanelRecord record;
1345  record.dock = addPane( name, panel, area, floating );
1346  record.panel = panel;
1347  record.name = name;
1348  record.delete_action = delete_view_menu_->addAction( name, this, SLOT( onDeletePanel() ));
1349  custom_panels_.append( record );
1350  delete_view_menu_->setEnabled( true );
1351 
1352  record.panel->initialize( manager_ );
1353 
1354  record.dock->setIcon( panel_factory_->getIcon( class_id ) );
1355 
1356  return record.dock;
1357 }
1358 
1359 PanelDockWidget* VisualizationFrame::addPane( const QString& name, QWidget* panel, Qt::DockWidgetArea area, bool floating )
1360 {
1361  PanelDockWidget *dock;
1362  dock = new PanelDockWidget( name );
1363  dock->setContentWidget( panel );
1364  dock->setFloating( floating );
1365  dock->setObjectName( name ); // QMainWindow::saveState() needs objectName to be set.
1366  addDockWidget( area, dock );
1367 
1368  // we want to know when that panel becomes visible
1369  connect( dock, SIGNAL( visibilityChanged( bool )), this, SLOT( onDockPanelVisibilityChange( bool ) ));
1370  connect( this, SIGNAL( fullScreenChange(bool) ), dock, SLOT( overrideVisibility(bool) ));
1371 
1372  QAction* toggle_action = dock->toggleViewAction();
1373  view_menu_->addAction( toggle_action );
1374 
1375  connect( toggle_action, SIGNAL( triggered( bool )), this, SLOT( setDisplayConfigModified() ));
1376  connect( dock, SIGNAL( closed()), this, SLOT( setDisplayConfigModified() ));
1377 
1378  dock->installEventFilter( geom_change_detector_ );
1379 
1380  // repair/update visibility status
1381  hideLeftDock( area == Qt::LeftDockWidgetArea ? false : hide_left_dock_button_->isChecked() );
1382  hideRightDock( area == Qt::RightDockWidgetArea ? false : hide_right_dock_button_->isChecked() );
1383 
1384  return dock;
1385 }
1386 
1387 } // end namespace rviz
void setContentWidget(QWidget *child)
void indicateToolIsCurrent(Tool *tool)
Mark the given tool as the current one.
void addTool(Tool *tool)
Add the given tool to this frame&#39;s toolbar.
QString getErrorMessage() const
void saveToolbars(Config config)
Saves the user configuration of the toolbar to the config node.
#define NULL
Definition: global.h:37
void exitFullScreen()
Exit full screen mode.
void setIcon(QIcon icon)
void setHideButtonVisibility(bool visible)
Hide or show the hide-dock buttons.
void initialize()
Do initialization that wasn&#39;t done in constructor. Initializes tool manager, view manager...
void removeTool(Tool *tool)
Remove the given tool from the frame&#39;s toolbar.
filename
void fullScreenChange(bool hidden)
Emitted when the interface enters or leaves full screen mode.
QDockWidget * addPanelByName(const QString &name, const QString &class_lookup_name, Qt::DockWidgetArea area=Qt::LeftDockWidgetArea, bool floating=true)
void setValue(const QVariant &value)
Ensures this is a valid Config object, sets the type to Value then sets the value.
Definition: config.cpp:305
bool saveDisplayConfig(const QString &path)
Save display and other settings to the given file.
virtual void load(const Config &config)
Load the properties of all subsystems from the given Config.
QString error_message_
Error message (if any) from most recent saveDisplayConfig() call.
void initialize(Ogre::SceneManager *scene_manager, DisplayContext *manager)
void initialize(VisualizationManager *manager)
Definition: panel.cpp:46
QString errorMessage()
Return an error message if the latest read call had an error, or the empty string if not...
void onDeletePanel()
Delete a panel widget.
void statusUpdate(const QString &message)
Emitted during file-loading and initialization to indicate progress.
void setSplashPath(const QString &splash_path)
Set the path to the "splash" image file. This image is shown during initialization and loading of the...
void removeTool(int index)
QString errorMessage()
Return an error message if the latest write call had an error, or the empty string if there was no er...
virtual QWidget * getParentWindow()
int listLength() const
Returns the length of the List in this Node, or 0 if this Node does not have type List...
Definition: config.cpp:317
ROSCPP_DECL bool isInitialized()
Config listChildAt(int i) const
Return the i&#39;th child in the list, if the referenced Node has type List. Returns an Invalid Config if...
Definition: config.cpp:322
void onToolbarRemoveTool(QAction *remove_tool_menu_action)
Remove a the tool whose name is given by remove_tool_menu_action->text().
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
config
Ogre::SceneManager * getSceneManager() const
Returns the Ogre::SceneManager used for the main RenderPanel.
virtual QIcon getIcon(const QString &class_id) const
Tool * getTool(int index)
Return the tool at a given index in the Tool list. If index is less than 0 or greater than the number...
TFSIMD_FORCE_INLINE const tfScalar & y() const
void initialize(const QString &display_config_file="")
Initialize the visualizer. Creates the VisualizationManager.
void savePanels(Config config)
Saves custom panels to the given config node.
bool toolbar_visible_
Indicates if the toolbar should be visible outside of fullscreen mode.
bool isValid() const
Returns true if the internal Node reference is valid, false if not. Same as (getType() != Invalid)...
Definition: config.cpp:300
std::map< Tool *, QAction * > tool_to_action_map_
virtual void setStatus(const QString &message)
bool error()
Return true if the latest write operation had an error.
virtual void onDockPanelVisibilityChange(bool visible)
virtual void closeEvent(QCloseEvent *event)
bool mapGetString(const QString &key, QString *value_out) const
Convenience function for looking up a named string.
Definition: config.cpp:281
void savePersistentSettings()
Save the "general" config file, which has just the few things which should not be saved with a displa...
void mapSetValue(const QString &key, QVariant value)
Set a named child to the given value.
Definition: config.cpp:185
void setCurrentTool(Tool *tool)
Set the current tool. The current tool is given all mouse and keyboard events which VisualizationMana...
A dialog for grabbing a screen shot.
Configuration data storage class.
Definition: config.h:125
void loadWindowGeometry(const Config &config)
virtual void setName(const QString &name)
Definition: panel.h:60
void onToolbarActionTriggered(QAction *action)
Looks up the Tool for this action and calls VisualizationManager::setCurrentTool().
void readFile(Config &config, const QString &filename)
Read config data from a file. This potentially changes the return value sof error(), statusMessage(), and config().
QList< PanelRecord > custom_panels_
void setDisplayConfigFile(const std::string &path)
Set the display config file path.
#define CONFIG_EXTENSION
QStringList getToolClasses()
void setImageSaveDirectory(const QString &directory)
Set the default directory in which to save screenshot images.
VisualizationManager * manager_
QVariant getValue() const
If this config object is valid and is a Value type, this returns its value. Otherwise it returns an i...
Definition: config.cpp:312
void setFullScreen(bool full_screen)
Set full screen mode.
Config mapMakeChild(const QString &key)
Create a child node stored with the given key, and return the child.
Definition: config.cpp:190
void loadPersistentSettings()
Load the "general" config file, which has just the few things which should not be saved with a displa...
bool mapGetBool(const QString &key, bool *value_out) const
Convenience function for looking up a named boolean.
Definition: config.cpp:270
std::string get_version()
The VisualizationManager class is the central manager class of rviz, holding all the Displays...
void setHelpPath(const QString &help_path)
Set the path to the help file. Should contain HTML. Default is a file in the RViz package...
Tool * addTool(const QString &tool_class_lookup_name)
Create a tool by class lookup name, add it to the list, and return it.
bool error()
Return true if the latest readFile() or readString() call had an error.
TFSIMD_FORCE_INLINE const tfScalar & x() const
std::map< QAction *, Tool * > action_to_tool_map_
virtual PanelDockWidget * addPane(const QString &name, QWidget *panel, Qt::DockWidgetArea area=Qt::LeftDockWidgetArea, bool floating=true)
#define RECENT_CONFIG_COUNT
void load(const Config &config)
Load the properties of each Display and most editable rviz data.
void initConfigs()
Initialize the default config directory (~/.rviz) and set up the persistent_settings_file_ and displa...
void markLoadingDone()
Set loading_ to false.
std::string get_distro()
bool mapGetInt(const QString &key, int *value_out) const
Convenience function for looking up a named integer.
Definition: config.cpp:229
ROSLIB_DECL std::string getPath(const std::string &package_name)
void save(Config config) const
Save the properties of each Display and most editable rviz data.
action
void onButtonStyleTool(QAction *button_style_tool_menu_action)
Change the button style of the toolbar.
void loadDisplayConfig(const QString &path)
Load display and other settings from the given file.
bool loading_
True just when loading a display config file, false all other times.
void writeFile(const Config &config, const QString &filename)
Write config data to a file. This potentially changes the return values of error() and statusMessage(...
const QIcon & getIcon()
Get the icon of this tool.
Definition: tool.h:154
static WallTime now()
void setDisplayConfigModified()
Call this to let the frame know that something that would get saved in the display config has changed...
QString getName() const
Definition: tool.h:113
void hideDockImpl(Qt::DockWidgetArea area, bool hide)
Config listAppendNew()
Ensure the referenced Node is of type List, append a new Empty Node to the end of the list...
Definition: config.cpp:334
void saveWindowGeometry(Config config)
#define CONFIG_EXTENSION_WILDCARD
PluginlibFactory< Tool > * getFactory()
Definition: tool_manager.h:118
void changeMaster()
Save the current state and quit with exit code 255 to signal the wrapper that we would like to restar...
VisualizationFrame(QWidget *parent=0)
Utility class for watching for events which indicate that widget geometry has changed.
QTimer * post_load_timer_
Single-shot timer for calling postLoad() a short time after loadDisplayConfig() finishes.
#define BOOST_FILE_STRING
bool prepareToExit()
Check for unsaved changes, prompt to save config, etc.
virtual ToolManager * getToolManager() const
Return a pointer to the ToolManager.
virtual Type * make(const QString &class_id, QString *error_return=NULL)
Instantiate and return a instance of a subclass of Type using makeRaw().
Config mapGetChild(const QString &key) const
If the referenced Node is a Map and it has a child with the given key, return a reference to the chil...
Definition: config.cpp:201
WidgetGeometryChangeDetector * geom_change_detector_
void initToolbars()
Sets up the top toolbar with QToolbuttions for adding/deleting tools and modifiying the tool view...
virtual void load(const Config &config)
Override to load configuration data. This version loads the name of the panel.
Definition: panel.cpp:58
void setApp(QApplication *app)
void loadPanels(const Config &config)
Loads custom panels from the given config node.
Dock widget class for docking widgets into VisualizationFrame.
void markRecentConfig(const std::string &path)
void startUpdate()
Start timers. Creates and starts the update and idle timers, both set to 30Hz (33ms).
#define ROS_ERROR(...)
QPixmap loadPixmap(QString url, bool fill_cache)
void setShowChooseNewMaster(bool show)
Call this before initialize() to have it take effect.
virtual void save(Config config)
Save the properties of each subsystem and most editable rviz data.
void resetTime()
Resets the wall and ROS elapsed time to zero and calls resetDisplays().
void setType(Type new_type)
Set the type of this Config Node.
Definition: config.cpp:172
void refreshTool(Tool *tool)
Refresh the given tool in this frame&#39;s&#39; toolbar.
virtual void setHelpPath(const QString &help_path)
void configureToolbars(const Config &config)
Applies the user defined toolbar configuration from the given config node.
virtual void leaveEvent(QEvent *event)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Wed Aug 28 2019 04:01:51