timeline_menu.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2009, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 
00033 from python_qt_binding.QtGui import QVBoxLayout, QMenu, QWidget, QDockWidget
00034 
00035 class TopicPopupWidget(QWidget):
00036     def __init__(self, popup_name, timeline, viewer_type, topic):
00037         super(TopicPopupWidget, self).__init__()
00038         self.setObjectName(popup_name)
00039         self.setWindowTitle(popup_name)
00040 
00041         layout = QVBoxLayout()
00042         self.setLayout(layout)
00043 
00044         self._timeline = timeline
00045         self._viewer_type = viewer_type
00046         self._topic = topic
00047         self._viewer = None
00048         self._is_listening = False
00049 
00050     def hideEvent(self, event):
00051         if self._is_listening:
00052             self._timeline.remove_listener(self._topic, self._viewer)
00053             self._is_listening = False
00054         super(TopicPopupWidget, self).hideEvent(event)
00055 
00056     def showEvent(self, event):
00057         if not self._is_listening:
00058             self._timeline.add_listener(self._topic, self._viewer)
00059             self._is_listening = True
00060         super(TopicPopupWidget, self).showEvent(event)
00061 
00062     def show(self, context):
00063         """
00064         Make this topic popup visible, if necessary. This includes setting up
00065         the proper close button hacks
00066         """
00067         if not self.parent():
00068             context.add_widget(self)
00069             # make the dock widget closable, even if it normally isn't
00070             dock_features = self.parent().features()
00071             dock_features |= QDockWidget.DockWidgetClosable
00072             self.parent().setFeatures(dock_features)
00073 
00074             # remove old listener
00075             if self._viewer:
00076                 self._timeline.remove_listener(self._topic, self._viewer)
00077                 self._viewer = None
00078 
00079             # clean out the layout
00080             while self.layout().count() > 0:
00081                 item = self.layout().itemAt(0)
00082                 self.layout().removeItem(item)
00083 
00084             # create a new viewer
00085             self._viewer = self._viewer_type(self._timeline, self, self._topic)
00086             if not self._is_listening:
00087                 self._timeline.add_listener(self._topic, self._viewer)
00088                 self._is_listening = True
00089 
00090         super(TopicPopupWidget, self).show()
00091 
00092 class TimelinePopupMenu(QMenu):
00093     """
00094     Custom popup menu displayed on rightclick from timeline
00095     """
00096     def __init__(self, timeline, event, menu_topic):
00097         super(TimelinePopupMenu, self).__init__()
00098 
00099         self.parent = timeline
00100         self.timeline = timeline
00101 
00102 
00103         if menu_topic is not None:
00104             self.setTitle(menu_topic)
00105             self._menu_topic = menu_topic
00106         else:
00107             self._menu_topic = None
00108 
00109         self._reset_timeline = self.addAction('Reset Timeline')
00110 
00111         self._play_all = self.addAction('Play All Messages')
00112         self._play_all.setCheckable(True)
00113         self._play_all.setChecked(self.timeline.play_all)
00114 
00115         self.addSeparator()
00116 
00117         self._renderers = self.timeline._timeline_frame.get_renderers()
00118         self._thumbnail_actions = []
00119 
00120         # create thumbnail menu items
00121         if menu_topic is None:
00122             submenu = self.addMenu('Thumbnails...')
00123             self._thumbnail_show_action = submenu.addAction('Show All')
00124             self._thumbnail_hide_action = submenu.addAction('Hide All')
00125             submenu.addSeparator()
00126 
00127             for topic, renderer in self._renderers:
00128                 self._thumbnail_actions.append(submenu.addAction(topic))
00129                 self._thumbnail_actions[-1].setCheckable(True)
00130                 self._thumbnail_actions[-1].setChecked(self.timeline._timeline_frame.is_renderer_active(topic))
00131         else:
00132             self._thumbnail_show_action = None
00133             self._thumbnail_hide_action = None
00134             for topic, renderer in self._renderers:
00135                 if menu_topic == topic:
00136                     self._thumbnail_actions.append(self.addAction("Thumbnail"))
00137                     self._thumbnail_actions[-1].setCheckable(True)
00138                     self._thumbnail_actions[-1].setChecked(self.timeline._timeline_frame.is_renderer_active(topic))
00139 
00140         # create view menu items
00141         self._topic_actions = []
00142         self._type_actions = []
00143         if menu_topic is None:
00144             self._topics = self.timeline._timeline_frame.topics
00145             view_topics_menu = self.addMenu('View (by Topic)')
00146             for topic in self._topics:
00147                 datatype = self.timeline.get_datatype(topic)
00148 
00149                 # View... / topic
00150                 topic_menu = QMenu(topic, self)
00151                 viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype)
00152 
00153                 # View... / topic / Viewer
00154                 for viewer_type in viewer_types:
00155                     tempaction = topic_menu.addAction(viewer_type.name)
00156                     tempaction.setData(viewer_type)
00157                     self._topic_actions.append(tempaction)
00158                 view_topics_menu.addMenu(topic_menu)
00159 
00160             view_type_menu = self.addMenu('View (by Type)')
00161             self._topics_by_type = self.timeline._timeline_frame._topics_by_datatype
00162             for datatype in self._topics_by_type:
00163                 # View... / datatype
00164                 datatype_menu = QMenu(datatype, self)
00165                 datatype_topics = self._topics_by_type[datatype]
00166                 viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype)
00167                 for topic in [t for t in self._topics if t in datatype_topics]:   # use timeline ordering
00168                     topic_menu = QMenu(topic, datatype_menu)
00169                     # View... / datatype / topic / Viewer
00170                     for viewer_type in viewer_types:
00171                         tempaction = topic_menu.addAction(viewer_type.name)
00172                         tempaction.setData(viewer_type)
00173                         self._topic_actions.append(tempaction)
00174                     datatype_menu.addMenu(topic_menu)
00175                 view_type_menu.addMenu(datatype_menu)
00176         else:
00177             view_menu = self.addMenu("View")
00178             datatype = self.timeline.get_datatype(menu_topic)
00179 
00180             viewer_types = self.timeline._timeline_frame.get_viewer_types(datatype)
00181             for viewer_type in viewer_types:
00182                 tempaction = view_menu.addAction(viewer_type.name)
00183                 tempaction.setData(viewer_type)
00184                 self._topic_actions.append(tempaction)
00185 
00186         self.addSeparator()
00187 
00188         # create publish menu items
00189         self._publish_actions = []
00190         if menu_topic is None:
00191             submenu = self.addMenu('Publish...')
00192 
00193             self._publish_all = submenu.addAction('Publish All')
00194             self._publish_none = submenu.addAction('Publish None')
00195 
00196             submenu.addSeparator()
00197 
00198             for topic in self._topics:
00199                 self._publish_actions.append(submenu.addAction(topic))
00200                 self._publish_actions[-1].setCheckable(True)
00201                 self._publish_actions[-1].setChecked(self.timeline.is_publishing(topic))
00202         else:
00203             self._publish_actions.append(self.addAction("Publish"))
00204             self._publish_actions[-1].setCheckable(True)
00205             self._publish_actions[-1].setChecked(self.timeline.is_publishing(menu_topic))
00206             self._publish_all = None
00207             self._publish_none = None
00208 
00209 
00210 
00211         action = self.exec_(event.globalPos())
00212         if action is not None and action != 0:
00213             self.process(action)
00214 
00215     def process(self, action):
00216         """
00217         :param action: action to execute, ''QAction''
00218         :raises: when it doesn't recognice the action passed in, ''Exception''
00219         """
00220         if action == self._reset_timeline:
00221             self.timeline._timeline_frame.reset_timeline()
00222         elif action == self._play_all:
00223             self.timeline.toggle_play_all()
00224         elif action == self._publish_all:
00225             for topic in self.timeline._timeline_frame.topics:
00226                 if not self.timeline.start_publishing(topic):
00227                     break
00228         elif action == self._publish_none:
00229             for topic in self.timeline._timeline_frame.topics:
00230                 if not self.timeline.stop_publishing(topic):
00231                     break
00232         elif action == self._thumbnail_show_action:
00233             self.timeline._timeline_frame.set_renderers_active(True)
00234         elif action == self._thumbnail_hide_action:
00235             self.timeline._timeline_frame.set_renderers_active(False)
00236         elif action in self._thumbnail_actions:
00237             if self._menu_topic is None:
00238                 topic = action.text()
00239             else:
00240                 topic = self._menu_topic
00241 
00242             if self.timeline._timeline_frame.is_renderer_active(topic):
00243                 self.timeline._timeline_frame.set_renderer_active(topic, False)
00244             else:
00245                 self.timeline._timeline_frame.set_renderer_active(topic, True)
00246         elif action in self._topic_actions + self._type_actions:
00247             if self._menu_topic is None:
00248                 topic = action.parentWidget().title()
00249             else:
00250                 topic = self._menu_topic
00251 
00252             popup_name = topic + '__' + action.text()
00253             if popup_name not in self.timeline.popups:
00254                 frame = TopicPopupWidget(popup_name, self.timeline,
00255                                          action.data(), str(topic))
00256 
00257                 self.timeline.add_view(topic, frame)
00258                 self.timeline.popups[popup_name] = frame
00259 
00260             # make popup visible
00261             frame = self.timeline.popups[popup_name]
00262             frame.show(self.timeline.get_context())
00263 
00264         elif action in self._publish_actions:
00265             if self._menu_topic is None:
00266                 topic = action.text()
00267             else:
00268                 topic = self._menu_topic
00269 
00270             if self.timeline.is_publishing(topic):
00271                 self.timeline.stop_publishing(topic)
00272             else:
00273                 self.timeline.start_publishing(topic)
00274         else:
00275             raise Exception('Unknown action in TimelinePopupMenu.process')


rqt_bag
Author(s): Aaron Blasdel, Tim Field
autogenerated on Wed Sep 16 2015 06:58:10