displays_panel.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 <QAction>
31 #include <QTimer>
32 #include <QHBoxLayout>
33 #include <QVBoxLayout>
34 #include <QPushButton>
35 #include <QInputDialog>
36 #include <QApplication>
37 #include <QProgressDialog>
38 
39 #include <boost/bind/bind.hpp>
40 
41 #include <rviz/display_factory.h>
42 #include <rviz/display.h>
48 
49 #include <rviz/displays_panel.h>
50 
51 namespace rviz
52 {
53 DisplaysPanel::DisplaysPanel(QWidget* parent) : Panel(parent)
54 {
57 
58  QPushButton* add_button = new QPushButton("Add");
59  add_button->setShortcut(QKeySequence(QString("Ctrl+N")));
60  add_button->setToolTip("Add a new display, Ctrl+N");
61  duplicate_button_ = new QPushButton("Duplicate");
62  duplicate_button_->setShortcut(QKeySequence(QString("Ctrl+D")));
63  duplicate_button_->setToolTip("Duplicate a display, Ctrl+D");
64  duplicate_button_->setEnabled(false);
65  remove_button_ = new QPushButton("Remove");
66  remove_button_->setShortcut(QKeySequence(QString("Ctrl+X")));
67  remove_button_->setToolTip("Remove displays, Ctrl+X");
68  remove_button_->setEnabled(false);
69  rename_button_ = new QPushButton("Rename");
70  rename_button_->setShortcut(QKeySequence(QString("Ctrl+R")));
71  rename_button_->setToolTip("Rename a display, Ctrl+R");
72  rename_button_->setEnabled(false);
73 
74  QHBoxLayout* button_layout = new QHBoxLayout;
75  button_layout->addWidget(add_button);
76  button_layout->addWidget(duplicate_button_);
77  button_layout->addWidget(remove_button_);
78  button_layout->addWidget(rename_button_);
79  button_layout->setContentsMargins(2, 0, 2, 2);
80 
81  QVBoxLayout* layout = new QVBoxLayout;
82  layout->setContentsMargins(0, 0, 0, 2);
83  layout->addWidget(tree_with_help_);
84  layout->addLayout(button_layout);
85 
86  setLayout(layout);
87 
88  connect(add_button, &QPushButton::clicked, this, &DisplaysPanel::onNewDisplay);
89  connect(duplicate_button_, &QPushButton::clicked, this, &DisplaysPanel::onDuplicateDisplay);
90  connect(remove_button_, &QPushButton::clicked, this, &DisplaysPanel::onDeleteDisplay);
91  connect(rename_button_, &QPushButton::clicked, this, &DisplaysPanel::onRenameDisplay);
94 
95  // additionally to buttons, allow shortcuts F2 / Del to rename / remove displays
96  rename_action_ = new QAction("Rename", this);
97  rename_action_->setShortcut(QKeySequence("F2"));
98  rename_action_->setShortcutContext(Qt::WidgetWithChildrenShortcut);
99  rename_action_->setEnabled(false);
100  tree_with_help_->addAction(rename_action_);
101  remove_action_ = new QAction("Remove", this);
102  remove_action_->setShortcut(QKeySequence("Del"));
103  remove_action_->setShortcutContext(Qt::WidgetWithChildrenShortcut);
104  remove_action_->setEnabled(false);
105  tree_with_help_->addAction(remove_action_);
106 
107  connect(rename_action_, &QAction::triggered, this, &DisplaysPanel::onRenameDisplay);
108  connect(remove_action_, &QAction::triggered, this, &DisplaysPanel::onDeleteDisplay);
109 }
110 
112 {
113 }
114 
116 {
118 }
119 
121 {
122  QString lookup_name;
123  QString display_name;
124  QString topic;
125  QString datatype;
126 
127  QStringList empty;
128 
129  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
130  AddDisplayDialog dialog(vis_manager_->getDisplayFactory(), "Display", empty, empty, &lookup_name,
131  &display_name, &topic, &datatype);
132  QApplication::restoreOverrideCursor();
133 
135  if (dialog.exec() == QDialog::Accepted)
136  {
137  Display* disp = vis_manager_->createDisplay(lookup_name, display_name, true);
138  if (!topic.isEmpty() && !datatype.isEmpty())
139  {
140  disp->setTopic(topic, datatype);
141  }
142  }
144  activateWindow(); // Force keyboard focus back on main window.
145 }
146 
148 {
149  QList<Display*> displays_to_duplicate = property_grid_->getSelectedObjects<Display>();
150  QList<Display*> duplicated_displays;
151  QProgressDialog progress_dlg("Duplicating displays...", "Cancel", 0, displays_to_duplicate.size(),
152  this);
154  progress_dlg.setWindowModality(Qt::WindowModal);
155  progress_dlg.show();
156  QApplication::processEvents(); // explicitly progress events for update
157 
158  // duplicate all selected displays
159  for (int i = 0; i < displays_to_duplicate.size(); i++)
160  {
161  // initialize display
162  QString lookup_name = displays_to_duplicate[i]->getClassId();
163  QString display_name = displays_to_duplicate[i]->getName();
164  Display* disp = vis_manager_->createDisplay(lookup_name, display_name, true);
165  // duplicate config
166  Config config;
167  displays_to_duplicate[i]->save(config);
168  disp->load(config);
169  duplicated_displays.push_back(disp);
170  progress_dlg.setValue(i + 1);
171  QApplication::processEvents(); // explicitly progress events for update
172  // push cancel to stop duplicate
173  if (progress_dlg.wasCanceled())
174  break;
175  }
176  // make sure the newly duplicated displays are selected.
177  if (!duplicated_displays.empty())
178  {
179  QModelIndex first = property_grid_->getModel()->indexOf(duplicated_displays.front());
180  QModelIndex last = property_grid_->getModel()->indexOf(duplicated_displays.back());
181  QItemSelection selection(first, last);
182  property_grid_->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
183  }
185  activateWindow(); // Force keyboard focus back on main window.
186 }
187 
189 {
190  QList<Display*> displays_to_delete = property_grid_->getSelectedObjects<Display>();
191 
192  for (int i = 0; i < displays_to_delete.size(); i++)
193  {
194  // Displays can emit signals from other threads with self pointers. We're
195  // freeing the display now, so ensure no one is listening to those signals.
196  displays_to_delete[i]->disconnect();
197  // Remove dipslay from property tree to avoid memory access after deletion
198  displays_to_delete[i]->getParent()->takeChild(displays_to_delete[i]);
199  // Delete display later in case there are pending signals to it.
200  displays_to_delete[i]->deleteLater();
201  }
202  // Select new current index
203  const QModelIndex& cur = property_grid_->currentIndex();
204  QItemSelection selection(cur.sibling(cur.row(), 0),
205  cur.sibling(cur.row(), cur.model()->columnCount() - 1));
206  property_grid_->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
207 
209 }
210 
212 {
213  QList<Display*> displays = property_grid_->getSelectedObjects<Display>();
214 
215  int num_displays_selected = displays.size();
216 
217  duplicate_button_->setEnabled(num_displays_selected > 0);
218  remove_button_->setEnabled(num_displays_selected > 0);
219  rename_button_->setEnabled(num_displays_selected == 1);
220 
221  remove_action_->setEnabled(num_displays_selected > 0);
222  rename_action_->setEnabled(num_displays_selected == 1);
223 }
224 
226 {
227  QList<Display*> displays = property_grid_->getSelectedObjects<Display>();
228  if (displays.empty())
229  {
230  return;
231  }
232  Display* display_to_rename = displays[0];
233 
234  QString old_name = display_to_rename->getName();
235  QString new_name =
236  QInputDialog::getText(this, "Rename Display", "New Name?", QLineEdit::Normal, old_name);
237 
238  if (new_name.isEmpty() || new_name == old_name)
239  {
240  return;
241  }
242 
243  display_to_rename->setName(new_name);
244 }
245 
246 void DisplaysPanel::save(Config config) const
247 {
250 }
251 
252 void DisplaysPanel::load(const Config& config)
253 {
256 }
257 
258 } // namespace rviz
rviz::DisplaysPanel::save
void save(Config config) const override
Write state to the given Config object.
Definition: displays_panel.cpp:246
rviz::DisplaysPanel::DisplaysPanel
DisplaysPanel(QWidget *parent=nullptr)
Definition: displays_panel.cpp:53
rviz::Panel
Definition: panel.h:41
display_factory.h
rviz::DisplaysPanel::load
void load(const Config &config) override
Read state from the given Config.
Definition: displays_panel.cpp:252
property.h
rviz::DisplaysPanel::onInitialize
void onInitialize() override
Definition: displays_panel.cpp:115
rviz::DisplaysPanel::onNewDisplay
void onNewDisplay()
Called when the "Add" button is pressed.
Definition: displays_panel.cpp:120
rviz::DisplaysPanel::duplicate_button_
QPushButton * duplicate_button_
Definition: displays_panel.h:86
rviz::DisplaysPanel::remove_action_
QAction * remove_action_
Definition: displays_panel.h:89
rviz::VisualizationManager::notifyConfigChanged
void notifyConfigChanged()
Notify this VisualizationManager that something about its display configuration has changed.
Definition: visualization_manager.cpp:580
rviz::DisplaysPanel::onSelectionChanged
void onSelectionChanged()
Definition: displays_panel.cpp:211
rviz::PropertyTreeWidget::getSelectedObjects
QList< Type * > getSelectedObjects()
Return the list of objects of a given type which are currently selected.
Definition: property_tree_widget.h:78
rviz::PropertyTreeWithHelp::getTree
PropertyTreeWidget * getTree()
Definition: property_tree_with_help.h:50
rviz::Display
Definition: display.h:63
rviz::Display::setTopic
virtual void setTopic(const QString &topic, const QString &datatype)
Set the ROS topic to listen to for this display.
Definition: display.h:122
displays_panel.h
add_display_dialog.h
rviz::DisplaysPanel::property_grid_
PropertyTreeWidget * property_grid_
Definition: displays_panel.h:84
rviz::DisplaysPanel::remove_button_
QPushButton * remove_button_
Definition: displays_panel.h:87
rviz::VisualizationManager::startUpdate
void startUpdate()
Start timers. Creates and starts the update and idle timers, both set to 30Hz (33ms).
Definition: visualization_manager.cpp:278
rviz::VisualizationManager::getDisplayFactory
DisplayFactory * getDisplayFactory() const override
Return a factory for creating Display subclasses based on a class id string.
Definition: visualization_manager.h:330
rviz::DisplaysPanel::~DisplaysPanel
~DisplaysPanel() override
Definition: displays_panel.cpp:111
rviz
Definition: add_display_dialog.cpp:54
rviz::PropertyTreeWidget::setModel
void setModel(PropertyTreeModel *model)
Set the data model this widget should view.
Definition: property_tree_widget.cpp:95
rviz::PropertyTreeModel::indexOf
QModelIndex indexOf(Property *property) const
Definition: property_tree_model.cpp:285
rviz::AddDisplayDialog
Definition: add_display_dialog.h:64
rviz::Display::load
void load(const Config &config) override
Load the settings for this display from the given Config node, which must be a map.
Definition: display.cpp:231
rviz::DisplaysPanel::onRenameDisplay
void onRenameDisplay()
Called when the "Rename" button is pressed.
Definition: displays_panel.cpp:225
property_tree_widget.h
rviz::PropertyTreeWidget::selectionHasChanged
void selectionHasChanged()
rviz::Property::getParent
Property * getParent() const
Return the parent Property.
Definition: property.cpp:231
rviz::DisplaysPanel::rename_action_
QAction * rename_action_
Definition: displays_panel.h:90
rviz::DisplaysPanel::tree_with_help_
PropertyTreeWithHelp * tree_with_help_
Definition: displays_panel.h:91
rviz::PropertyTreeWithHelp::save
void save(Config config) const
Write state to the given Config.
Definition: property_tree_with_help.cpp:79
visualization_manager.h
property_tree_with_help.h
rviz::Display::setName
void setName(const QString &name) override
Overridden from Property to set associated widget title to the new name.
Definition: display.cpp:402
display.h
rviz::Property::getName
virtual QString getName() const
Return the name of this Property as a QString.
Definition: property.cpp:164
rviz::PropertyTreeWithHelp::load
void load(const Config &config)
Read state from the given Config.
Definition: property_tree_with_help.cpp:88
rviz::Panel::load
virtual void load(const Config &config)
Override to load configuration data. This version loads the name of the panel.
Definition: panel.cpp:56
rviz::VisualizationManager::stopUpdate
void stopUpdate()
Definition: visualization_manager.cpp:284
rviz::VisualizationManager::createDisplay
Display * createDisplay(const QString &class_lookup_name, const QString &name, bool enabled)
Create and add a display to this panel, by class lookup name.
Definition: visualization_manager.cpp:474
rviz::PropertyTreeWidget::getModel
PropertyTreeModel * getModel() const
Definition: property_tree_widget.h:71
rviz::DisplaysPanel::onDeleteDisplay
void onDeleteDisplay()
Called when the "Remove" button is pressed.
Definition: displays_panel.cpp:188
rviz::Panel::save
virtual void save(Config config) const
Override to save configuration data. This version saves the name and class ID of the panel.
Definition: panel.cpp:50
datatype
const char * datatype()
rviz::DisplaysPanel::onDuplicateDisplay
void onDuplicateDisplay()
Called when the "copy" button is pressed.
Definition: displays_panel.cpp:147
rviz::PropertyTreeWithHelp
Definition: property_tree_with_help.h:44
rviz::DisplaysPanel::rename_button_
QPushButton * rename_button_
Definition: displays_panel.h:88
config
config
rviz::Property::takeChild
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
Definition: property.cpp:322
rviz::Config
Configuration data storage class.
Definition: config.h:124
rviz::VisualizationManager::getDisplayTreeModel
PropertyTreeModel * getDisplayTreeModel() const
Definition: visualization_manager.h:335
rviz::Panel::vis_manager_
VisualizationManager * vis_manager_
Definition: panel.h:113


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust, William Woodall
autogenerated on Sat Jun 1 2024 02:31:52