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.QtCore import Qt, QMetaObject 
 34  try: 
 35      from python_qt_binding.QtGui import QComboBox, QDialog, QDialogButtonBox, QLabel, QLineEdit, QWidget 
 36      from python_qt_binding.QtGui import QFormLayout, QHBoxLayout, QVBoxLayout, QSizePolicy 
 37  except: 
 38      from python_qt_binding.QtWidgets import QComboBox, QDialog, QDialogButtonBox, QLabel, QLineEdit, QWidget 
 39      from python_qt_binding.QtWidgets import QFormLayout, QHBoxLayout, QVBoxLayout, QSizePolicy 
 40  import os 
 41   
 42  from packages_thread import PackagesThread 
 43  import node_manager_fkie as nm 
 44   
 45   
46 -class PackageDialog(QDialog):
47
48 - def __init__(self, parent=None):
49 QDialog.__init__(self, parent) 50 self.setWindowTitle('Select Binary') 51 self.verticalLayout = QVBoxLayout(self) 52 self.verticalLayout.setObjectName("verticalLayout") 53 54 self.content = QWidget() 55 self.contentLayout = QFormLayout(self.content) 56 self.contentLayout.setVerticalSpacing(0) 57 self.verticalLayout.addWidget(self.content) 58 59 self.packages = None 60 61 package_label = QLabel("Package:", self.content) 62 self.package_field = QComboBox(self.content) 63 self.package_field.setInsertPolicy(QComboBox.InsertAlphabetically) 64 self.package_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 65 self.package_field.setEditable(True) 66 self.contentLayout.addRow(package_label, self.package_field) 67 binary_label = QLabel("Binary:", self.content) 68 self.binary_field = QComboBox(self.content) 69 # self.binary_field.setSizeAdjustPolicy(QComboBox.AdjustToContents) 70 self.binary_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 71 self.binary_field.setEditable(True) 72 self.contentLayout.addRow(binary_label, self.binary_field) 73 74 self.buttonBox = QDialogButtonBox(self) 75 self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) 76 self.buttonBox.setOrientation(Qt.Horizontal) 77 self.buttonBox.setObjectName("buttonBox") 78 self.verticalLayout.addWidget(self.buttonBox) 79 80 self.package_field.setFocus(Qt.TabFocusReason) 81 self.package = '' 82 self.binary = '' 83 84 if self.packages is None: 85 self.package_field.addItems(['packages searching...']) 86 self.package_field.setCurrentIndex(0) 87 self._fill_packages_thread = PackagesThread() 88 self._fill_packages_thread.packages.connect(self._fill_packages) 89 self._fill_packages_thread.start() 90 91 self.buttonBox.accepted.connect(self.accept) 92 self.buttonBox.rejected.connect(self.reject) 93 QMetaObject.connectSlotsByName(self) 94 self.package_field.activated[str].connect(self.on_package_selected) 95 if hasattr(self.package_field, "textChanged"): # qt compatibility 96 self.package_field.textChanged.connect(self.on_package_selected) 97 self.binary_field.textChanged.connect(self.on_binary_selected) 98 else: 99 self.package_field.editTextChanged.connect(self.on_package_selected) 100 self.binary_field.editTextChanged.connect(self.on_binary_selected)
101
102 - def _fill_packages(self, packages):
103 # fill the input fields 104 self.packages = packages 105 packages = packages.keys() 106 packages.sort() 107 self.package_field.clear() 108 self.package_field.clearEditText() 109 self.package_field.addItems(packages)
110
111 - def _getBinaries(self, path):
112 result = {} 113 if os.path.isdir(path): 114 fileList = os.listdir(path) 115 for f in fileList: 116 if f and f[0] != '.' and f not in ['build'] and not f.endswith('.cfg') and not f.endswith('.so'): 117 ret = self._getBinaries(os.path.join(path, f)) 118 result = dict(ret.items() + result.items()) 119 elif os.path.isfile(path) and os.access(path, os.X_OK): 120 # create a selection for binaries 121 return {os.path.basename(path): path} 122 return result
123
124 - def on_package_selected(self, package):
125 self.binary_field.clear() 126 if self.packages and package in self.packages: 127 self.binary_field.setEnabled(True) 128 path = self.packages[package] 129 binaries = self._getBinaries(path).keys() 130 try: 131 # find binaries in catkin workspace 132 from catkin.find_in_workspaces import find_in_workspaces as catkin_find 133 search_paths = catkin_find(search_dirs=['libexec', 'share'], project=package, first_matching_workspace_only=True) 134 for p in search_paths: 135 binaries += self._getBinaries(p).keys() 136 except: 137 pass 138 binaries = list(set(binaries)) 139 binaries.sort() 140 self.binary_field.addItems(binaries) 141 self.package = package 142 self.binary = self.binary_field.currentText()
143
144 - def on_binary_selected(self, binary):
145 self.binary = binary
146 147
148 -class RunDialog(PackageDialog):
149 ''' 150 A dialog to run a ROS node without configuration 151 ''' 152
153 - def __init__(self, host, masteruri=None, parent=None):
154 PackageDialog.__init__(self, parent) 155 self.host = host 156 self.setWindowTitle('Run') 157 158 ns_name_label = QLabel("NS/Name:", self.content) 159 self.ns_field = QComboBox(self.content) 160 self.ns_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 161 self.ns_field.setEditable(True) 162 ns_history = nm.history().cachedParamValues('run_dialog/NS') 163 ns_history.insert(0, '/') 164 self.ns_field.addItems(ns_history) 165 self.name_field = QLineEdit(self.content) 166 self.name_field.setEnabled(False) 167 horizontalLayout = QHBoxLayout() 168 horizontalLayout.addWidget(self.ns_field) 169 horizontalLayout.addWidget(self.name_field) 170 self.contentLayout.addRow(ns_name_label, horizontalLayout) 171 args_label = QLabel("Args:", self.content) 172 self.args_field = QComboBox(self.content) 173 self.args_field.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) 174 self.args_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 175 self.args_field.setEditable(True) 176 self.contentLayout.addRow(args_label, self.args_field) 177 args_history = nm.history().cachedParamValues('run_dialog/Args') 178 args_history.insert(0, '') 179 self.args_field.addItems(args_history) 180 181 host_label = QLabel("Host:", self.content) 182 self.host_field = QComboBox(self.content) 183 # self.host_field.setSizeAdjustPolicy(QComboBox.AdjustToContents) 184 self.host_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 185 self.host_field.setEditable(True) 186 host_label.setBuddy(self.host_field) 187 self.contentLayout.addRow(host_label, self.host_field) 188 self.host_history = host_history = nm.history().cachedParamValues('/Host') 189 if self.host in host_history: 190 host_history.remove(self.host) 191 host_history.insert(0, self.host) 192 self.host_field.addItems(host_history) 193 194 master_label = QLabel("ROS Master URI:", self.content) 195 self.master_field = QComboBox(self.content) 196 self.master_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)) 197 self.master_field.setEditable(True) 198 master_label.setBuddy(self.host_field) 199 self.contentLayout.addRow(master_label, self.master_field) 200 self.master_history = master_history = nm.history().cachedParamValues('/Optional Parameter/ROS Master URI') 201 self.masteruri = "ROS_MASTER_URI" if masteruri is None else masteruri 202 if self.masteruri in master_history: 203 master_history.remove(self.masteruri) 204 master_history.insert(0, self.masteruri) 205 self.master_field.addItems(master_history) 206 207 # self.package_field.setFocus(QtCore.Qt.TabFocusReason) 208 if hasattr(self.package_field, "textChanged"): # qt compatibility 209 self.package_field.textChanged.connect(self.on_package_selected) 210 else: 211 self.package_field.editTextChanged.connect(self.on_package_selected) 212 self.binary_field.activated[str].connect(self.on_binary_selected)
213
214 - def run_params(self):
215 ''' 216 Runs the selected node, or do nothing. 217 :return: a tuple with host, package, binary, name, args, maseruri or empty tuple on errors 218 ''' 219 self.binary = self.binary_field.currentText() 220 self.host = self.host_field.currentText() if self.host_field.currentText() else self.host 221 self.masteruri = self.master_field.currentText() if self.master_field.currentText() else self.masteruri 222 if self.host not in self.host_history and self.host != 'localhost' and self.host != '127.0.0.1': 223 nm.history().add2HostHistory(self.host) 224 ns = self.ns_field.currentText() 225 if ns and ns != '/': 226 nm.history().addParamCache('run_dialog/NS', ns) 227 args = self.args_field.currentText() 228 if args: 229 nm.history().addParamCache('run_dialog/Args', args) 230 if self.package and self.binary: 231 nm.history().addParamCache('/Host', self.host) 232 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) 233 return ()
234
235 - def on_package_selected(self, package):
236 PackageDialog.on_package_selected(self, package) 237 if self.packages and package in self.packages: 238 self.args_field.setEnabled(True) 239 self.ns_field.setEnabled(True) 240 self.name_field.setEnabled(True) 241 root, _ext = os.path.splitext(os.path.basename(self.binary_field.currentText())) 242 self.name_field.setText(root)
243
244 - def on_binary_selected(self, binary):
245 root, _ext = os.path.splitext(os.path.basename(binary)) 246 self.name_field.setText(root)
247