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 PySide import QtGui
34 from PySide import QtCore
35
36 import os
37 import threading
38
39 import node_manager_fkie as nm
40 from detailed_msg_box import WarningMessageBox
44 '''
45 A dialog to set the sync options.
46 '''
47
49 QtGui.QDialog.__init__(self, parent)
50
51 self.setWindowTitle('Sync')
52 self.verticalLayout = QtGui.QVBoxLayout(self)
53 self.verticalLayout.setObjectName("verticalLayout")
54 self.resize(350,160)
55
56 self.toolButton_SyncAll = QtGui.QToolButton(self)
57 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
58 sizePolicy.setHorizontalStretch(0)
59 sizePolicy.setVerticalStretch(2)
60 sizePolicy.setHeightForWidth(self.toolButton_SyncAll.sizePolicy().hasHeightForWidth())
61 self.toolButton_SyncAll.setSizePolicy(sizePolicy)
62 self.toolButton_SyncAll.setObjectName("toolButton_SyncAll")
63 self.verticalLayout.addWidget(self.toolButton_SyncAll)
64 self.toolButton_SyncAll.setText(QtGui.QApplication.translate("Form", "Sync All", None, QtGui.QApplication.UnicodeUTF8))
65 self.toolButton_SyncAll.clicked.connect(self._on_sync_all_clicked)
66
67 self.toolButton_SyncTopicOnDemand = QtGui.QToolButton(self)
68 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
69 sizePolicy.setHorizontalStretch(0)
70 sizePolicy.setVerticalStretch(1)
71 sizePolicy.setHeightForWidth(self.toolButton_SyncTopicOnDemand.sizePolicy().hasHeightForWidth())
72 self.toolButton_SyncTopicOnDemand.setSizePolicy(sizePolicy)
73 self.toolButton_SyncTopicOnDemand.setObjectName("toolButton_SyncTopicOnDemand")
74 self.verticalLayout.addWidget(self.toolButton_SyncTopicOnDemand)
75 self.toolButton_SyncTopicOnDemand.setText(QtGui.QApplication.translate("Form", "Sync only topics on demand", None, QtGui.QApplication.UnicodeUTF8))
76 self.toolButton_SyncTopicOnDemand.clicked.connect(self._on_sync_topics_on_demand_clicked)
77
78 self.toolButton_SelectInterface = QtGui.QToolButton(self)
79 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
80 sizePolicy.setHorizontalStretch(0)
81 sizePolicy.setVerticalStretch(1)
82 sizePolicy.setHeightForWidth(self.toolButton_SelectInterface.sizePolicy().hasHeightForWidth())
83 self.toolButton_SelectInterface.setSizePolicy(sizePolicy)
84 self.toolButton_SelectInterface.setObjectName("toolButton_SelectInterface")
85 self.verticalLayout.addWidget(self.toolButton_SelectInterface)
86 self.toolButton_SelectInterface.setText(QtGui.QApplication.translate("Form", "Select an interface", None, QtGui.QApplication.UnicodeUTF8))
87 self.toolButton_SelectInterface.clicked.connect(self._on_select_interface_clicked)
88
89 self.interface_field = QtGui.QComboBox(self)
90 self.interface_field.setInsertPolicy(QtGui.QComboBox.InsertAlphabetically)
91 self.interface_field.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed))
92 self.interface_field.setEditable(True)
93 self.interface_field.setVisible(False)
94 self.interface_field.setObjectName("interface_field")
95 self.verticalLayout.addWidget(self.interface_field)
96 self.interface_field.currentIndexChanged[str].connect(self._on_interface_selected)
97
98 self.toolButton_EditInterface = QtGui.QToolButton(self)
99 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
100 sizePolicy.setHorizontalStretch(0)
101 sizePolicy.setVerticalStretch(1)
102 sizePolicy.setHeightForWidth(self.toolButton_EditInterface.sizePolicy().hasHeightForWidth())
103 self.toolButton_EditInterface.setSizePolicy(sizePolicy)
104 self.toolButton_EditInterface.setObjectName("toolButton_EditInterface")
105 self.verticalLayout.addWidget(self.toolButton_EditInterface)
106 self.toolButton_EditInterface.setText(QtGui.QApplication.translate("Form", "Edit selected interface", None, QtGui.QApplication.UnicodeUTF8))
107 self.toolButton_EditInterface.clicked.connect(self._on_edit_interface_clicked)
108 self.toolButton_EditInterface.setVisible(False)
109
110 self.toolButton_CreateInterface = QtGui.QToolButton(self)
111 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
112 sizePolicy.setHorizontalStretch(0)
113 sizePolicy.setVerticalStretch(1)
114 sizePolicy.setHeightForWidth(self.toolButton_CreateInterface.sizePolicy().hasHeightForWidth())
115 self.toolButton_CreateInterface.setSizePolicy(sizePolicy)
116 self.toolButton_CreateInterface.setObjectName("toolButton_CreateInterface")
117 self.verticalLayout.addWidget(self.toolButton_CreateInterface)
118 self.toolButton_CreateInterface.setText(QtGui.QApplication.translate("Form", "Create an interface", None, QtGui.QApplication.UnicodeUTF8))
119 self.toolButton_CreateInterface.clicked.connect(self._on_create_interface_clicked)
120 self.toolButton_CreateInterface.setVisible(False)
121
122 self.textedit = QtGui.QTextEdit(self)
123 sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
124 self.textedit.setSizePolicy(sizePolicy)
125 self.textedit.setObjectName("textedit")
126 self.verticalLayout.addWidget(self.textedit)
127 self.textedit.setVisible(False)
128
129
130 self._fill_interface_thread = None
131 self._interfaces_files = None
132 self._sync_args = []
133
134 self.buttonBox = QtGui.QDialogButtonBox(self)
135 self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel)
136 self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
137 self.buttonBox.setObjectName("buttonBox")
138 self.verticalLayout.addWidget(self.buttonBox)
139 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.accept)
140 QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
141
142 self._new_iface = True
143
144 @property
146 return self._sync_args
147
149 self.setResult(QtGui.QDialog.Accepted)
150 self._sync_args = []
151 self._sync_args.append(''.join(['_interface_url:=', "'.'"]))
152 self._sync_args.append(''.join(['_sync_topics_on_demand:=', 'False']))
153 self._sync_args.append(''.join(['_ignore_hosts:=', '[]']))
154 self._sync_args.append(''.join(['_sync_hosts:=', '[]']))
155 self._sync_args.append(''.join(['_ignore_nodes:=', '[]']))
156 self._sync_args.append(''.join(['_sync_nodes:=', '[]']))
157 self._sync_args.append(''.join(['_ignore_topics:=', '[]']))
158 self._sync_args.append(''.join(['_sync_topics:=', '[]']))
159 self._sync_args.append(''.join(['_ignore_services:=', '[]']))
160 self._sync_args.append(''.join(['_sync_services:=', '[]']))
161 self.accept()
162
164 self._sync_args = []
165 self._sync_args.append(''.join(['_interface_url:=', "'.'"]))
166 self._sync_args.append(''.join(['_sync_topics_on_demand:=', 'True']))
167 self._sync_args.append(''.join(['_ignore_hosts:=', '[]']))
168 self._sync_args.append(''.join(['_sync_hosts:=', '[]']))
169 self._sync_args.append(''.join(['_ignore_nodes:=', '[]']))
170 self._sync_args.append(''.join(['_sync_nodes:=', '[]']))
171 self._sync_args.append(''.join(['_ignore_topics:=', '[]']))
172 self._sync_args.append(''.join(['_sync_topics:=', '[/only_on_demand]']))
173 self._sync_args.append(''.join(['_ignore_services:=', '[/*]']))
174 self._sync_args.append(''.join(['_sync_services:=', '[]']))
175 self.accept()
176
178 self.toolButton_SyncAll.setVisible(False)
179 self.toolButton_SyncTopicOnDemand.setVisible(False)
180 self.toolButton_SelectInterface.setVisible(False)
181 self.interface_field.setVisible(True)
182 self.toolButton_CreateInterface.setVisible(True)
183 self.toolButton_EditInterface.setVisible(True)
184 self.toolButton_EditInterface.setEnabled(False)
185 self.textedit.setVisible(False)
186
187 if self._interfaces_files is None:
188 self.interface_field.addItems(['interface searching...'])
189 self.interface_field.setCurrentIndex(0)
190 self._fill_interface_thread = threading.Thread(target=self._fill_interfaces)
191 self._fill_interface_thread.start()
192 else:
193 self.toolButton_EditInterface.setEnabled(self._interfaces_files.has_key(self.interface_field.currentText()))
194 self.buttonBox.clear()
195 self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
196 self.interface_field.setFocus(QtCore.Qt.TabFocusReason)
197 self.resize(350,80)
198
200 if self._interfaces_files is None:
201 self.root_paths = [os.path.normpath(p) for p in os.getenv("ROS_PACKAGE_PATH").split(':')]
202 self._interfaces_files = {}
203 for p in self.root_paths:
204 ret = self._getInterfaces(p)
205 self._interfaces_files = dict(ret.items() + self._interfaces_files.items())
206 self.interface_field.clear()
207 self.interface_field.clearEditText()
208 self.interface_field.addItems(self._interfaces_files.keys())
209
211 if self._interfaces_files.has_key(interface):
212 self._sync_args = []
213 self._sync_args.append(''.join(['_interface_url:=', interface]))
214 self.toolButton_EditInterface.setEnabled(True)
215
217 if self.textedit.isVisible():
218 try:
219 tmp_file = os.path.join(nm.screen().LOG_PATH, 'tmp_sync_interface.sync')
220 with open(tmp_file, 'w+') as f:
221 iface = f.write(self.textedit.toPlainText())
222 from master_sync_fkie.common import read_interface
223 read_interface(tmp_file)
224 if not self._new_iface and self._interfaces_files.has_key(self.interface_field.currentText()):
225 fileName = self._interfaces_files[self.interface_field.currentText()]
226 else:
227 fileName, selectedFilter = QtGui.QFileDialog.getSaveFileName(self, 'Save sync interface', '/home', "Sync Files (*.sync)")
228 if fileName:
229 with open(fileName, 'w+') as f:
230 iface = f.write(self.textedit.toPlainText())
231 if self._new_iface:
232 self.interface_field.clear()
233 self._interfaces_files = None
234 self._on_select_interface_clicked()
235
236
237 except Exception as e:
238 WarningMessageBox(QtGui.QMessageBox.Warning, "Create sync interface",
239 "Error while create interface",
240 str(e)).exec_()
241 elif self.interface_field.isVisible():
242 interface = self.interface_field.currentText()
243 if self._interfaces_files and self._interfaces_files.has_key(interface):
244 self._sync_args = []
245 self._sync_args.append(''.join(['_interface_url:=', interface]))
246 QtGui.QDialog.accept(self)
247 self.resetView()
248 else:
249 QtGui.QDialog.accept(self)
250 self.resetView()
251
252
254 if self.textedit.isVisible():
255 self._on_select_interface_clicked()
256 else:
257 QtGui.QDialog.reject(self)
258 self.resetView()
259
261 self._new_iface = True
262 self.interface_field.setVisible(False)
263 self.toolButton_CreateInterface.setVisible(False)
264 self.toolButton_EditInterface.setVisible(False)
265 self.textedit.setVisible(True)
266 self.textedit.setText("# The ignore_* lists will be processed first.\n"
267 "ignore_hosts:\n"
268 "sync_hosts:\n\n"
269 "ignore_nodes:\n"
270 "sync_nodes:\n\n"
271 "ignore_topics:\n"
272 "sync_topics:\n\n"
273 "ignore_services:\n"
274 " - /*get_loggers\n"
275 " - /*set_logger_level\n"
276 "sync_services:\n\n"
277 "# The sync_topics_on_demand is only regarded, if sync_nodes or sync_topics are set.\n"
278 "# In this case the subscribed and published topics are synchronized even if they are\n"
279 "# not in the sync_* list.\n"
280 "sync_topics_on_demand: False\n"
281 )
282 self.resize(350,300)
283
285 self._new_iface = False
286 self.interface_field.setVisible(False)
287 self.toolButton_CreateInterface.setVisible(False)
288 self.toolButton_EditInterface.setVisible(False)
289 self.textedit.setVisible(True)
290 if self._interfaces_files.has_key(self.interface_field.currentText()):
291 try:
292 with open(self._interfaces_files[self.interface_field.currentText()], 'rw') as f:
293 iface = f.read()
294 self.textedit.setText(iface)
295 except Exception as e:
296 WarningMessageBox(QtGui.QMessageBox.Warning, "Edit sync interface",
297 "Error while open interface",
298 str(e)).exec_()
299 self.resize(350,300)
300
302 self.toolButton_SyncAll.setVisible(True)
303 self.toolButton_SyncTopicOnDemand.setVisible(True)
304 self.toolButton_SelectInterface.setVisible(True)
305 self.interface_field.setVisible(False)
306 self.toolButton_CreateInterface.setVisible(False)
307 self.toolButton_EditInterface.setVisible(False)
308 self.textedit.setVisible(False)
309 self.buttonBox.clear()
310 self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel)
311 self.resize(350,160)
312
314 result = {}
315 if os.path.isdir(path):
316 fileList = os.listdir(path)
317
318 if not package:
319
320 if 'manifest.xml' in fileList:
321 package = os.path.basename(path)
322 for f in fileList:
323 ret = self._getInterfaces(os.path.sep.join([path, f]), package)
324 result = dict(ret.items() + result.items())
325 elif package and os.path.isfile(path) and path.endswith('.sync'):
326
327 return {''.join(['pkg://', package, '///', os.path.basename(path)]) : path}
328 return result
329