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)
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)
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
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()
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)
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
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
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
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)
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)
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()
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)
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)