00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 import os
00011 import sys
00012
00013 from python_qt_binding import loadUi
00014 from python_qt_binding.QtCore import Qt, QSize
00015 from python_qt_binding.QtGui import QIcon, QWidget, QLabel
00016 from python_qt_binding.QtGui import QSizePolicy, QTextEdit, QPushButton, QDialog
00017 from python_qt_binding.QtGui import QMainWindow, QCheckBox
00018
00019 from python_qt_binding.QtGui import QGridLayout, QVBoxLayout, QHBoxLayout, QMessageBox
00020
00021
00022 import rospkg
00023 from rocon_console import console
00024 import rocon_python_utils
00025
00026 from .rocon_masters import RoconMasters
00027 from . import utils
00028
00029
00030
00031
00032
00033
00034 class QMasterChooser(QMainWindow):
00035
00036 rocon_remocon_script = utils.find_rocon_remocon_script('rocon_remocon')
00037 rocon_remocon_sub_script = utils.find_rocon_remocon_script('rocon_remocon_sub')
00038
00039 def __init__(self, parent, title, application):
00040 self._context = parent
00041 self.application = application
00042 super(QMasterChooser, self).__init__()
00043 utils.setup_home_dirs()
00044
00045 self._init_widget()
00046 self._init_interface()
00047
00048
00049 self._widget_main.show()
00050 self._widget_main.activateWindow()
00051 self._widget_main.raise_()
00052 self._update_rocon_master_list()
00053
00054 def __del__(self):
00055 console.loginfo("RemoconMain: Destroy")
00056
00057 def _init_host_configuration(self):
00058 self.host_name = "localhost"
00059 self.master_uri = "http://%s:11311" % (self.host_name)
00060
00061 self.env_host_name = os.getenv("ROS_HOSTNAME")
00062 self.env_master_uri = os.getenv("ROS_MASTER_URI")
00063 if self.env_host_name:
00064 self.host_name = self.env_host_name
00065 if self.env_master_uri == None:
00066 self.env_master_uri = "http://%s:11311" % (self.host_name)
00067 elif self.env_master_uri:
00068 self.master_uri = self.env_master_uri
00069
00070 def _init_icon_paths(self):
00071 self.icon_paths = {}
00072 try:
00073 self.icon_paths['unknown'] = rocon_python_utils.ros.find_resource_from_string('rocon_icons/unknown', extension='png')
00074 except (rospkg.ResourceNotFound, ValueError):
00075 console.logerror("Remocon : couldn't find icons on the ros package path (install rocon_icons and rocon_bubble_icons")
00076 sys.exit(1)
00077
00078 def _init_widget(self):
00079 self._init_icon_paths()
00080
00081 self.setObjectName('Remocon')
00082 self._widget_main = QWidget()
00083
00084 rospack = rospkg.RosPack()
00085 path = os.path.join(rospack.get_path('rocon_remocon'), 'ui', 'remocon.ui')
00086 loadUi(path, self._widget_main)
00087
00088
00089 self._widget_main.list_widget.setIconSize(QSize(50, 50))
00090 self._widget_main.list_widget.itemDoubleClicked.connect(self._connect_rocon_master)
00091 self._widget_main.list_widget.itemClicked.connect(self._select_rocon_master)
00092
00093 self._widget_main.add_concert_btn.pressed.connect(self._set_add_rocon_master)
00094 self._widget_main.delete_btn.pressed.connect(self._delete_rocon_master)
00095 self._widget_main.delete_all_btn.pressed.connect(self._delete_all_rocon_masters)
00096 self._widget_main.refresh_btn.pressed.connect(self._refresh_all_rocon_master_list)
00097
00098 self._widget_main.list_info_widget.clear()
00099
00100 def _init_interface(self):
00101 self._init_host_configuration()
00102
00103 self.rocon_masters = RoconMasters()
00104 self._connect_dlg = None
00105 self.cur_selected_rocon_master = None
00106 self._is_init = True
00107
00108 def _delete_all_rocon_masters(self):
00109 self.rocon_masters.clear()
00110 self._update_rocon_master_list()
00111 self._widget_main.list_info_widget.clear()
00112
00113 def _delete_rocon_master(self):
00114 if self.cur_selected_rocon_master in self.rocon_masters.keys():
00115 self.rocon_masters.delete(self.cur_selected_rocon_master)
00116 self._update_rocon_master_list()
00117 self._widget_main.list_info_widget.clear()
00118
00119 def _add_rocon_master(self, uri_text_widget, host_name_text_widget):
00120 rocon_master = self.rocon_masters.add(uri_text_widget.toPlainText(), host_name_text_widget.toPlainText())
00121 self._refresh_rocon_master(rocon_master)
00122
00123 def _set_add_rocon_master(self):
00124 if self._connect_dlg:
00125 console.logdebug("Dialog is live!!")
00126 self._connect_dlg.done(0)
00127
00128 self._connect_dlg = self._create_add_rocon_master_dialog()
00129 self._connect_dlg.setVisible(True)
00130 self._connect_dlg.finished.connect(self._destroy_connect_dlg)
00131
00132 def _refresh_rocon_master(self, rocon_master):
00133 rocon_master.check()
00134 self._widget_main.list_info_widget.clear()
00135 self._update_rocon_master_list()
00136
00137 def _refresh_all_rocon_master_list(self):
00138 self.rocon_masters.check()
00139 self._widget_main.list_info_widget.clear()
00140 self._update_rocon_master_list()
00141
00142 def _update_rocon_master_list(self):
00143 self._widget_main.list_widget.clear()
00144 for rocon_master in self.rocon_masters.values():
00145 self._add_rocon_master_list_item(rocon_master)
00146 self.rocon_masters.dump()
00147
00148 def _add_rocon_master_list_item(self, rocon_master):
00149
00150 rocon_master.current_row = str(self._widget_main.list_widget.count())
00151
00152 display_name = str(rocon_master.name) + "\n" + "[" + str(rocon_master.uri) + "]"
00153 self._widget_main.list_widget.insertItem(self._widget_main.list_widget.count(), display_name)
00154
00155
00156 font = self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).font()
00157 font.setPointSize(13)
00158 self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setFont(font)
00159
00160
00161 rocon_master_info = ""
00162 rocon_master_info += "rocon_master_index: " + str(rocon_master.index) + "\n"
00163 rocon_master_info += "rocon_master_name: " + str(rocon_master.name) + "\n"
00164 rocon_master_info += "master_uri: " + str(rocon_master.uri) + "\n"
00165 rocon_master_info += "host_name: " + str(rocon_master.host_name) + "\n"
00166 rocon_master_info += "description: " + str(rocon_master.description)
00167 self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setToolTip(rocon_master_info)
00168
00169
00170 if rocon_master.icon == "unknown.png":
00171 icon = QIcon(self.icon_paths['unknown'])
00172 self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
00173 elif len(rocon_master.icon):
00174 icon = QIcon(os.path.join(utils.get_icon_cache_home(), rocon_master.icon))
00175 self._widget_main.list_widget.item(self._widget_main.list_widget.count() - 1).setIcon(icon)
00176 else:
00177 console.logdebug("%s : No icon" % rocon_master.name)
00178
00179 def _select_rocon_master(self, Item):
00180 list_widget = Item.listWidget()
00181 for k in self.rocon_masters.values():
00182 if k.current_row == str(list_widget.currentRow()):
00183 self.cur_selected_rocon_master = k.index
00184 break
00185 self._widget_main.list_info_widget.clear()
00186 info_text = "<html>"
00187 info_text += "<p>-------------------------------------------</p>"
00188 info_text += "<p><b>name: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].name) + "</p>"
00189 info_text += "<p><b>master_uri: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].uri) + "</p>"
00190 info_text += "<p><b>host_name: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].host_name) + "</p>"
00191 info_text += "<p><b>description: </b>" + str(self.rocon_masters[self.cur_selected_rocon_master].description) + "</p>"
00192 info_text += "<p>-------------------------------------------</p>"
00193 info_text += "</html>"
00194 self._widget_main.list_info_widget.appendHtml(info_text)
00195
00196 def _destroy_connect_dlg(self):
00197 self._connect_dlg = None
00198
00199 def _connect_rocon_master(self):
00200 rocon_master_name = str(self.rocon_masters[self.cur_selected_rocon_master].name)
00201 rocon_master_uri = str(self.rocon_masters[self.cur_selected_rocon_master].uri)
00202 rocon_master_host_name = str(self.rocon_masters[self.cur_selected_rocon_master].host_name)
00203
00204 rocon_master_index = str(self.cur_selected_rocon_master)
00205 self.rocon_masters[rocon_master_index].check()
00206
00207 if self.rocon_masters[rocon_master_index].flag == '0':
00208 QMessageBox.warning(self, 'Rocon Master Connection Error', "Could not find a rocon master at %s" % self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
00209 return
00210 if self.rocon_masters[rocon_master_index].flag == '1':
00211 QMessageBox.warning(self, 'Rocon Master Communication Error', "Found a rocon master at %s but cannot communicate with it (are ROS_IP/ROS_MASTER_URI correctly configured locally and remotely?)" % self.rocon_masters[rocon_master_index].uri, QMessageBox.Ok)
00212 return
00213
00214 self._widget_main.hide()
00215 arguments = ["", rocon_master_uri, rocon_master_host_name]
00216 os.execv(QMasterChooser.rocon_remocon_sub_script, arguments)
00217 console.logdebug("Spawning: %s with args %s" % (QMasterChooser.rocon_remocon_sub_script, arguments))
00218
00219 def _create_add_rocon_master_dialog(self):
00220
00221 connect_dlg = QDialog(self._widget_main)
00222 connect_dlg.setWindowTitle("Add Ros Master")
00223 connect_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00224 connect_dlg.setMinimumSize(350, 0)
00225
00226
00227
00228 ver_layout = QVBoxLayout(connect_dlg)
00229 ver_layout.setContentsMargins(9, 9, 9, 9)
00230
00231
00232 text_grid_sub_widget = QWidget()
00233 text_grid_layout = QGridLayout(text_grid_sub_widget)
00234 text_grid_layout.setColumnStretch(1, 0)
00235 text_grid_layout.setRowStretch(2, 0)
00236
00237
00238 title_widget1 = QLabel("MASTER_URI: ")
00239 context_widget1 = QTextEdit()
00240 context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00241 context_widget1.setMinimumSize(0, 30)
00242 context_widget1.append(self.master_uri)
00243
00244
00245 title_widget2 = QLabel("HOST_NAME: ")
00246 context_widget2 = QTextEdit()
00247 context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
00248 context_widget2.setMinimumSize(0, 30)
00249 context_widget2.append(self.host_name)
00250
00251
00252 text_grid_layout.addWidget(title_widget1)
00253 text_grid_layout.addWidget(context_widget1)
00254 text_grid_layout.addWidget(title_widget2)
00255 text_grid_layout.addWidget(context_widget2)
00256
00257
00258 ver_layout.addWidget(text_grid_sub_widget)
00259
00260
00261 button_hor_sub_widget = QWidget()
00262 button_hor_layout = QHBoxLayout(button_hor_sub_widget)
00263
00264 uri_text_widget = context_widget1
00265 host_name_text_widget = context_widget2
00266
00267
00268 btn_call = QPushButton("Add")
00269 btn_cancel = QPushButton("Cancel")
00270
00271 btn_call.clicked.connect(lambda: connect_dlg.done(0))
00272 btn_call.clicked.connect(lambda: self._add_rocon_master(uri_text_widget, host_name_text_widget))
00273
00274 btn_cancel.clicked.connect(lambda: connect_dlg.done(0))
00275
00276
00277 button_hor_layout.addWidget(btn_call)
00278 button_hor_layout.addWidget(btn_cancel)
00279
00280
00281 ver_layout.addWidget(button_hor_sub_widget)
00282
00283 return connect_dlg