messages_widget.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2012, 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 import os
00034 
00035 from python_qt_binding import loadUi
00036 from python_qt_binding.QtCore import Qt
00037 from python_qt_binding.QtGui import QIcon
00038 from python_qt_binding.QtWidgets import (QAction, QMenu, QMessageBox,
00039                                          QTreeView, QWidget)
00040 import roslib
00041 import rosmsg
00042 import rospkg
00043 import rospy
00044 
00045 
00046 from .messages_tree_view import MessagesTreeView
00047 from rqt_py_common import rosaction
00048 from rqt_console.text_browse_dialog import TextBrowseDialog
00049 
00050 
00051 class MessagesWidget(QWidget):
00052     """
00053     This class is intended to be able to handle msg, srv & action (actionlib).
00054     The name of the class is kept to use message, by following the habit of
00055     rosmsg (a script that can handle both msg & srv).
00056     """
00057     def __init__(self, mode=rosmsg.MODE_MSG,
00058                  pkg_name='rqt_msg',
00059                  ui_filename='messages.ui'):
00060         """
00061         :param ui_filename: This Qt-based .ui file must have elements that are
00062                             referred from this class. Otherwise unexpected
00063                             errors are likely to happen. Best way to avoid that
00064                             situation when you want to give your own .ui file
00065                             is to implement all Qt components in
00066                             rqt_msg/resource/message.ui file.
00067         """
00068 
00069         super(MessagesWidget, self).__init__()
00070         self._rospack = rospkg.RosPack()
00071         ui_file = os.path.join(self._rospack.get_path(pkg_name), 'resource', ui_filename)
00072         loadUi(ui_file, self, {'MessagesTreeView': MessagesTreeView})
00073         self.setObjectName(ui_filename)
00074         self._mode = mode
00075 
00076         self._add_button.setIcon(QIcon.fromTheme('list-add'))
00077         self._add_button.clicked.connect(self._add_message)
00078         self._refresh_packages(mode)
00079         self._refresh_msgs(self._package_combo.itemText(0))
00080         self._package_combo.currentIndexChanged[str].connect(self._refresh_msgs)
00081         self._messages_tree.mousePressEvent = self._handle_mouse_press
00082 
00083         self._browsers = []
00084 
00085     def _refresh_packages(self, mode=rosmsg.MODE_MSG):
00086         if (self._mode == rosmsg.MODE_MSG) or self._mode == rosmsg.MODE_SRV:
00087             packages = sorted([pkg_tuple[0] for pkg_tuple in
00088                                rosmsg.iterate_packages(self._rospack, self._mode)])
00089         elif self._mode == rosaction.MODE_ACTION:
00090             packages = sorted([pkg_tuple[0]
00091                                for pkg_tuple in rosaction.iterate_packages(
00092                                                          self._rospack, self._mode)])
00093         self._package_list = packages
00094         rospy.logdebug('pkgs={}'.format(self._package_list))
00095         self._package_combo.clear()
00096         self._package_combo.addItems(self._package_list)
00097         self._package_combo.setCurrentIndex(0)
00098 
00099     def _refresh_msgs(self, package=None):
00100         if package is None or len(package) == 0:
00101             return
00102         self._msgs = []
00103         if (self._mode == rosmsg.MODE_MSG or
00104             self._mode == rosaction.MODE_ACTION):
00105             msg_list = rosmsg.list_msgs(package)
00106         elif self._mode == rosmsg.MODE_SRV:
00107             msg_list = rosmsg.list_srvs(package)
00108 
00109         rospy.logdebug('_refresh_msgs package={} msg_list={}'.format(package,
00110                                                                     msg_list))
00111         for msg in msg_list:
00112             if (self._mode == rosmsg.MODE_MSG or
00113                 self._mode == rosaction.MODE_ACTION):
00114                 msg_class = roslib.message.get_message_class(msg)
00115             elif self._mode == rosmsg.MODE_SRV:
00116                 msg_class = roslib.message.get_service_class(msg)
00117 
00118             rospy.logdebug('_refresh_msgs msg_class={}'.format(msg_class))
00119 
00120             if msg_class is not None:
00121                 self._msgs.append(msg)
00122 
00123         self._msgs = [x.split('/')[1] for x in self._msgs]
00124 
00125         self._msgs_combo.clear()
00126         self._msgs_combo.addItems(self._msgs)
00127 
00128     def _add_message(self):
00129         if self._msgs_combo.count() == 0:
00130             return
00131         msg = (self._package_combo.currentText() +
00132                '/' + self._msgs_combo.currentText())
00133 
00134         rospy.logdebug('_add_message msg={}'.format(msg))
00135 
00136         if (self._mode == rosmsg.MODE_MSG or
00137             self._mode == rosaction.MODE_ACTION):
00138             msg_class = roslib.message.get_message_class(msg)()
00139             if self._mode == rosmsg.MODE_MSG:
00140                 text_tree_root = 'Msg Root'
00141             elif self._mode == rosaction.MODE_ACTION:
00142                 text_tree_root = 'Action Root'
00143             self._messages_tree.model().add_message(msg_class,
00144                                             self.tr(text_tree_root), msg, msg)
00145 
00146         elif self._mode == rosmsg.MODE_SRV:
00147             msg_class = roslib.message.get_service_class(msg)()
00148             self._messages_tree.model().add_message(msg_class._request_class,
00149                                                 self.tr('Service Request'),
00150                                                 msg, msg)
00151             self._messages_tree.model().add_message(msg_class._response_class,
00152                                                 self.tr('Service Response'),
00153                                                 msg, msg)
00154         self._messages_tree._recursive_set_editable(
00155                         self._messages_tree.model().invisibleRootItem(), False)
00156 
00157     def _handle_mouse_press(self, event,
00158                             old_pressEvent=QTreeView.mousePressEvent):
00159         if (event.buttons() & Qt.RightButton and
00160             event.modifiers() == Qt.NoModifier):
00161             self._rightclick_menu(event)
00162             event.accept()
00163         return old_pressEvent(self._messages_tree, event)
00164 
00165     def _rightclick_menu(self, event):
00166         """
00167         :type event: QEvent
00168         """
00169 
00170         # QTreeview.selectedIndexes() returns 0 when no node is selected.
00171         # This can happen when after booting no left-click has been made yet
00172         # (ie. looks like right-click doesn't count). These lines are the
00173         # workaround for that problem.
00174         selected = self._messages_tree.selectedIndexes()
00175         if len(selected) == 0:
00176             return
00177 
00178         menu = QMenu()
00179         text_action = QAction(self.tr('View Text'), menu)
00180         menu.addAction(text_action)
00181         raw_action = QAction(self.tr('View Raw'), menu)
00182         menu.addAction(raw_action)
00183         remove_action = QAction(self.tr('Remove message'), menu)
00184         menu.addAction(remove_action)
00185 
00186         action = menu.exec_(event.globalPos())
00187 
00188         if action == raw_action or action == text_action:
00189             rospy.logdebug('_rightclick_menu selected={}'.format(selected))
00190             selected_type = selected[1].data()
00191 
00192             if selected_type[-2:] == '[]':
00193                 selected_type = selected_type[:-2]
00194             browsetext = None
00195             try:
00196                 if (self._mode == rosmsg.MODE_MSG or
00197                     self._mode == rosaction.MODE_ACTION):
00198                     browsetext = rosmsg.get_msg_text(selected_type,
00199                                                      action == raw_action)
00200                 elif self._mode == rosmsg.MODE_SRV:
00201                     browsetext = rosmsg.get_srv_text(selected_type,
00202                                                      action == raw_action)
00203 
00204                 else:
00205                     raise
00206             except rosmsg.ROSMsgException as e:
00207                 QMessageBox.warning(self, self.tr('Warning'),
00208                                     self.tr('The selected item component ' +
00209                                             'does not have text to view.'))
00210             if browsetext is not None:
00211                 self._browsers.append(TextBrowseDialog(browsetext,
00212                                                        self._rospack))
00213                 self._browsers[-1].show()
00214 
00215         if action == remove_action:
00216             self._messages_tree.model().removeRow(selected[0].row())
00217 
00218     def cleanup_browsers_on_close(self):
00219         for browser in self._browsers:
00220             browser.close()


rqt_msg
Author(s): Aaron Blasdel
autogenerated on Tue May 2 2017 02:22:58