def reloadPackages(self):
   '''
   Reloads the cached packag list.
   '''
   if not self._fill_packages_thread.isAlive():
     self._fill_packages_thread = PackagesThread()
     self._fill_packages_thread.packages.connect(self._fill_packages)
     self._fill_packages_thread.start()
示例#2
0
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Select Binary')
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")

        self.content = QtGui.QWidget()
        self.contentLayout = QtGui.QFormLayout(self.content)
        self.contentLayout.setVerticalSpacing(0)
        self.verticalLayout.addWidget(self.content)

        self.packages = None

        package_label = QtGui.QLabel("Package:", self.content)
        self.package_field = QtGui.QComboBox(self.content)
        self.package_field.setInsertPolicy(
            QtGui.QComboBox.InsertAlphabetically)
        self.package_field.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                              QtGui.QSizePolicy.Fixed))
        self.package_field.setEditable(True)
        self.contentLayout.addRow(package_label, self.package_field)
        binary_label = QtGui.QLabel("Binary:", self.content)
        self.binary_field = QtGui.QComboBox(self.content)
        #    self.binary_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
        self.binary_field.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                              QtGui.QSizePolicy.Fixed))
        self.binary_field.setEditable(True)
        self.contentLayout.addRow(binary_label, self.binary_field)

        self.buttonBox = QtGui.QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok
                                          | QtGui.QDialogButtonBox.Cancel)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.package_field.setFocus(QtCore.Qt.TabFocusReason)
        self.package = ''
        self.binary = ''

        if self.packages is None:
            self.package_field.addItems(['packages searching...'])
            self.package_field.setCurrentIndex(0)
            self._fill_packages_thread = PackagesThread()
            self._fill_packages_thread.packages.connect(self._fill_packages)
            self._fill_packages_thread.start()

        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"),
                               self.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"),
                               self.reject)
        QtCore.QMetaObject.connectSlotsByName(self)
        self.package_field.activated[str].connect(self.on_package_selected)
        self.package_field.textChanged.connect(self.on_package_selected)
 def __init__(self):
   '''
   Creates a new list model.
   '''
   QtGui.QStandardItemModel.__init__(self)
   self.setColumnCount(len(LaunchListModel.header))
   self.setHorizontalHeaderLabels([label for label, width in LaunchListModel.header])
   self.pyqt_workaround = dict() # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
   self.items = []
   self.DIR_CACHE = {}
   self.currentPath = None
   self.load_history = self._getLoadHistory()
   self.root_paths = [os.path.normpath(p) for p in os.getenv("ROS_PACKAGE_PATH").split(':')]
   self._setNewList(self._moveUp(None))
   self.__packages = {}
   self._fill_packages_thread = PackagesThread()
   self._fill_packages_thread.packages.connect(self._fill_packages)
   self._fill_packages_thread.start()
示例#4
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Select Binary')
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")

        self.content = QWidget()
        self.contentLayout = QFormLayout(self.content)
        self.contentLayout.setVerticalSpacing(0)
        self.verticalLayout.addWidget(self.content)

        self.packages = None

        package_label = QLabel("Package:", self.content)
        self.package_field = QComboBox(self.content)
        self.package_field.setInsertPolicy(QComboBox.InsertAlphabetically)
        self.package_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        self.package_field.setEditable(True)
        self.contentLayout.addRow(package_label, self.package_field)
        binary_label = QLabel("Binary:", self.content)
        self.binary_field = QComboBox(self.content)
#    self.binary_field.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.binary_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        self.binary_field.setEditable(True)
        self.contentLayout.addRow(binary_label, self.binary_field)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.package_field.setFocus(Qt.TabFocusReason)
        self.package = ''
        self.binary = ''

        if self.packages is None:
            self.package_field.addItems(['packages searching...'])
            self.package_field.setCurrentIndex(0)
            self._fill_packages_thread = PackagesThread()
            self._fill_packages_thread.packages.connect(self._fill_packages)
            self._fill_packages_thread.start()

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)
        self.package_field.activated[str].connect(self.on_package_selected)
        if hasattr(self.package_field, "textChanged"):  # qt compatibility
            self.package_field.textChanged.connect(self.on_package_selected)
            self.binary_field.textChanged.connect(self.on_binary_selected)
        else:
            self.package_field.editTextChanged.connect(self.on_package_selected)
            self.binary_field.editTextChanged.connect(self.on_binary_selected)
示例#5
0
class PackageDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Select Binary')
        self.verticalLayout = QtGui.QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")

        self.content = QtGui.QWidget()
        self.contentLayout = QtGui.QFormLayout(self.content)
        self.contentLayout.setVerticalSpacing(0)
        self.verticalLayout.addWidget(self.content)

        self.packages = None

        package_label = QtGui.QLabel("Package:", self.content)
        self.package_field = QtGui.QComboBox(self.content)
        self.package_field.setInsertPolicy(
            QtGui.QComboBox.InsertAlphabetically)
        self.package_field.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                              QtGui.QSizePolicy.Fixed))
        self.package_field.setEditable(True)
        self.contentLayout.addRow(package_label, self.package_field)
        binary_label = QtGui.QLabel("Binary:", self.content)
        self.binary_field = QtGui.QComboBox(self.content)
        #    self.binary_field.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
        self.binary_field.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                              QtGui.QSizePolicy.Fixed))
        self.binary_field.setEditable(True)
        self.contentLayout.addRow(binary_label, self.binary_field)

        self.buttonBox = QtGui.QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok
                                          | QtGui.QDialogButtonBox.Cancel)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.package_field.setFocus(QtCore.Qt.TabFocusReason)
        self.package = ''
        self.binary = ''

        if self.packages is None:
            self.package_field.addItems(['packages searching...'])
            self.package_field.setCurrentIndex(0)
            self._fill_packages_thread = PackagesThread()
            self._fill_packages_thread.packages.connect(self._fill_packages)
            self._fill_packages_thread.start()

        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"),
                               self.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"),
                               self.reject)
        QtCore.QMetaObject.connectSlotsByName(self)
        self.package_field.activated[str].connect(self.on_package_selected)
        self.package_field.textChanged.connect(self.on_package_selected)

    def _fill_packages(self, packages):
        # fill the input fields
        self.packages = packages
        packages = packages.keys()
        packages.sort()
        self.package_field.clear()
        self.package_field.clearEditText()
        self.package_field.addItems(packages)

    def _getBinaries(self, path):
        result = {}
        if os.path.isdir(path):
            fileList = os.listdir(path)
            for f in fileList:
                if f and f[0] != '.' and not f in [
                        'build'
                ] and not f.endswith('.cfg') and not f.endswith('.so'):
                    ret = self._getBinaries(os.path.join(path, f))
                    result = dict(ret.items() + result.items())
        elif os.path.isfile(path) and os.access(path, os.X_OK):
            # create a selection for binaries
            return {os.path.basename(path): path}
        return result

    def on_package_selected(self, package):
        self.binary_field.clear()
        if self.packages and self.packages.has_key(package):
            self.binary_field.setEnabled(True)
            path = self.packages[package]
            binaries = self._getBinaries(path).keys()
            try:
                # find binaries in catkin workspace
                from catkin.find_in_workspaces import find_in_workspaces as catkin_find
                search_paths = catkin_find(search_dirs=['libexec', 'share'],
                                           project=package,
                                           first_matching_workspace_only=True)
                for p in search_paths:
                    binaries += self._getBinaries(p).keys()
            except:
                pass
            binaries = list(set(binaries))
            binaries.sort()
            self.binary_field.addItems(binaries)
            self.package = package
            self.binary = binaries[0] if binaries else ''
class LaunchListModel(QtGui.QStandardItemModel):
  '''
  The model to manage the list with launch files.
  '''
  header = [('Name', -1)]
  '''@ivar: the list with columns C{[(name, width), ...]}'''

  def __init__(self):
    '''
    Creates a new list model.
    '''
    QtGui.QStandardItemModel.__init__(self)
    self.setColumnCount(len(LaunchListModel.header))
    self.setHorizontalHeaderLabels([label for label, width in LaunchListModel.header])
    self.pyqt_workaround = dict() # workaround for using with PyQt: store the python object to keep the defined attributes in the TopicItem subclass
    self.items = []
    self.DIR_CACHE = {}
    self.currentPath = None
    self.load_history = self._getLoadHistory()
    self.root_paths = [os.path.normpath(p) for p in os.getenv("ROS_PACKAGE_PATH").split(':')]
    self._setNewList(self._moveUp(None))
    self.__packages = {}
    self._fill_packages_thread = PackagesThread()
    self._fill_packages_thread.packages.connect(self._fill_packages)
    self._fill_packages_thread.start()

  def _getRootItems(self):
    result = list(self.load_history)
    result.extend(self.root_paths)
    return result

  def _fill_packages(self, packages):
    self.__packages = packages

  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  #%%%%%%%%%%%%%              Overloaded methods                    %%%%%%%%
  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  def flags(self, index):
    '''
    @param index: parent of the list
    @type index: L{PySide.QtCore.QModelIndex}
    @return: Flag or the requested item
    @rtype: L{PySide.QtCore.Qt.ItemFlag}
    @see: U{http://www.pyside.org/docs/pyside-1.0.1/PySide/QtCore/Qt.html}
    '''
    if not index.isValid():
      return QtCore.Qt.NoItemFlags
    try:
      item = self.itemFromIndex(index)
      result = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled
      if item.id in [LaunchItem.RECENT_FILE, LaunchItem.LAUNCH_FILE, LaunchItem.CFG_FILE, LaunchItem.FOLDER]:
        result = result | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsDragEnabled
      return result
    except:
      return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  #%%%%%%%%%%%%%              Drag operation                        %%%%%%%%
  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  def mimeTypes(self):
    return ['text/plain']

  def mimeData(self, indexes):
    mimeData = QtCore.QMimeData()
    text = ''
    for index in indexes:
      if index.isValid():
        item = self.itemFromIndex(index)
        prev = '%s\n'%text if text else ''
        text = '%sfile://%s'%(prev, item.path)
    mimeData.setData('text/plain', text)
    return mimeData

  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  #%%%%%%%%%%%%%              External usage                        %%%%%%%%
  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  def reloadPackages(self):
    '''
    Reloads the cached packag list.
    '''
    if not self._fill_packages_thread.isAlive():
      self._fill_packages_thread = PackagesThread()
      self._fill_packages_thread.packages.connect(self._fill_packages)
      self._fill_packages_thread.start()

  def reloadCurrentPath(self):
    '''
    Reloads the current path.
    '''
    # clear the cache for package names
    try:
      from common import PACKAGE_CACHE
      PACKAGE_CACHE.clear()
      self.DIR_CACHE = {}
    except:
      import traceback
      print traceback.format_exc(2)
    try:
      if self.currentPath is None:
        self._setNewList(self._moveUp(self.currentPath))
      else:
          self._setNewList(self._moveDown(self.currentPath))
    except:
      self._setNewList(self._moveUp(None))

  def expandItem(self, path_item, path, id):
    '''
    Returns for the given item and path the file path if this is a file. Otherwise the 
    folder will be expanded and None will be returned.
    @param path_item: the list item
    @type path_item: C{str}
    @param path: the real path of the item
    @type path: C{str}
    @return: path of the launch file or None
    @rtype: C{str
    @raise Exception if no path to given item was found
    '''
    if path_item == '..':
      root_path, items = self._moveUp(os.path.dirname(path))
    elif os.path.isfile(path):
      return path
    elif id == LaunchItem.RECENT_FILE or id == LaunchItem.LAUNCH_FILE:
      raise Exception("Invalid file path: %s", path)
    else:
      root_path, items = self._moveDown(path)
    self._setNewList((root_path, items))
    return None


  def setPath(self, path):
    '''
    Shows the new path in the launch configuration view. Only if the new path
    is in ros package paths
    @param path: new path
    @type path: C{str}
    '''
#    if self._is_in_ros_packages(path):
    self._setNewList(self._moveDown(path))

  def add2LoadHistory(self, file):
    try:
      self.load_history.remove(file)
    except:
      pass
    self.load_history.append(file)
    try:
      while len(self.load_history) > nm.settings().launch_history_length:
        self.load_history.pop(0)
    except:
      pass
    self._storeLoadHistory(self.load_history)
#    self.reloadCurrentPath() # todo: keep the item selected in list view after the reload the path

  def removeFromLoadHistory(self, file):
    try:
      self.load_history.remove(file)
    except:
      pass
    self._storeLoadHistory(self.load_history)
#    self.reloadCurrentPath() # todo: keep the item selected in list view after the reload the path

  def show_packages(self, show):
    if show:
    # clear the cache for package names
      try:
        items = []
        for package, path in self.__packages.items():
          items.append((package, path, LaunchItem.PACKAGE))
        self._setNewList((self.currentPath if self.currentPath else '', items))
      except:
        import traceback
        print traceback.format_exc(2)
    else:
      self._setNewList(self._moveUp(self.currentPath))

  def paste_from_clipboard(self):
    '''
    Copy the file or folder to new position...
    '''
    if QtGui.QApplication.clipboard().mimeData().hasText() and self.currentPath:
      text = QtGui.QApplication.clipboard().mimeData().text()
      if text.startswith('file://'):
        path = text.replace('file://', '')
        basename = os.path.basename(text)
        ok = True
        if os.path.exists(os.path.join(self.currentPath, basename)):
          basename, ok = QtGui.QInputDialog.getText(None, 'File exists', 'New name (or override):', QtGui.QLineEdit.Normal, basename)
        if ok and basename:
          if os.path.isdir(path):
            shutil.copytree(path, os.path.join(self.currentPath, basename))
          elif os.path.isfile(path):
            shutil.copy2(path, os.path.join(self.currentPath, basename))
          self.reloadCurrentPath()

  def copy_to_clipboard(self, indexes):
    '''
    Copy the selected path to the clipboard
    '''
    mimeData = QtCore.QMimeData()
    text = ''
    for index in indexes:
      if index.isValid():
        item = self.itemFromIndex(index)
        prev = '%s\n'%text if text else ''
        text = '%sfile://%s'%(prev, item.path)
    mimeData.setData('text/plain', text)
    QtGui.QApplication.clipboard().setMimeData(mimeData)
        
  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  #%%%%%%%%%%%%%              Functionality                         %%%%%%%%
  #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  def _setNewList(self, (root_path, items)):
    '''
    Sets the list to the given path and insert the items. If the root path is not
    None the additional item '..' to go up will be inserted. The items parameter 
    is a tupel with three values (the displayed name, the path of the item, the id
    of the item). 
    @see: L{LaunchListModel._addPathToList()}
    @param root_path: the root directory
    @type root_path: C{str}
    @param items: the list with characterized items
    @type items: C{[(item, path, id)]}
    '''
    root = self.invisibleRootItem()
    while root.rowCount():
      root.removeRow(0)
    self.pyqt_workaround.clear()
    # add new items
    if not root_path is None:
      self._addPathToList('..', root_path, LaunchItem.NOTHING)
    for item_name, item_path, item_id in items:
      self._addPathToList(item_name, item_path, item_id)
    self.currentPath = root_path
示例#7
0
class PackageDialog(QDialog):

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle('Select Binary')
        self.verticalLayout = QVBoxLayout(self)
        self.verticalLayout.setObjectName("verticalLayout")

        self.content = QWidget()
        self.contentLayout = QFormLayout(self.content)
        self.contentLayout.setVerticalSpacing(0)
        self.verticalLayout.addWidget(self.content)

        self.packages = None

        package_label = QLabel("Package:", self.content)
        self.package_field = QComboBox(self.content)
        self.package_field.setInsertPolicy(QComboBox.InsertAlphabetically)
        self.package_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        self.package_field.setEditable(True)
        self.contentLayout.addRow(package_label, self.package_field)
        binary_label = QLabel("Binary:", self.content)
        self.binary_field = QComboBox(self.content)
#    self.binary_field.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        self.binary_field.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed))
        self.binary_field.setEditable(True)
        self.contentLayout.addRow(binary_label, self.binary_field)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.package_field.setFocus(Qt.TabFocusReason)
        self.package = ''
        self.binary = ''

        if self.packages is None:
            self.package_field.addItems(['packages searching...'])
            self.package_field.setCurrentIndex(0)
            self._fill_packages_thread = PackagesThread()
            self._fill_packages_thread.packages.connect(self._fill_packages)
            self._fill_packages_thread.start()

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)
        self.package_field.activated[str].connect(self.on_package_selected)
        if hasattr(self.package_field, "textChanged"):  # qt compatibility
            self.package_field.textChanged.connect(self.on_package_selected)
            self.binary_field.textChanged.connect(self.on_binary_selected)
        else:
            self.package_field.editTextChanged.connect(self.on_package_selected)
            self.binary_field.editTextChanged.connect(self.on_binary_selected)

    def _fill_packages(self, packages):
        # fill the input fields
        self.packages = packages
        packages = packages.keys()
        packages.sort()
        self.package_field.clear()
        self.package_field.clearEditText()
        self.package_field.addItems(packages)

    def _getBinaries(self, path):
        result = {}
        if os.path.isdir(path):
            fileList = os.listdir(path)
            for f in fileList:
                if f and f[0] != '.' and f not in ['build'] and not f.endswith('.cfg') and not f.endswith('.so'):
                    ret = self._getBinaries(os.path.join(path, f))
                    result = dict(ret.items() + result.items())
        elif os.path.isfile(path) and os.access(path, os.X_OK):
            # create a selection for binaries
            return {os.path.basename(path): path}
        return result

    def on_package_selected(self, package):
        self.binary_field.clear()
        if self.packages and package in self.packages:
            self.binary_field.setEnabled(True)
            path = self.packages[package]
            binaries = self._getBinaries(path).keys()
            try:
                # find binaries in catkin workspace
                from catkin.find_in_workspaces import find_in_workspaces as catkin_find
                search_paths = catkin_find(search_dirs=['libexec', 'share'], project=package, first_matching_workspace_only=True)
                for p in search_paths:
                    binaries += self._getBinaries(p).keys()
            except:
                pass
            binaries = list(set(binaries))
            binaries.sort()
            self.binary_field.addItems(binaries)
            self.package = package
            self.binary = self.binary_field.currentText()

    def on_binary_selected(self, binary):
        self.binary = binary