tool_manager.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 <QKeyEvent>
31 #include <QRegExp>
32 
33 #include <ros/assert.h>
34 
35 #include "rviz/failed_tool.h"
38 
39 #include "rviz/tool_manager.h"
40 
41 namespace rviz
42 {
43 
44 QString addSpaceToCamelCase( QString input )
45 {
46  QRegExp re = QRegExp( "([A-Z])([a-z]*)" );
47  input.replace( re, " \\1\\2" );
48  return input.trimmed();
49 }
50 
52  : factory_( new PluginlibFactory<Tool>( "rviz", "rviz::Tool" ))
53  , property_tree_model_( new PropertyTreeModel( new Property() ))
54  , context_( context )
55  , current_tool_( NULL )
56  , default_tool_( NULL )
57 {
58  connect( property_tree_model_, SIGNAL( configChanged() ), this, SIGNAL( configChanged() ));
59 }
60 
62 {
63  removeAll();
64  delete factory_;
65  delete property_tree_model_;
66 }
67 
69 {
70  // Possibly this should be done with a loop over
71  // factory_->getDeclaredClassIds(), but then I couldn't control the
72  // order.
73  addTool( "rviz/MoveCamera" );
74  addTool( "rviz/Interact" );
75  addTool( "rviz/Select" );
76  addTool( "rviz/SetInitialPose" );
77  addTool( "rviz/SetGoal" );
78 }
79 
81 {
82  for( int i = tools_.size() - 1; i >= 0; i-- )
83  {
84  removeTool( i );
85  }
86 }
87 
88 void ToolManager::load( const Config& config )
89 {
90  removeAll();
91 
92  int num_tools = config.listLength();
93  for( int i = 0; i < num_tools; i++ )
94  {
95  Config tool_config = config.listChildAt( i );
96 
97  QString class_id;
98  if( tool_config.mapGetString( "Class", &class_id ))
99  {
100  Tool* tool = addTool( class_id );
101  tool->load( tool_config );
102  }
103  }
104 }
105 
106 void ToolManager::save( Config config ) const
107 {
108  for( int i = 0; i < tools_.size(); i++ )
109  {
110  tools_[ i ]->save( config.listAppendNew() );
111  }
112 }
113 
114 bool ToolManager::toKey( QString const& str, uint& key )
115 {
116  QKeySequence seq( str );
117 
118  // We should only working with a single key here
119  if( seq.count() == 1 )
120  {
121  key = seq[ 0 ];
122  return true;
123  }
124  else
125  {
126  return false;
127  }
128 }
129 
130 void ToolManager::handleChar( QKeyEvent* event, RenderPanel* panel )
131 {
132  // if the incoming key is ESC fallback to the default tool
133  if( event->key() == Qt::Key_Escape )
134  {
136  return;
137  }
138 
139  // check if the incoming key triggers the activation of another tool
140  Tool* tool = NULL;
141  if( shortkey_to_tool_map_.find(event->key()) != shortkey_to_tool_map_.end() )
142  {
143  tool = shortkey_to_tool_map_[ event->key() ];
144  }
145 
146  if( tool )
147  {
148  // if there is a incoming tool check if it matches the current tool
149  if( current_tool_ == tool)
150  {
151  // if yes, deactivate the current tool and fallback to default
153  }
154  else
155  {
156  // if no, check if the current tool accesses all key events
158  {
159  // if yes, pass the key
160  current_tool_->processKeyEvent( event, panel );
161  }
162  else
163  {
164  // if no, switch the tool
165  setCurrentTool( tool );
166  }
167  }
168  }
169  else
170  {
171  // if the incoming key triggers no other tool,
172  // just hand down the key event
173  current_tool_->processKeyEvent( event, panel );
174  }
175 }
176 
178 {
179  if( current_tool_ )
180  {
182  }
183 
184  current_tool_ = tool;
185 
186  if( current_tool_ )
187  {
189  }
190 
191  Q_EMIT toolChanged( current_tool_ );
192 }
193 
195 {
196  default_tool_ = tool;
197 }
198 
200 {
201  ROS_ASSERT( index >= 0 );
202  ROS_ASSERT( index < (int)tools_.size() );
203 
204  return tools_[ index ];
205 }
206 
208 {
209  if( container->numChildren() > 0 )
210  {
211  if( !property_tree_model_->getRoot()->contains( container ))
212  {
213  property_tree_model_->getRoot()->addChild( container );
214  container->expand();
215  }
216  }
217  else
218  {
219  property_tree_model_->getRoot()->takeChild( container );
220  }
221 }
222 
224 {
226 }
227 
228 Tool* ToolManager::addTool( const QString& class_id )
229 {
230  QString error;
231  bool failed = false;
232  Tool* tool = factory_->make( class_id, &error );
233  if( !tool )
234  {
235  tool = new FailedTool( class_id, error );
236  failed = true;
237  }
238 
239  tools_.append( tool );
240  tool->setName( addSpaceToCamelCase( factory_->getClassName( class_id )));
241  tool->setIcon( factory_->getIcon( class_id ) );
242  tool->initialize( context_ );
243 
244  if( tool->getShortcutKey() != '\0' )
245  {
246  uint key;
247  QString str = QString( tool->getShortcutKey() );
248 
249  if( toKey( str, key ) )
250  {
251  shortkey_to_tool_map_[ key ] = tool;
252  }
253  }
254 
255  Property* container = tool->getPropertyContainer();
256  connect( container, SIGNAL( childListChanged( Property* )), this, SLOT( updatePropertyVisibility( Property* )));
257  updatePropertyVisibility( container );
258 
259  Q_EMIT toolAdded( tool );
260 
261  // If the default tool is unset and this tool loaded correctly, set
262  // it as the default and current.
263  if( default_tool_ == NULL && !failed )
264  {
265  setDefaultTool( tool );
266  setCurrentTool( tool );
267  }
268 
269  QObject::connect(tool, SIGNAL(close()),
270  this, SLOT(closeTool()));
271 
272  Q_EMIT configChanged();
273 
274  return tool;
275 }
276 
277 void ToolManager::removeTool( int index )
278 {
279  Tool* tool = tools_.takeAt( index );
280  Tool* fallback = NULL;
281  if( tools_.size() > 0 )
282  {
283  fallback = tools_[ 0 ];
284  }
285  if( tool == current_tool_ )
286  {
287  setCurrentTool( fallback );
288  }
289  if( tool == default_tool_ )
290  {
291  setDefaultTool( fallback );
292  }
293  Q_EMIT toolRemoved( tool );
294 
295  uint key;
296  if( toKey( QString( tool->getShortcutKey() ), key ) )
297  {
298  shortkey_to_tool_map_.erase( key );
299  }
300  delete tool;
301  Q_EMIT configChanged();
302 }
303 
305 {
306  Q_EMIT toolRefreshed( tool );
307 }
308 
310 {
311  QStringList class_names;
312  for( int i = 0; i < tools_.size(); i++ )
313  {
314  class_names.append( tools_[ i ]->getClassId() );
315  }
316  return class_names;
317 }
318 
319 } // end namespace rviz
void toolChanged(Tool *)
Emitted by setCurrentTool() after the newly chosen tool is activated.
virtual void activate()=0
#define NULL
Definition: global.h:37
PluginlibFactory< Tool > * factory_
Definition: tool_manager.h:147
virtual ~ToolManager()
virtual void expand()
Expand (show the children of) this Property.
Definition: property.cpp:542
void load(const Config &config)
void setDefaultTool(Tool *tool)
Set the default tool.
bool accessAllKeys()
Definition: tool.h:79
A FailedTool instance represents a Tool class we tried and failed to instantiate. ...
Definition: failed_tool.h:47
void removeTool(int index)
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
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 toolRefreshed(Tool *)
Emitted by refreshTool() to gedraw the tool&#39;s icon in the toolbar&#39;.
A single element of a property tree, with a name, value, description, and possibly children...
Definition: property.h:100
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...
ToolManager(DisplayContext *context)
char getShortcutKey()
Definition: tool.h:77
virtual int numChildren() const
Return the number of child objects (Property or otherwise).
Definition: property.h:215
bool mapGetString(const QString &key, QString *value_out) const
Convenience function for looking up a named string.
Definition: config.cpp:281
void initialize()
Initialization for after the DisplayContext is created. Loads standard RViz tools.
void setCurrentTool(Tool *tool)
Set the current tool. The current tool is given all mouse and keyboard events which VisualizationMana...
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
Definition: property.cpp:316
Configuration data storage class.
Definition: config.h:125
void toolRemoved(Tool *)
void configChanged()
Emitted when anything changes which will change the saved config file contents.
void updatePropertyVisibility(Property *property)
If property has children, it is added to the tool property tree, and if it does not, it is removed.
Pure-virtual base class for objects which give Display subclasses context in which to work...
QStringList getToolClasses()
void toolAdded(Tool *)
Emitted by addTool() after the tool is added to the list of tools.
virtual void load(const Config &config)
Load properties from the given Config.
Definition: tool.cpp:86
QList< Tool * > tools_
Definition: tool_manager.h:149
DisplayContext * context_
Definition: tool_manager.h:150
Tool * addTool(const QString &tool_class_lookup_name)
Create a tool by class lookup name, add it to the list, and return it.
PropertyTreeModel * property_tree_model_
Definition: tool_manager.h:148
void setName(const QString &name)
Set the name of the tool.
Definition: tool.cpp:74
bool contains(Property *possible_child) const
Return true if the list of children includes possible_child, false if not.
Definition: property.cpp:213
std::map< int, Tool * > shortkey_to_tool_map_
Definition: tool_manager.h:153
bool toKey(QString const &str, uint &key_out)
void handleChar(QKeyEvent *event, RenderPanel *panel)
void save(Config config) const
void initialize(DisplayContext *context)
Definition: tool.cpp:54
void setIcon(const QIcon &icon)
Set the toolbar icon for this tool (will also set its cursor).
Definition: tool.cpp:63
void closeTool()
Deactivates the current tool and sets the default tool.
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
virtual void addChild(Property *child, int index=-1)
Add a child property.
Definition: property.cpp:350
void refreshTool(Tool *tool)
Triggers redrawing the tool&#39;s icon/text in the toolbar.
virtual void deactivate()=0
virtual Property * getPropertyContainer() const
Return the container for properties of this Tool.
Definition: tool.h:75
#define ROS_ASSERT(cond)
Tool * getDefaultTool()
Get the default tool.
Definition: tool_manager.h:112
Property * getRoot() const
virtual int processKeyEvent(QKeyEvent *event, RenderPanel *panel)
Definition: tool.h:106
QString addSpaceToCamelCase(QString input)


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