Package node_manager_fkie :: Module run_dialog
[frames] | no frames]

Source Code for Module node_manager_fkie.run_dialog

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  from python_qt_binding import QtGui 
 34  from python_qt_binding import QtCore 
 35   
 36  import os 
 37   
 38  import node_manager_fkie as nm 
 39  from packages_thread import PackagesThread 
 40   
 41   
42 -class PackageDialog(QtGui.QDialog):
43 - def __init__(self, parent=None):
44 QtGui.QDialog.__init__(self, parent) 45 self.setWindowTitle('Select Binary') 46 self.verticalLayout = QtGui.QVBoxLayout(self) 47 self.verticalLayout.setObjectName("verticalLayout") 48 49 self.content = QtGui.QWidget() 50 self.contentLayout = QtGui.QFormLayout(self.content) 51 self.contentLayout.setVerticalSpacing(0) 52 self.verticalLayout.addWidget(self.content) 53 54 self.packages = None 55 56 package_label = QtGui.QLabel("Package:", self.content) 57 self.package_field = QtGui.QComboBox(self.content) 58 self.package_field.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically) 59 self.package_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 60 self.package_field.setEditable(True) 61 self.contentLayout.addRow(package_label, self.package_field) 62 binary_label = QtGui.QLabel("Binary:", self.content) 63 self.binary_field = QtGui.QComboBox(self.content) 64 # self.binary_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) 65 self.binary_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 66 self.binary_field.setEditable(True) 67 self.contentLayout.addRow(binary_label, self.binary_field) 68 69 self.buttonBox = QtGui.QDialogButtonBox(self) 70 self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel) 71 self.buttonBox.setOrientation(QtCore.Qt.Horizontal) 72 self.buttonBox.setObjectName("buttonBox") 73 self.verticalLayout.addWidget(self.buttonBox) 74 75 self.package_field.setFocus(QtCore.Qt.TabFocusReason) 76 self.package = '' 77 self.binary = '' 78 79 if self.packages is None: 80 self.package_field.addItems(['packages searching...']) 81 self.package_field.setCurrentIndex(0) 82 self._fill_packages_thread = PackagesThread() 83 self._fill_packages_thread.packages.connect(self._fill_packages) 84 self._fill_packages_thread.start() 85 86 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.accept) 87 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject) 88 QtCore.QMetaObject.connectSlotsByName(self) 89 self.package_field.activated[str].connect(self.on_package_selected) 90 self.package_field.textChanged.connect(self.on_package_selected) 91 self.binary_field.textChanged.connect(self.on_binary_selected)
92
93 - def _fill_packages(self, packages):
94 # fill the input fields 95 self.packages = packages 96 packages = packages.keys() 97 packages.sort() 98 self.package_field.clear() 99 self.package_field.clearEditText() 100 self.package_field.addItems(packages)
101
102 - def _getBinaries(self, path):
103 result = {} 104 if os.path.isdir(path): 105 fileList = os.listdir(path) 106 for f in fileList: 107 if f and f[0] != '.' and not f in ['build'] and not f.endswith('.cfg') and not f.endswith('.so'): 108 ret = self._getBinaries(os.path.join(path, f)) 109 result = dict(ret.items() + result.items()) 110 elif os.path.isfile(path) and os.access(path, os.X_OK): 111 # create a selection for binaries 112 return {os.path.basename(path) : path} 113 return result
114
115 - def on_package_selected(self, package):
116 self.binary_field.clear() 117 if self.packages and self.packages.has_key(package): 118 self.binary_field.setEnabled(True) 119 path = self.packages[package] 120 binaries = self._getBinaries(path).keys() 121 try: 122 # find binaries in catkin workspace 123 from catkin.find_in_workspaces import find_in_workspaces as catkin_find 124 search_paths = catkin_find(search_dirs=['libexec', 'share'], project=package, first_matching_workspace_only=True) 125 for p in search_paths: 126 binaries += self._getBinaries(p).keys() 127 except: 128 pass 129 binaries = list(set(binaries)) 130 binaries.sort() 131 self.binary_field.addItems(binaries) 132 self.package = package 133 self.binary = self.binary_field.currentText()
134
135 - def on_binary_selected(self, binary):
136 self.binary = binary
137
138 -class RunDialog(PackageDialog):
139 ''' 140 A dialog to run a ROS node without configuration 141 ''' 142
143 - def __init__(self, host, masteruri=None, parent=None):
144 PackageDialog.__init__(self, parent) 145 self.host = host 146 self.setWindowTitle('Run') 147 148 ns_name_label = QtGui.QLabel("NS/Name:", self.content) 149 self.ns_field = QtGui.QComboBox(self.content) 150 self.ns_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 151 self.ns_field.setEditable(True) 152 ns_history = nm.history().cachedParamValues('run_dialog/NS') 153 ns_history.insert(0, '/') 154 self.ns_field.addItems(ns_history) 155 self.name_field = QtGui.QLineEdit(self.content) 156 self.name_field.setEnabled(False) 157 horizontalLayout = QtGui.QHBoxLayout() 158 horizontalLayout.addWidget(self.ns_field) 159 horizontalLayout.addWidget(self.name_field) 160 self.contentLayout.addRow(ns_name_label, horizontalLayout) 161 args_label = QtGui.QLabel("Args:", self.content) 162 self.args_field = QtGui.QComboBox(self.content) 163 self.args_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength) 164 self.args_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 165 self.args_field.setEditable(True) 166 self.contentLayout.addRow(args_label, self.args_field) 167 args_history = nm.history().cachedParamValues('run_dialog/Args') 168 args_history.insert(0, '') 169 self.args_field.addItems(args_history) 170 171 host_label = QtGui.QLabel("Host:", self.content) 172 self.host_field = QtGui.QComboBox(self.content) 173 # self.host_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents) 174 self.host_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 175 self.host_field.setEditable(True) 176 host_label.setBuddy(self.host_field) 177 self.contentLayout.addRow(host_label, self.host_field) 178 self.host_history = host_history = nm.history().cachedParamValues('/Host') 179 if self.host in host_history: 180 host_history.remove(self.host) 181 host_history.insert(0, self.host) 182 self.host_field.addItems(host_history) 183 184 master_label = QtGui.QLabel("ROS Master URI:", self.content) 185 self.master_field = QtGui.QComboBox(self.content) 186 self.master_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)) 187 self.master_field.setEditable(True) 188 master_label.setBuddy(self.host_field) 189 self.contentLayout.addRow(master_label, self.master_field) 190 self.master_history = master_history = nm.history().cachedParamValues('/Optional Parameter/ROS Master URI') 191 self.masteruri = "ROS_MASTER_URI" if masteruri is None else masteruri 192 if self.masteruri in master_history: 193 master_history.remove(self.masteruri) 194 master_history.insert(0, self.masteruri) 195 self.master_field.addItems(master_history) 196 197 # self.package_field.setFocus(QtCore.Qt.TabFocusReason) 198 self.package_field.textChanged.connect(self.on_package_selected) 199 self.binary_field.activated[str].connect(self.on_binary_selected)
200
201 - def run_params(self):
202 ''' 203 Runs the selected node, or do nothing. 204 :return: a tuple with host, package, binary, name, args, maseruri or empty tuple on errors 205 ''' 206 self.binary = self.binary_field.currentText() 207 self.host = self.host_field.currentText() if self.host_field.currentText() else self.host 208 self.masteruri = self.master_field.currentText() if self.master_field.currentText() else self.masteruri 209 if not self.host in self.host_history and self.host != 'localhost' and self.host != '127.0.0.1': 210 nm.history().add2HostHistory(self.host) 211 ns = self.ns_field.currentText() 212 if ns and ns != '/': 213 nm.history().addParamCache('run_dialog/NS', ns) 214 args = self.args_field.currentText() 215 if args: 216 nm.history().addParamCache('run_dialog/Args', args) 217 if self.package and self.binary: 218 nm.history().addParamCache('/Host', self.host) 219 return (self.host, self.package, self.binary, self.name_field.text(), ('__ns:=%s %s'%(ns, args)).split(' '), None if self.masteruri == 'ROS_MASTER_URI' else self.masteruri) 220 return ()
221
222 - def on_package_selected(self, package):
223 PackageDialog.on_package_selected(self, package) 224 if self.packages and self.packages.has_key(package): 225 self.args_field.setEnabled(True) 226 self.ns_field.setEnabled(True) 227 self.name_field.setEnabled(True) 228 root, ext = os.path.splitext(os.path.basename(self.binary_field.currentText())) 229 self.name_field.setText(root)
230
231 - def on_binary_selected(self, binary):
232 root, ext = os.path.splitext(os.path.basename(binary)) 233 self.name_field.setText(root)
234