1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
43 '''
44 A dialog to run a ROS node without configuration
45 '''
46
47 - def __init__(self, host, masteruri=None, parent=None):
48 QtGui.QDialog.__init__(self, parent)
49 self.host = host
50 self.setWindowTitle('Run')
51 self.verticalLayout = QtGui.QVBoxLayout(self)
52 self.verticalLayout.setObjectName("verticalLayout")
53
54 self.content = QtGui.QWidget()
55 self.contentLayout = QtGui.QFormLayout(self.content)
56 self.contentLayout.setVerticalSpacing(0)
57 self.verticalLayout.addWidget(self.content)
58
59 self.packages = None
60
61 package_label = QtGui.QLabel("Package:", self.content)
62 self.package_field = QtGui.QComboBox(self.content)
63 self.package_field.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
64 self.package_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
65 self.package_field.setEditable(True)
66 self.contentLayout.addRow(package_label, self.package_field)
67 binary_label = QtGui.QLabel("Binary:", self.content)
68 self.binary_field = QtGui.QComboBox(self.content)
69
70 self.binary_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
71 self.binary_field.setEditable(True)
72 self.contentLayout.addRow(binary_label, self.binary_field)
73 ns_name_label = QtGui.QLabel("NS/Name:", self.content)
74 self.ns_field = QtGui.QComboBox(self.content)
75 self.ns_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
76 self.ns_field.setEditable(True)
77 ns_history = nm.history().cachedParamValues('run_dialog/NS')
78 ns_history.insert(0, '/')
79 self.ns_field.addItems(ns_history)
80 self.name_field = QtGui.QLineEdit(self.content)
81 self.name_field.setEnabled(False)
82 horizontalLayout = QtGui.QHBoxLayout()
83 horizontalLayout.addWidget(self.ns_field)
84 horizontalLayout.addWidget(self.name_field)
85 self.contentLayout.addRow(ns_name_label, horizontalLayout)
86 args_label = QtGui.QLabel("Args:", self.content)
87 self.args_field = QtGui.QComboBox(self.content)
88 self.args_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
89 self.args_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
90 self.args_field.setEditable(True)
91 self.contentLayout.addRow(args_label, self.args_field)
92 args_history = nm.history().cachedParamValues('run_dialog/Args')
93 args_history.insert(0, '')
94 self.args_field.addItems(args_history)
95
96 host_label = QtGui.QLabel("Host:", self.content)
97 self.host_field = QtGui.QComboBox(self.content)
98
99 self.host_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
100 self.host_field.setEditable(True)
101 host_label.setBuddy(self.host_field)
102 self.contentLayout.addRow(host_label, self.host_field)
103 self.host_history = host_history = nm.history().cachedParamValues('/Host')
104 if self.host in host_history:
105 host_history.remove(self.host)
106 host_history.insert(0, self.host)
107 self.host_field.addItems(host_history)
108
109 master_label = QtGui.QLabel("ROS Master URI:", self.content)
110 self.master_field = QtGui.QComboBox(self.content)
111 self.master_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
112 self.master_field.setEditable(True)
113 master_label.setBuddy(self.host_field)
114 self.contentLayout.addRow(master_label, self.master_field)
115 self.master_history = master_history = nm.history().cachedParamValues('/Optional Parameter/ROS Master URI')
116 self.masteruri = "ROS_MASTER_URI" if masteruri is None else masteruri
117 if self.masteruri in master_history:
118 master_history.remove(self.masteruri)
119 master_history.insert(0, self.masteruri)
120 self.master_field.addItems(master_history)
121
122 self.buttonBox = QtGui.QDialogButtonBox(self)
123 self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
124 self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
125 self.buttonBox.setObjectName("buttonBox")
126 self.verticalLayout.addWidget(self.buttonBox)
127
128 self.package_field.setFocus(QtCore.Qt.TabFocusReason)
129 self.package = ''
130 self.binary = ''
131
132 if self.packages is None:
133 self.package_field.addItems(['packages searching...'])
134 self.package_field.setCurrentIndex(0)
135 self._fill_packages_thread = PackagesThread()
136 self._fill_packages_thread.packages.connect(self._fill_packages)
137 self._fill_packages_thread.start()
138
139 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.accept)
140 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
141 QtCore.QMetaObject.connectSlotsByName(self)
142 self.package_field.activated[str].connect(self.on_package_selected)
143 self.package_field.textChanged.connect(self.on_package_selected)
144 self.binary_field.activated[str].connect(self.on_binary_selected)
145
154
156 '''
157 Runs the selected node, or do nothing.
158 :return: a tuple with host, package, binary, name, args, maseruri or empty tuple on errors
159 '''
160 self.binary = self.binary_field.currentText()
161 self.host = self.host_field.currentText() if self.host_field.currentText() else self.host
162 self.masteruri = self.master_field.currentText() if self.master_field.currentText() else self.masteruri
163 if not self.host in self.host_history and self.host != 'localhost' and self.host != '127.0.0.1':
164 nm.history().add2HostHistory(self.host)
165 ns = self.ns_field.currentText()
166 if ns and ns != '/':
167 nm.history().addParamCache('run_dialog/NS', ns)
168 args = self.args_field.currentText()
169 if args:
170 nm.history().addParamCache('run_dialog/Args', args)
171 if self.package and self.binary:
172 nm.history().addParamCache('/Host', self.host)
173 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)
174 return ()
175
177 result = {}
178 if os.path.isdir(path):
179 fileList = os.listdir(path)
180 for f in fileList:
181 if f and f[0] != '.' and not f in ['build'] and not f.endswith('.cfg') and not f.endswith('.so'):
182 ret = self._getBinaries(os.path.join(path, f))
183 result = dict(ret.items() + result.items())
184 elif os.path.isfile(path) and os.access(path, os.X_OK):
185
186 return {os.path.basename(path) : path}
187 return result
188
190 self.binary_field.clear()
191 if self.packages and self.packages.has_key(package):
192 self.binary_field.setEnabled(True)
193 self.args_field.setEnabled(True)
194 self.ns_field.setEnabled(True)
195 self.name_field.setEnabled(True)
196 path = self.packages[package]
197 binaries = self._getBinaries(path).keys()
198 try:
199
200 from catkin.find_in_workspaces import find_in_workspaces as catkin_find
201 search_paths = catkin_find(search_dirs=['libexec', 'share'], project=package, first_matching_workspace_only=True)
202 for p in search_paths:
203 binaries += self._getBinaries(p).keys()
204 except:
205 pass
206 binaries.sort()
207 self.binary_field.addItems(binaries)
208 self.package = package
209 root, ext = os.path.splitext(os.path.basename(self.binary_field.currentText()))
210 self.name_field.setText(root)
211
213 root, ext = os.path.splitext(os.path.basename(binary))
214 self.name_field.setText(root)
215