docs: def _makeDPItem(self, parent, dp, after=None):
          """Creates listview item for data product 'dp', inserts it after item 'after'"""
          if parent:
              item = QTreeWidgetItem(parent, after)
          else:
              item = QTreeWidgetItem()
          item.setTextAlignment(self.ColAction, Qt.AlignRight | Qt.AlignVCenter)
          item.setTextAlignment(self.ColFilename, Qt.AlignRight | Qt.AlignVCenter)
          item.setTextAlignment(self.ColType, Qt.AlignLeft | Qt.AlignVCenter)
          item.setTextAlignment(self.ColRename, Qt.AlignLeft | Qt.AlignVCenter)
          item.setTextAlignment(self.ColRender, Qt.AlignHCenter | Qt.AlignVCenter)
          item.setTextAlignment(self.ColComment, Qt.AlignLeft | Qt.AlignVCenter)
          item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsEnabled)
          item._dp = dp
          # init stuff for combobox functions above
          item._combobox_option_list = {}
          item._combobox_current_index = {}
          item._combobox_current_value = {}
          item._combobox_indices = {}
          item._combobox_changed = {}
          # setup available policies for new or archived items, set initial policy
          if dp.archived:
              item._menu = self._archived_dp_menu
              item._combobox_option_list[self.ColAction] = policies = self._policy_list_archived
              policy = "keep"
          else:
              item._combobox_option_list[self.ColAction] = policies = self._policy_list_default
              policy = dp.policy
          # create reverse mapping from policy names to indices
          item._combobox_indices[self.ColAction] = dict([(name, num) for num, (name, icon) in enumerate(policies)])
          # init item policy
          self.setItemPolicy(item, policy)
          # set other columns
          basename = os.path.basename(dp.sourcepath)
          name, ext = os.path.splitext(basename)
          item.setText(self.ColFilename, name)
          item.setText(self.ColType, ext)
          item.setToolTip(self.ColFilename, basename)
          item.setToolTip(self.ColType, basename)
          item.setData(self.ColComment, Qt.EditRole, QVariant(dp.comment or ""))
          # make sure new filenames are unique
          filename = _sanitizeFilename(dp.filename)
          if not dp.archived:
              # tack on .tgz prefix onto dirs
              if os.path.isdir(dp.sourcepath) and not filename.endswith(".tgz"):
                  filename += ".tgz"
              # form up set of taken names
              taken_names = set()
              for i0, dp0 in self.getItemDPList():
                  if dp0.policy not in ["remove", "ignore", "banish"]:
                      taken_names.add(str(i0.text(self.ColRename)))
              # ensure uniqueness of filename
              filename = _makeUniqueFilename(taken_names, filename)
          item.setData(self.ColRename, Qt.EditRole, QVariant(filename))
          # get list of available renderers
          item._renderers = Purr.Render.getRenderers(dp.fullpath or dp.sourcepath)
          item._render = 0
          item._combobox_option_list[self.ColRender] = [(name, None) for name in item._renderers]
          # create reverse mapping from renderer names to indices
          item._combobox_indices[self.ColRender] = dict([(name, num) for num, name in enumerate(item._renderers)])
          # for archived items, try to find renderer in list
          if dp.archived:
              try:
                  item._render = item._renderers.index(dp.render)
              except:
                  pass
          self._updateItemComboBoxIndex(item, self.ColRender, item._render)
          # add to map of items
          self.dpitems[dp.fullpath or dp.sourcepath] = item
          return item