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