Example #1
0
    def __init__(self, context):
        super(NodeManager, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('NodeManagerFKIE')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q",
                            "--quiet",
                            action="store_true",
                            dest="quiet",
                            help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print('arguments: ', args)
            print('unknowns: ', unknowns)
        fkie_node_manager.init_settings()
        masteruri = fkie_node_manager.settings().masteruri()
        fkie_node_manager.init_globals(masteruri)
        # Create QWidget
        try:
            self._widget = MainWindow()
#          self._widget.read_view_history()
        except Exception, e:
            MessageBox.critical(None, "Node Manager", utf8(e))
            raise
 def file_changed(self, mtime):
     if self.file_mtime != mtime:
         self.file_mtime = mtime
         result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No)
         if result == MessageBox.Yes:
             try:
                 _, self.file_mtime, file_content = nm.nmd().file.get_file_content(self.filename, force=True)
                 self.setText(file_content)
                 self.document().setModified(False)
                 self.textChanged.emit()
             except Exception as err:
                 MessageBox.critical(self, "Error", "Cannot open launch file %s" % self.filename, utf8(err))
Example #3
0
    def save(self, force=False):
        '''
        Saves changes to the file.

        :return: saved, errors, msg
        :rtype: bool, bool, str
        '''
        if force or self.document().isModified():
            try:
                mtime = nm.nmd().file.save_file(self.filename, self.toPlainText().encode('utf-8'), 0 if force else self.file_mtime)
                self.file_mtime = mtime
                if mtime == 0:
                    MessageBox.warning(self, "Warning", "File not saved and not error reported: %s" % os.path.basename(self.filename))
                self.document().setModified(mtime == 0)
                ext = os.path.splitext(self.filename)
                # validate the xml structure of the launch files
                if ext[1] in self.CONTEXT_FILE_EXT:
                    imported = False
                    try:
                        from lxml import etree
                        imported = True
                        parser = etree.XMLParser()
                        etree.fromstring(self.toPlainText().encode('utf-8'), parser)
                    except Exception as e:
                        if imported:
                            self.markLine(e.position[0])
                            return True, True, "%s" % e
                # validate the yaml structure of yaml files
                elif ext[1] in self.YAML_VALIDATION_FILES:
                    try:
                        import ruamel.yaml
                        ruamel.yaml.load(self.toPlainText().encode('utf-8'), Loader=ruamel.yaml.Loader)
                    except ruamel.yaml.MarkedYAMLError as e:
                        return True, True, "YAML validation error: %s" % e
                return True, False, ''
            except IOError as ioe:
                if ioe.errno in [file_item.EFILE_CHANGED, file_item.EFILE_REMOVED]:
                    result = MessageBox.question(self, "Changed file", "%s\n%s" % (utf8(ioe), "Save anyway?"), buttons=MessageBox.Yes | MessageBox.No)
                    if result == MessageBox.Yes:
                        return self.save(force=True)
                else:
                    rospy.logwarn("Error while save file: %s" % ioe)
                    MessageBox.critical(self, "Error", "Error while save file: %s" % os.path.basename(self.filename), detailed_text=utf8(ioe))
            except Exception as e:
                rospy.logwarn("Error while save file: %s" % e)
                print(traceback.format_exc())
        return False, False, ''
    def __init__(self, context):
        super(NodeManager, self).__init__(context)
        # Give QObjects reasonable names
        self.setObjectName('NodeManagerFKIE')

        # Process standalone plugin command-line arguments
        from argparse import ArgumentParser
        parser = ArgumentParser()
        # Add argument(s) to the parser.
        parser.add_argument("-q",
                            "--quiet",
                            action="store_true",
                            dest="quiet",
                            help="Put plugin in silent mode")
        args, unknowns = parser.parse_known_args(context.argv())
        if not args.quiet:
            print('arguments: ', args)
            print('unknowns: ', unknowns)
        fkie_node_manager.init_settings()
        masteruri = fkie_node_manager.settings().masteruri()
        fkie_node_manager.init_globals(masteruri)
        # Create QWidget
        try:
            self._widget = MainWindow()
#          self._widget.read_view_history()
        except Exception as e:
            MessageBox.critical(None, "Node Manager", utf8(e))
            raise
        # Get path to UI file which is a sibling of this file
        # in this example the .ui and .py file are in the same folder
#        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'MyPlugin.ui')
# Extend the widget with all attributes and children from UI file
#        loadUi(ui_file, self._widget)
# Give QObjects reasonable names
        self._widget.setObjectName('NodeManagerFKIEPlugin')
        # Show _widget.windowTitle on left-top of each plugin (when
        # it's set in _widget). This is useful when you open multiple
        # plugins at once. Also if you open multiple instances of your
        # plugin at once, these lines add number to make it easy to
        # tell from pane to pane.
        if context.serial_number() > 1:
            self._widget.setWindowTitle(self._widget.windowTitle() +
                                        (' (%d)' % context.serial_number()))
        # Add widget to the user interface
        context.add_widget(self._widget)
Example #5
0
 def on_saveButton_clicked(self):
     '''
     Saves the current document. This method is called if the C{save button}
     was clicked.
     '''
     saved, errors, msg = self.tabWidget.currentWidget().save()
     if errors:
         if msg:
             rospy.logwarn(msg)
             MessageBox.critical(self, "Error", "Error while save file: %s" % os.path.basename(self.tabWidget.currentWidget().filename), detailed_text=msg)
         self.tabWidget.setTabIcon(self.tabWidget.currentIndex(), self._error_icon)
         self.tabWidget.setTabToolTip(self.tabWidget.currentIndex(), msg)
         self.on_graph_info("saved failed %s: %s" % (self.tabWidget.currentWidget().filename, msg), True)
     elif saved:
         self.on_graph_info("saved %s" % self.tabWidget.currentWidget().filename)
         self.tabWidget.setTabIcon(self.tabWidget.currentIndex(), self._empty_icon)
         self.tabWidget.setTabToolTip(self.tabWidget.currentIndex(), '')
         self.graph_view.clear_cache()
Example #6
0
 def mouseReleaseEvent(self, event):
     '''
     Opens the new editor, if the user clicked on the included file and sets the
     default cursor.
     '''
     if self.isReadOnly():
         event.accept()
         return
     if event.modifiers() == Qt.ControlModifier or event.modifiers(
     ) == Qt.ShiftModifier:
         cursor = self.cursorForPosition(event.pos())
         try:
             textblock = self._strip_bad_parts(cursor.block().text(),
                                               cursor.positionInBlock())
             for inc_file in find_included_files(textblock,
                                                 False,
                                                 False,
                                                 search_in_ext=[]):
                 aval = inc_file.raw_inc_path
                 aitems = aval.split("'")
                 for search_for in aitems:
                     if not search_for:
                         continue
                     try:
                         rospy.logdebug("try to interpret: %s" % search_for)
                         args_in_name = get_arg_names(search_for)
                         resolved_args = {}
                         # if found arg in the name, try to detect values
                         if args_in_name:
                             rospy.logdebug(
                                 "  args %s in filename found, try to resolve..."
                                 % args_in_name)
                             resolved_args = self.parent.graph_view.get_include_args(
                                 args_in_name, search_for, self.filename)
                         if resolved_args:
                             params = {}
                             self._internal_args
                             # create parameter dialog
                             for key, val in resolved_args.items():
                                 values = list(val)
                                 # add args defined in current file
                                 if key in self._internal_args and self._internal_args[
                                         key] not in values:
                                     values.append(self._internal_args[key])
                                 params[key] = {
                                     ':type': 'string',
                                     ':value': values
                                 }
                             dia = ParameterDialog(
                                 params,
                                 store_geometry="open_launch_on_click")
                             dia.setFilterVisible(False)
                             dia.setWindowTitle('Select Parameter')
                             if dia.exec_():
                                 params = dia.getKeywords()
                                 search_for = replace_arg(
                                     search_for, params)
                             else:
                                 # canceled -> cancel interpretation
                                 QTextEdit.mouseReleaseEvent(self, event)
                                 return
                         # now resolve find-statements
                         rospy.logdebug(
                             "  send interpret request to daemon: %s" %
                             search_for)
                         inc_files = nm.nmd().launch.get_interpreted_path(
                             self.filename, text=[search_for])
                         for path, exists in inc_files:
                             try:
                                 rospy.logdebug(
                                     "  received interpret request from daemon: %s, exists: %d"
                                     % (path, exists))
                                 if exists:
                                     event.setAccepted(True)
                                     self.load_request_signal.emit(path)
                                 else:
                                     _filename, file_extension = os.path.splitext(
                                         path)
                                     if file_extension in nm.settings(
                                     ).launch_view_file_ext:
                                         # create a new file, if it does not exists
                                         result = MessageBox.question(
                                             self,
                                             "File not exists",
                                             '\n\n'.join([
                                                 "Create a new file?", path
                                             ]),
                                             buttons=MessageBox.Yes
                                             | MessageBox.No)
                                         if result == MessageBox.Yes:
                                             content = '<launch>\n\n</launch>' if path.endswith(
                                                 '.launch') else ''
                                             nm.nmd().file.save_file(
                                                 path, content.encode(), 0)
                                             event.setAccepted(True)
                                             self.load_request_signal.emit(
                                                 path)
                             except Exception as e:
                                 MessageBox.critical(self,
                                                     "Error",
                                                     "File not found %s" %
                                                     path,
                                                     detailed_text=utf8(e))
                     except exceptions.ResourceNotFound as not_found:
                         MessageBox.critical(
                             self,
                             "Error",
                             "Resource not found %s" % search_for,
                             detailed_text=utf8(not_found.error))
         except Exception as err:
             print(traceback.format_exc())
             MessageBox.critical(self,
                                 "Error",
                                 "Error while request included file %s" %
                                 self.filename,
                                 detailed_text=utf8(err))
     QTextEdit.mouseReleaseEvent(self, event)
Example #7
0
    def on_load_request(self, filename, search_text='', insert_index=-1, goto_line=-1, only_launch=False, count_results=0):
        '''
        Loads a file in a new tab or focus the tab, if the file is already open.

        :param str filename: the path to file
        :param str search_text: if not empty, searches in new document for first occurrence of the given text
        '''
        if not filename:
            return
        self.tabWidget.setUpdatesEnabled(False)
        try:
            if filename not in self.files:
                tab_name = self.__getTabName(filename)
                editor = TextEdit(filename, parent=self)
                linenumber_editor = LineNumberWidget(editor)
                tab_index = 0
                if insert_index > -1:
                    tab_index = self.tabWidget.insertTab(insert_index, linenumber_editor, tab_name)
                else:
                    tab_index = self.tabWidget.addTab(linenumber_editor, tab_name)
                self.files.append(filename)
                editor.setCurrentPath(os.path.basename(filename))
                editor.load_request_signal.connect(self.on_load_request)
                editor.document().modificationChanged.connect(self.on_editor_modificationChanged)
                editor.cursorPositionChanged.connect(self.on_editor_positionChanged)
                editor.setFocus(Qt.OtherFocusReason)
#                editor.textChanged.connect(self.on_text_changed)
                editor.undoAvailable.connect(self.on_text_changed)
                self.tabWidget.setCurrentIndex(tab_index)
#                self.find_dialog.set_search_path(filename)
            else:
                for i in range(self.tabWidget.count()):
                    if self.tabWidget.widget(i).filename == filename:
                        self.tabWidget.setCurrentIndex(i)
                        break
            self.tabWidget.setUpdatesEnabled(True)
            if search_text:
                if only_launch:
                    self.find_dialog.found_files_list.clear()
                try:
                    self._search_thread.stop()
                    self._search_thread = None
                except Exception:
                    pass
                # TODO: put all text of all tabs into path_text
                rospy.logdebug("serach for '%s'" % search_text)
                self._search_node_count = 0
                self._search_thread = TextSearchThread(search_text, filename, recursive=True, only_launch=only_launch, count_results=count_results)
                self._search_thread.search_result_signal.connect(self.on_search_result_on_open)
                self._search_thread.warning_signal.connect(self.on_search_result_warning)
                self._last_search_request = (filename, search_text, insert_index, goto_line, only_launch)
                if not self.graph_view.is_loading():
                    self.on_graph_info("search thread: start search for '%s'" % self._search_thread._search_text)
                    self._search_thread.start()
            if goto_line != -1:
                self._goto(goto_line, True)
            self.upperButton.setEnabled(self.tabWidget.count() > 1)
        except Exception as err:
            self.tabWidget.setUpdatesEnabled(True)
            import traceback
            msg = "Error while open %s: %s" % (filename, traceback.format_exc())
            rospy.logwarn(msg)
            MessageBox.critical(self, "Error", utf8(err), msg)
            if self.tabWidget.count() == 0:
                self.close()