Exemplo n.º 1
0
class LaunchFilesWidget(QDockWidget):
    '''
    Launch file browser.
    '''

    load_signal = Signal(str)
    ''' load the launch file '''
    load_as_default_signal = Signal(str, str)
    ''' load the launch file as default (path, host) '''
    edit_signal = Signal(list)
    ''' list of paths to open in an editor '''
    transfer_signal = Signal(list)
    ''' list of paths selected for transfer '''

    def __init__(self, parent=None):
        '''
        Creates the window, connects the signals and init the class.
        '''
        QDockWidget.__init__(self, parent)
        # initialize parameter
        self.__current_path = os.path.expanduser('~')
        # load the UI file
        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'LaunchFilesDockWidget.ui')
        loadUi(ui_file, self)
        # initialize the view for the launch files
        self.launchlist_model = LaunchListModel()
        self.launchlist_proxyModel = QSortFilterProxyModel(self)
        self.launchlist_proxyModel.setSourceModel(self.launchlist_model)
        self.xmlFileView.setModel(self.launchlist_proxyModel)
        self.xmlFileView.setAlternatingRowColors(True)
        self.xmlFileView.activated.connect(self.on_launch_selection_activated)
        self.xmlFileView.setDragDropMode(QAbstractItemView.DragOnly)
        self.xmlFileView.setDragEnabled(True)
        sm = self.xmlFileView.selectionModel()
        sm.selectionChanged.connect(self.on_xmlFileView_selection_changed)
#    self.searchPackageLine.setVisible(False)
        self.searchPackageLine.textChanged.connect(self.set_package_filter)
        self.searchPackageLine.focusInEvent = self._searchline_focusInEvent
        # connect to the button signals
        self.refreshXmlButton.clicked.connect(self.on_refresh_xml_clicked)
        self.editXmlButton.clicked.connect(self.on_edit_xml_clicked)
        self.newXmlButton.clicked.connect(self.on_new_xml_clicked)
        self.openXmlButton.clicked.connect(self.on_open_xml_clicked)
        self.transferButton.clicked.connect(self.on_transfer_file_clicked)
        self.loadXmlButton.clicked.connect(self.on_load_xml_clicked)
        self.loadXmlAsDefaultButton.clicked.connect(self.on_load_as_default)
        # creates a default config menu
        start_menu = QMenu(self)
        self.loadDeafaultAtHostAct = QAction("&Load default config on host", self, statusTip="Loads the default config at given host", triggered=self.on_load_as_default_at_host)
        start_menu.addAction(self.loadDeafaultAtHostAct)
        self.loadXmlAsDefaultButton.setMenu(start_menu)
        # initialize the progress queue
        self.progress_queue = ProgressQueue(self.progressFrame_cfg, self.progressBar_cfg, self.progressCancelButton_cfg)

    def stop(self):
        '''
        Cancel the executing queued actions. This method must be
        called at the exit!
        '''
        self.progress_queue.stop()

    def on_launch_selection_activated(self, activated):
        '''
        Tries to load the launch file, if one was activated.
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        for item in selected:
            try:
                lfile = self.launchlist_model.expandItem(item.name, item.path, item.id)
                self.searchPackageLine.setText('')
                if lfile is not None:
                    if item.isLaunchFile():
                        self.launchlist_model.add2LoadHistory(item.path)
                        key_mod = QApplication.keyboardModifiers()
                        if key_mod & Qt.ShiftModifier:
                            self.load_as_default_signal.emit(item.path, None)
                        elif key_mod & Qt.ControlModifier:
                            self.launchlist_model.setPath(os.path.dirname(item.path))
                        else:
                            self.load_signal.emit(item.path)
                    elif item.isConfigFile():
                        self.edit_signal.emit([lfile])
            except Exception as e:
                rospy.logwarn("Error while load launch file %s: %s" % (item, e))
                WarningMessageBox(QMessageBox.Warning, "Load error",
                                  'Error while load launch file:\n%s' % item.name,
                                  "%s" % e).exec_()
#        self.launchlist_model.reloadCurrentPath()

    def on_xmlFileView_selection_changed(self, selected, deselected):
        '''
        On selection of a launch file, the buttons are enabled otherwise disabled.
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        for item in selected:
            islaunch = item.isLaunchFile()
            isconfig = item.isConfigFile()
            self.editXmlButton.setEnabled(islaunch or isconfig)
            self.loadXmlButton.setEnabled(islaunch)
            self.transferButton.setEnabled(islaunch or isconfig)
            self.loadXmlAsDefaultButton.setEnabled(islaunch)

    def set_package_filter(self, text):
        self.launchlist_proxyModel.setFilterRegExp(QRegExp(text,
                                                           Qt.CaseInsensitive,
                                                           QRegExp.Wildcard))

    def on_refresh_xml_clicked(self):
        '''
        Reload the current path.
        '''
        self.launchlist_model.reloadCurrentPath()
        self.launchlist_model.reloadPackages()
        self.editXmlButton.setEnabled(False)
        self.loadXmlButton.setEnabled(False)
        self.transferButton.setEnabled(False)
        self.loadXmlAsDefaultButton.setEnabled(False)

    def on_edit_xml_clicked(self):
        '''
        Opens an XML editor to edit the launch file.
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        for item in selected:
            path = self.launchlist_model.expandItem(item.name, item.path, item.id)
            if path is not None:
                self.edit_signal.emit([path])

    def on_new_xml_clicked(self):
        '''
        Creates a new launch file.
        '''
        # get new file from open dialog, use last path if one exists
        open_path = self.__current_path
        if self.launchlist_model.currentPath is not None:
            open_path = self.launchlist_model.currentPath
        (fileName, _) = QFileDialog.getSaveFileName(self,
                                                    "New launch file",
                                                    open_path,
                                                    "Config files (*.launch *.yaml);;All files (*)")
        if fileName:
            try:
                (pkg, _) = package_name(os.path.dirname(fileName))  # _:=pkg_path
                if pkg is None:
                    WarningMessageBox(QMessageBox.Warning, "New File Error",
                                      'The new file is not in a ROS package').exec_()
                    return
                with open(fileName, 'w+') as f:
                    f.write("<launch>\n"
                            "  <arg name=\"robot_ns\" default=\"my_robot\"/>\n"
                            "  <group ns=\"$(arg robot_ns)\">\n"
                            "    <param name=\"tf_prefix\" value=\"$(arg robot_ns)\"/>\n"
                            "\n"
                            "    <node pkg=\"my_pkg\" type=\"my_node\" name=\"my_name\" >\n"
                            "      <param name=\"capability_group\" value=\"MY_GROUP\"/>\n"
                            "    </node>\n"
                            "  </group>\n"
                            "</launch>\n"
                            )
                self.__current_path = os.path.dirname(fileName)
                self.launchlist_model.setPath(self.__current_path)
                self.edit_signal.emit([fileName])
            except EnvironmentError as e:
                WarningMessageBox(QMessageBox.Warning, "New File Error",
                                  'Error while create a new file',
                                  '%s' % e).exec_()

    def on_open_xml_clicked(self):
        (fileName, _) = QFileDialog.getOpenFileName(self,
                                                    "Load launch file",
                                                    self.__current_path,
                                                    "Config files (*.launch);;All files (*)")
        if fileName:
            self.__current_path = os.path.dirname(fileName)
            self.launchlist_model.add2LoadHistory(fileName)
            self.load_signal.emit(fileName)

    def on_transfer_file_clicked(self):
        '''
        Emit the signal to copy the selected file to a remote host.
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        paths = list()
        for item in selected:
            path = self.launchlist_model.expandItem(item.name, item.path, item.id)
            if path is not None:
                paths.append(path)
        if paths:
            self.transfer_signal.emit(paths)

    def on_load_xml_clicked(self):
        '''
        Tries to load the selected launch file. The button is only enabled and this
        method is called, if the button was enabled by on_launch_selection_clicked()
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        for item in selected:
            path = self.launchlist_model.expandItem(item.name, item.path, item.id)
            if path is not None:
                self.launchlist_model.add2LoadHistory(path)
                self.load_signal.emit(path)

    def on_load_as_default_at_host(self):
        '''
        Tries to load the selected launch file as default configuration. The button
        is only enabled and this method is called, if the button was enabled by
        on_launch_selection_clicked()
        '''
        selected = self._launchItemsFromIndexes(self.xmlFileView.selectionModel().selectedIndexes(), False)
        for item in selected:
            path = self.launchlist_model.expandItem(item.name, item.path, item.id)
            if path is not None:
                params = {'Host': ('string', 'localhost')}
                dia = ParameterDialog(params)
                dia.setFilterVisible(False)
                dia.setWindowTitle('Start node on...')
                dia.resize(350, 120)
                dia.setFocusField('Host')
                if dia.exec_():
                    try:
                        params = dia.getKeywords()
                        host = params['Host']
                        rospy.loginfo("LOAD the launch file on host %s as default: %s" % (host, path))
                        self.launchlist_model.add2LoadHistory(path)
                        self.load_as_default_signal.emit(path, host)
                    except Exception, e:
                        WarningMessageBox(QMessageBox.Warning, "Load default config error",
                                          'Error while parse parameter',
                                          '%s' % e).exec_()
Exemplo n.º 2
0
 def setFilterRegExp(self, string):
     self.invalidateFilter()
     QSortFilterProxyModel.setFilterRegExp(self, string)
Exemplo n.º 3
0
 def setFilterRegExp(self, string):
     self.invalidateFilter()
     QSortFilterProxyModel.setFilterRegExp(self, string)