Beispiel #1
0
    def setData(self, value, role=Qt.EditRole):

        if role == Qt.EditRole:

            metaobj = self._metaobj
            if not metaobj:
                return

            bSuccess = False
            try:
                value = self._metaprpty.castFromUi(value)
                bSuccess = metaobj.setPrpty(self.propertyName,
                                            value,
                                            warn=False,
                                            prompt=True)
            except Exception, err:
                sMsg = u"Could not set {}.{}:\n\n".format(
                    metaobj, self.propertyName)
                confirmDialog(title='SORRY !',
                              message=sMsg + toStr(err),
                              button=["OK"],
                              defaultButton="OK",
                              cancelButton="OK",
                              dismissString="OK",
                              icon="critical")
                raise

            if bSuccess:
                metaobj.refresh()
                self.emitDataChanged()
    def __publishFiles(self, pubDir):

        if not pubDir.freeToPublish():
            confirmDialog(title='SORRY !',
                          message="You can't add new files here.",
                          button=["OK"],
                          icon="information")
            return

        sRes = confirmDialog(title="DO YOU WANT TO...",
                                 message="publish ?",
                                 button=["Files", "Packages", "Cancel"],
                                 defaultButton="Cancel",
                                 cancelButton="Cancel",
                                 dismissString="Cancel",
                                 icon="question")
        if sRes == "Cancel":
            logMsg("Canceled !", warning=True)
            return
        elif sRes == "Files":
            sSrcPathList = self.chooseFiles(pubDir)
        elif sRes == "Packages":
            sSrcPathList = self.choosePacks(pubDir)

        if not sSrcPathList:
            logMsg("No {} selected: Canceled.".format(sRes.lower()), warning=True)
            return

        pubDir._publishFiles(sSrcPathList, autoLock=True, autoUnlock=True)
Beispiel #3
0
    def createNewDirectory(self, *itemList):

        item = itemList[-1]
        pubDir = item._metaobj
        #proj = self.model()._metamodel

        if not pubDir.allowFreePublish():
            confirmDialog(title='SORRY !',
                          message="You can't add new directories here.",
                          button=["OK"],
                          icon="information")
            return

        result = promptDialog(title='Please...',
                            message='Directory Name: ',
                            button=['OK', 'Cancel'],
                            defaultButton='OK',
                            cancelButton='Cancel',
                            dismissString='Cancel',
                            scrollableField=True,
                            )

        if result == 'Cancel':
            logMsg("Cancelled !" , warning=True)
            return

        sDirName = promptDialog(query=True, text=True)
        if not sDirName:
            return

        os.mkdir(pathJoin(pubDir.absPath(), sDirName.strip().replace(" ", "_")))
        pubDir.refresh(children=True)
Beispiel #4
0
    def setProject(self, *args, **kwargs):

        try:
            return self.browserWidget.setProject(*args, **kwargs)
        except Exception, err:
            confirmDialog(title='SORRY !'
                        , message=toStr(err)
                        , button=["OK"]
                        , defaultButton="OK"
                        , cancelButton="OK"
                        , dismissString="OK"
                        , icon="critical")

            if not hostApp():
                os.environ["PYTHONINSPECT"] = "1"

            self.close()

            raise

#    def __del__(self):
#        print "__del__", self.objectName()

#    def closeEvent(self, event):
#        print self, "closeEvent"
#        return QtGui.QMainWindow.closeEvent(self, event)
    def doPublish(self, *itemList):

        item = itemList[-1]
        pubEntry = item._metaobj
        proj = self.model()._metamodel

        if isinstance(pubEntry, DrcFile):

            try:
                pubEntry.assertFreeToPublish()
            except EnvironmentError as e:
                confirmDialog(title='SORRY !',
                              message="Publishing not allowed:\n\n" + toStr(e),
                              button=["OK"],
                              icon="critical")
                return

            sAbsPath = pubEntry.absPath()
            if proj.isEditableResource(sAbsPath):

                if hostApp() == "maya":
                    sExt = osp.splitext(sAbsPath)[-1]
                    if sExt in (".ma", ".mb"):
                        raise EnvironmentError("Please, publish from integrated 'Davos' menu.")

                self.__publishEditedVersion(pubEntry)
            else:
                self.__publishRegularVersion(pubEntry)
        else:
            self.__publishFiles(pubEntry)
    def setData(self, value, role=Qt.EditRole):

        if role == Qt.EditRole:

            metaobj = self._metaobj
            if not metaobj:
                return

            bSuccess = False
            try:
                value = self._metaprpty.castFromUi(value)
                bSuccess = metaobj.setPrpty(self.propertyName, value, warn=False, prompt=True)
            except Exception, err:
                sMsg = u"Could not set {}.{}:\n\n".format(metaobj, self.propertyName)
                confirmDialog(title='SORRY !',
                              message=sMsg + toStr(err),
                              button=["OK"],
                              defaultButton="OK",
                              cancelButton="OK",
                              dismissString="OK",
                              icon="critical")
                raise

            if bSuccess:
                metaobj.refresh()
                self.emitDataChanged()
    def importFiles(self, *itemList):

        proj = self.model()._metamodel

        try:
            if not hostApp():
                raise AssertionError("You can only import from inside another application.")

            drcFileList = tuple(item._metaobj for item in itemList)

            if len(drcFileList) > 1:
                for drcFile in drcFileList:
                    try:
                        drcFile.importIt()
                    except Exception as e:
                        sResult = confirmDialog(title='SORRY !',
                                                message=toStr(e),
                                                button=["Continue", "Abort"],
                                                defaultButton="Continue",
                                                cancelButton="Abort",
                                                dismissString="Abort",
                                                icon="critical")
                        if sResult == "Abort":
                            break
                        else:
                            continue
            else:
                drcFileList[0].importIt()
        finally:
            proj.mayaLoadReferences = True
Beispiel #8
0
    def deleteDbNode(self, *itemList):

        entryList = []
        msg = ""
        for item in itemList:
            entry = item._metaobj
            dbNode = entry._dbnode
            if dbNode:
                r = dbNode.dataRepr("file")
                r = re.sub(r"[\s{}]", "", r)
                msg += (r + "\n")
                entryList.append(entry)

        sMsg = u'Are you sure you want to DELETE these db nodes:\n\n' + msg

        sConfirm = confirmDialog(title='WARNING !',
                                 message=sMsg,
                                 button=['OK', 'Cancel'],
                                 defaultButton='Cancel',
                                 cancelButton='Cancel',
                                 dismissString='Cancel',
                                 icon="warning")

        if sConfirm == 'Cancel':
            logMsg("Cancelled !", warning=True)
            return

        for entry in entryList:
            entry.deleteDbNode()
Beispiel #9
0
    def __publishFiles(self, pubDir):

        if not pubDir.allowFreePublish():
            confirmDialog(title='SORRY !',
                          message="You can't add new files here.",
                          button=["OK"],
                          icon="information")
            return

        sFilePathList = self.chooseFiles(pubDir)
        if not sFilePathList:
            logMsg("Cancelled !", warning=True)
            return

        for sSrcFilePath in sFilePathList:
            print pubDir.publishFile(sSrcFilePath, autoLock=True, autoUnlock=True)

        pubDir.refresh(children=True)
Beispiel #10
0
    def showPrivateLoc(self, *itemList):

        item = itemList[-1]
        drcEntry = item._metaobj

        pubDir = drcEntry
        if isinstance(drcEntry, DrcFile):
            pubDir = drcEntry.parentDir()

        privDir = pubDir.getHomonym("private")

        if not privDir:
            confirmDialog(title='SORRY !',
                        message="Private directory not found !",
                        button=["OK"],
                        icon="critical")
            return

        privDir.showInExplorer(select=True)
    def setProject(self, *args, **kwargs):

        try:
            return self.browserWidget.setProject(*args, **kwargs)
        except Exception, err:
            confirmDialog(title='SORRY !'
                        , message=toStr(err)
                        , button=["OK"]
                        , defaultButton="OK"
                        , cancelButton="OK"
                        , dismissString="OK"
                        , icon="critical")

            if not hostApp():
                os.environ["PYTHONINSPECT"] = "1"

            self.close()

            raise
def showPathInExplorer(sPath, isFile=False, select=False):

    p = osp.normpath(sPath)

    if not osp.exists(p):

        sPathType = "file" if isFile else "directory"

        confirmDialog(title='SORRY !'
                    , message='No such {0} found: \n\n{1}'.format(sPathType, p)
                    , button=['OK']
                    , icon="critical")
        return False

    sCmd = "explorer /select, {0}" if isFile or select else "explorer {0}"
    sCmd = sCmd.format(p)
    subprocess.Popen(sCmd, shell=True)

    return True
def showPathInExplorer(sPath, isFile=False, select=False):

    p = osp.normpath(sPath)

    if not osp.exists(p):

        sPathType = "file" if isFile else "directory"

        confirmDialog(title='SORRY !',
                      message='No such {0} found: \n\n{1}'.format(
                          sPathType, p),
                      button=['OK'],
                      icon="critical")
        return False

    sCmd = "explorer /select, {0}" if isFile or select else "explorer {0}"
    sCmd = sCmd.format(p)
    subprocess.Popen(sCmd, shell=True)

    return True
Beispiel #14
0
    def _checkLibraryPaths(self, noError=False):

        sMissingPathList = []

        sSamePathDct = {}

        for sSpace, sLibSection in self._iterLibrariesSpaceAndSection():

            sLibFullName = DrcLibrary.makeFullName(sSpace, sLibSection)
            sLibPath = self.getPath(sSpace, sLibSection)

            sSamePathDct.setdefault(normCase(sLibPath), []).append(sLibFullName)

            if not osp.isdir(sLibPath):

                if sSpace == "public":
                    msg = u"No such '{}': '{}'.".format(sLibFullName, sLibPath)
                    if noError:
                        logMsg(msg, warning=True)
                    else:
                        raise EnvironmentError(msg)
                elif sSpace == "private":
                    sMissingPathList.append((sLibFullName, sLibPath))

        sSamePathList = tuple((p, libs) for p, libs in sSamePathDct.iteritems() if len(libs) > 1)
        if sSamePathList:
            msgIter = (u"'{}': {}".format(p, libs) for p, libs in sSamePathList)
            msg = u"Libraries using the same path:\n\n    " + u"\n    ".join(msgIter)
            raise EnvironmentError(msg)

        if sMissingPathList:

            msgIter = (u"'{}': '{}'".format(n, p) for n, p in sMissingPathList)
            msg = u"No such libraries:\n" + u"\n".join(msgIter)

            sConfirm = confirmDialog(title='WARNING !',
                                     message=msg + u"\n\nShould I create them ?",
                                     button=['Yes', 'No'],
                                     defaultButton='No',
                                     cancelButton='No',
                                     dismissString='No',
                                     icon="warning")

            if sConfirm == 'No':
                return False

            for _, p in sMissingPathList:
                os.makedirs(p)

        return True
Beispiel #15
0
    def removeItems(self, *itemList):

        entryList = tuple(item._metaobj for item in itemList)

        sEntryList = "\n    " .join(entry.name for entry in entryList)

        sMsg = u'Are you sure you want to DELETE these resources: \n\n    ' + sEntryList

        sConfirm = confirmDialog(title='WARNING !',
                                 message=sMsg,
                                 button=['OK', 'Cancel'],
                                 defaultButton='Cancel',
                                 cancelButton='Cancel',
                                 dismissString='Cancel',
                                 icon="warning")

        if sConfirm == 'Cancel':
            logMsg("Cancelled !", warning=True)
            return

        if len(entryList) > 1:
            for entry in entryList:

                try:
                    entry.sendToTrash()
                except Exception, e:
                    sResult = confirmDialog(title='SORRY !',
                                            message=toStr(e),
                                            button=["Continue", "Abort"],
                                            defaultButton="Continue",
                                            cancelButton="Abort",
                                            dismissString="Abort",
                                            icon="critical")
                    if sResult == "Abort":
                        return
                    else:
                        continue
Beispiel #16
0
    def showLocation(self, *itemList):
        item = itemList[-1]
        drcEntry = item._metaobj

        if drcEntry.isPublic():
            sMsg = u"Go to PUBLIC location of {} !?".format(drcEntry.name)
            sConfirm = confirmDialog(title='WARNING !',
                                     message=sMsg,
                                     button=['OK', 'Cancel'],
                                     defaultButton='Cancel',
                                     cancelButton='Cancel',
                                     dismissString='Cancel',
                                     icon="warning")

            if sConfirm == 'Cancel':
                logMsg("Cancelled !", warning=True)
                return

        drcEntry.showInExplorer(select=True)
Beispiel #17
0
    def rollBackToVersion(self, *itemList):

        item = itemList[-1]
        drcFile = item._metaobj
        drcFile.refresh()

        v = drcFile.currentVersion - 1

        sMsg = u"Restore version {} of '{}' ??".format(v, drcFile.name)

        sConfirm = confirmDialog(title='WARNING !',
                                 message=sMsg,
                                 button=['OK', 'Cancel'],
                                 defaultButton='Cancel',
                                 cancelButton='Cancel',
                                 dismissString='Cancel',
                                 icon="warning")

        if sConfirm == 'Cancel':
            logMsg("Cancelled !", warning=True)
            return

        drcFile.rollBackToVersion(v)
Beispiel #18
0
    def importFiles(self, *itemList):

        if not hostApp():
            raise AssertionError("You can only import from inside another application.")

        drcFileList = tuple(item._metaobj for item in itemList)

        if len(drcFileList) > 1:
            for drcFile in drcFileList:

                try:
                    drcFile.importIt()
                except Exception, e:
                    sResult = confirmDialog(title='SORRY !',
                                            message=toStr(e),
                                            button=["Continue", "Abort"],
                                            defaultButton="Continue",
                                            cancelButton="Abort",
                                            dismissString="Abort",
                                            icon="critical")
                    if sResult == "Abort":
                        return
                    else:
                        continue
def launch(rootDirList, update=False, dryRun=True, project="", dialogParent=None):

    global TREE_ITEM_DCT
    TREE_ITEM_DCT = {}

    app = qtGuiApp()
    if not app:
        app = QtGui.QApplication(sys.argv)

    proj = initProject(project)

    dlg = QuickTreeDialog(dialogParent)
    treeWdg = dlg.treeWidget
    treeWdg.setHeaderLabels(("Entity Name", "Infos"))

    missingPathItems = listMissingPathItems(rootDirList, update=update)

    badEntityList = []
    treeDataList = []
    for damEntity, sMissingPaths in missingPathItems:

        if isinstance(damEntity, basestring):
            p = pathJoin("Errors", damEntity)
            badEntityList.append({"path":p, "texts":[damEntity, sMissingPaths],
                                  "flags":Qt.ItemIsEnabled,
                                  "roles":{Qt.ForegroundRole:(1, QtGui.QBrush(Qt.red))}
                                })
            continue

        drcLib = proj.getLibrary("public", damEntity.libraryName)
        sLibPath = drcLib.absPath()
        sEntityTitle = damEntity.sgEntityType + 's'

        sEntityPath = damEntity.getPath("public")
        sEntiTreePath = re.sub("^" + sLibPath, sEntityTitle, sEntityPath)

        roleData = {Qt.UserRole:(0, damEntity)}
        treeDataList.append({"path":sEntiTreePath, "flags":None, "roles":roleData})

        sTreePathList = tuple(re.sub("^" + sLibPath, sEntityTitle, p)
                              for p in sMissingPaths)

        tree = OrderedTree.fromPaths(sTreePathList)

        for sTreePath in tree.iterPaths(rootPath=sEntiTreePath):
            treeDataList.append({"path":sTreePath, "flags":Qt.NoItemFlags})

    treeWdg.createTree(badEntityList)

    treeWdg.defaultFlags |= Qt.ItemIsTristate
    treeWdg.defaultRoles = {Qt.CheckStateRole:(0, Qt.Unchecked)}
    treeWdg.createTree(treeDataList)

    topItemCount = treeWdg.topLevelItemCount()
    if topItemCount == 1:
        curItem = treeWdg.topLevelItem(0)
        treeWdg.setRootIndex(treeWdg.indexFromItem(curItem))
        while curItem.childCount() == 1:
            curItem = curItem.child(0)
            curItem.setExpanded(True)
    else:
        for i in xrange(topItemCount):
            treeWdg.topLevelItem(i).setExpanded(True)

    dlg.show()

    while True:

        bOk = dlg.exec_()
        if not bOk:
            return

        bApply = False

        flags = (QTreeWidgetItemIterator.Checked | QTreeWidgetItemIterator.Enabled)
        treeIter = QTreeWidgetItemIterator(treeWdg, flags)
        damEntities = tuple(it.value().data(0, Qt.UserRole) for it in treeIter)
        damAssets = tuple(e for e in damEntities if isinstance(e, DamAsset))
        damShots = tuple(e for e in damEntities if isinstance(e, DamShot))
        if damAssets or damShots:

            sMsg = "Create directories and files for:\n"
            if damAssets:
                sMsg += "\n     - {} Assets".format(len(damAssets))

            if damShots:
                sMsg += "\n     - {} Shots".format(len(damShots))

            sConfirm = confirmDialog(title="WARNING !",
                                     message=sMsg,
                                     button=("Yes", "No"),
                                     defaultButton="No",
                                     cancelButton="No",
                                     dismissString="No",
                                     icon="warning",
                                    )

            if sConfirm == "Yes":
                bApply = True
                break

    if bApply:

        entityDirList = len(damEntities) * [None]

        for i, damEntity in enumerate(damEntities):
            if not damEntity:
                continue
            damEntity.createDirsAndFiles(dryRun=dryRun, checkDb=False)
            entityDirList[i] = damEntity.getResource("public", "entity_dir")

        for drcDir in entityDirList:
            if drcDir:
                drcDir.setSyncRules(drcDir.syncRules)
def launch(dryRun=True, project=""):

    app = qtGuiApp()
    if not app:
        app = QtGui.QApplication(sys.argv)

    sProject = os.environ["DAVOS_INIT_PROJECT"] if not project else project
    proj = DamProject(sProject)
    print sProject.center(80, "-")

    dbNodeDct = {}

    sFieldSet = set()

    print "Querying all dbnodes..."
    dbNodeList = proj.findDbNodes()
    print "Got {} dbnodes.".format(len(dbNodeList))

    for dbnode in dbNodeList:
        sFieldSet.update(dbnode._data.iterkeys())
        dbNodeDct.setdefault(dbnode.file.lower(), []).append(dbnode)

    dlg = QuickTreeDialog()
    treeWdg = dlg.treeWidget

    sFieldList = sorted(sFieldSet)
    sFieldList.remove("file")
    sFieldList.remove("#parent")
    sFieldList.insert(0, "file")

    treeWdg.setHeaderLabels(sFieldList)
    treeWdg.setTextElideMode(Qt.ElideLeft)

    topLevelItemDct = {}
    for sDbPath, nodes in dbNodeDct.iteritems():
        x = len(nodes)
        if x > 1:
            nodes = sorted(nodes, key=lambda n:int(n.time) * .001, reverse=True)

            if sDbPath not in topLevelItemDct:
                topItem = TreeItem(treeWdg, [sDbPath])
                topLevelItemDct[sDbPath] = topItem
            else:
                topItem = topLevelItemDct[sDbPath]

            for n in nodes:
                sTime = (datetime.fromtimestamp(int(n.time) / 1000)
                      .strftime(u"%Y-%m-%d %H:%M"))
                n._data["time"] = sTime

                itemData = tuple(toUnicode(n._data.get(f, "")) for f in sFieldList)
                print itemData[0]
                item = TreeItem(topItem, itemData)
                item.setCheckState(0, Qt.Unchecked)
                item.setData(0, Qt.UserRole, n)

    treeWdg.expandAll()
    for c in xrange(treeWdg.columnCount()):
        treeWdg.resizeColumnToContents(c)

    bOk = dlg.exec_()
    if not bOk:
        return

    itemIter = QTreeWidgetItemIterator(treeWdg, QTreeWidgetItemIterator.Checked)
    toDeleteNodes = [item.value().data(0, Qt.UserRole) for item in itemIter]
    if toDeleteNodes:
        sMsg = "Delete these {} Db nodes ???".format(len(toDeleteNodes))
        sConfirm = confirmDialog(title="WARNING !",
                                 message=sMsg,
                                 button=("Yes", "No"),
                                 defaultButton="No",
                                 cancelButton="No",
                                 dismissString="No",
                                 icon="warning",
                                )

        if sConfirm == "Yes":
            for n in toDeleteNodes:
                print "Deleting", n.file, n._data
                if not dryRun:
                    n.delete()
Beispiel #21
0
class BaseContextMenu(QtGui.QMenu):

    beforeActionLaunched = QtCore.Signal(dict, bool)
    afterActionLaunched = QtCore.Signal(dict, bool)

    def __init__(self, parentView):
        super(BaseContextMenu, self).__init__(parentView)

        self.view = parentView
        self.actionTargets = []
        self.actionTargetsLoaded = False

        self.createActions()
        self.buildSubmenus()

        self.installEventFilter(parentView)

    def model(self):

        model = self.view.model()
        if isinstance(model, QtGui.QSortFilterProxyModel):
            return model.sourceModel()

        return model

    def getActionTargets(self):

        view = self.view
        model = view.model()
        selectModel = view.selectionModel()

        selBhv = view.selectionBehavior()
        if selBhv == SelectionBehavior.SelectRows:
            selIndexes = selectModel.selectedRows(0)
        elif selBhv == SelectionBehavior.SelectColumns:
            selIndexes = selectModel.selectedColumns(0)
        else:
            selIndexes = selectModel.selectedIndexes()

        if len(selIndexes) > 1:

            curIndex = selectModel.currentIndex()

            if selBhv == SelectionBehavior.SelectRows:
                curIndex = curIndex.sibling(curIndex.row(), 0)
            elif selBhv == SelectionBehavior.SelectColumns:
                curIndex = curIndex.sibling(0, curIndex.column())

            if curIndex.isValid() and curIndex != selIndexes[-1]:

                try:
                    selIndexes.remove(curIndex)
                except ValueError:
                    pass

                selIndexes.append(curIndex)

        itemFromIndex = model.itemFromIndex
        return [itemFromIndex(idx) for idx in selIndexes]

    def loadActionTargets(self):

        self.actionTargets = self.getActionTargets()
        self.actionTargetsLoaded = True

    def assertActionTargets(self):

        if not self.actionTargetsLoaded:
            raise RuntimeError("Action Selection not loaded.")
        else:
            self.actionTargetsLoaded = False

    def launchAction(self, actionDct, checked):

        bCheckable = actionDct.get("checkable", False)

        self.beforeActionLaunched.emit(actionDct, checked)

        if not bCheckable:
            self.assertActionTargets()

        if not bCheckable:
            sActionMsg = u"Action: {} > {}".format(actionDct["menu"],
                                                   actionDct["label"])
            try:
                logMsg(u'# Action: {} #'.format(sActionMsg))
            except Exception, e:
                logMsg(e, warning=True)

        args = actionDct.get("args", []) + self.actionTargets
        kwargs = actionDct.get("kwargs", {})
        if bCheckable:
            kwargs.update(checked=checked)
        func = actionDct["fnc"]

        try:
            return func(*args, **kwargs)
        except Warning:
            raise
        except Exception as err:
            sMsg = u"{}\n\n".format(sActionMsg)
            confirmDialog(title='SORRY !',
                          message=(toStr(sMsg) + toStr(err)),
                          button=["OK"],
                          defaultButton="OK",
                          cancelButton="OK",
                          dismissString="OK",
                          icon="critical")
            raise

        self.afterActionLaunched.emit(actionDct, checked)
Beispiel #22
0
def launch_old(entityType="", dryRun=True, project="", dialogParent=None):

    global TREE_ITEM_DCT
    TREE_ITEM_DCT = {}

    app = qtGuiApp()
    if not app:
        app = QtGui.QApplication(sys.argv)

    sProject = os.environ["DAVOS_INIT_PROJECT"] if not project else project
    proj = DamProject(sProject)
    print sProject.center(80, "-")

    dlg = QuickTreeDialog(dialogParent)
    treeWdg = dlg.treeWidget
    treeWdg.setHeaderLabels(("Entity Name", "Infos"))

    dlg.show()

    missingPathItems = listMissingPathItems(proj, entityType)

    badEntityItems = []
    for damEntity, sMissingPaths in missingPathItems:

        if isinstance(damEntity, basestring):
            badEntityItems.append((damEntity, sMissingPaths))
            continue

        drcLib = proj.getLibrary("public", damEntity.libraryName)
        sLibPath = drcLib.absPath()
        sEntityTitle = damEntity.sgEntityType + 's'

        sEntityPath = damEntity.getPath("public")
        sEntityPath = re.sub("^" + sLibPath, sEntityTitle, sEntityPath)
        sEntityPathDirs = pathSplitDirs(sEntityPath)

        for sAbsPath in sMissingPaths:

            sTreePath = re.sub("^" + sLibPath, sEntityTitle, sAbsPath)

            sParentPath, sFilename = osp.split(pathNorm(sTreePath))
            parentItem = TREE_ITEM_DCT.get(sParentPath)
            if not parentItem:
                sDirList = pathSplitDirs(sParentPath)
                curParentItem = treeWdg
                for i, sDirName in enumerate(sDirList):
                    if i == 0:
                        sItemPath = sDirName
                    else:
                        sItemPath = pathJoin(*sDirList[:i + 1])

                    item = TREE_ITEM_DCT.get(sItemPath)
                    if not item:
                        flags = None
                        if sItemPath.startswith(sEntityPath):
                            if len(pathSplitDirs(sItemPath)) > len(sEntityPathDirs):
                                flags = Qt.NoItemFlags

                        userData = None
                        if sItemPath == sEntityPath:
                            userData = damEntity

                        item = loadTreeItem(curParentItem, sItemPath, [sDirName],
                                            flags=flags, userData=userData)

                    curParentItem = item

                parentItem = curParentItem

            flags = None
            if sTreePath.startswith(sEntityPath):
                if len(pathSplitDirs(sTreePath)) > len(sEntityPathDirs):
                    flags = Qt.NoItemFlags

            userData = None
            if sTreePath == sEntityPath:
                userData = damEntity

            loadTreeItem(parentItem, sTreePath, [sFilename], flags=flags, userData=userData)


    if badEntityItems:

        errorsItem = loadTreeItem(None, "Errors", ["ERRORS"])
        treeWdg.insertTopLevelItem(0, errorsItem)

        for sEntityName, sError in badEntityItems:
            loadTreeItem(errorsItem, sEntityName, [sEntityName, sError],
                         checkable=False)

    for i in xrange(treeWdg.topLevelItemCount()):
        treeWdg.topLevelItem(i).setExpanded(True)

    while True:

        bOk = dlg.exec_()
        if not bOk:
            return

        bApply = False

        flags = (QTreeWidgetItemIterator.Checked | QTreeWidgetItemIterator.Enabled)
        treeIter = QTreeWidgetItemIterator(treeWdg, flags)
        damEntities = tuple(it.value().data(0, Qt.UserRole) for it in treeIter)
        damAssets = tuple(e for e in damEntities if isinstance(e, DamAsset))
        damShots = tuple(e for e in damEntities if isinstance(e, DamShot))
        if damAssets or damShots:

            sMsg = "Create directories and files for:\n"
            if damAssets:
                sMsg += "\n     - {} Assets".format(len(damAssets))

            if damShots:
                sMsg += "\n     - {} Shots".format(len(damShots))

            sConfirm = confirmDialog(title="WARNING !",
                                     message=sMsg,
                                     button=("Yes", "No"),
                                     defaultButton="No",
                                     cancelButton="No",
                                     dismissString="No",
                                     icon="warning",
                                    )

            if sConfirm == "Yes":
                bApply = True
                break

    if bApply:
        for damEntity in damEntities:
            if not damEntity:
                continue
            damEntity.createDirsAndFiles(dryRun=dryRun)