Exemple #1
0
class SupportManager(PrymatexComponent, SupportBaseManager, QtCore.QObject):
    #Signals for bundle
    bundleAdded = QtCore.Signal(object)
    bundleRemoved = QtCore.Signal(object)
    bundleChanged = QtCore.Signal(object)
    bundlePopulated = QtCore.Signal(object)

    #Signals for bundle items
    bundleItemAdded = QtCore.Signal(object)
    bundleItemRemoved = QtCore.Signal(object)
    bundleItemChanged = QtCore.Signal(object)
    bundleItemTriggered = QtCore.Signal(object)
    
    #Signals for themes
    themeAdded = QtCore.Signal(object)
    themeRemoved = QtCore.Signal(object)
    themeChanged = QtCore.Signal(object)
    
    #Settings
    shellVariables = ConfigurableItem(default = [], tm_name = 'OakShelVariables')
    
    @ConfigurableItem(default = [], tm_name = 'OakBundleManagerDeletedBundles')
    def deleted(self, deleted):
        self.deletedObjects = [uuidmodule.UUID(uuid) for uuid in deleted]
        
    @ConfigurableItem(default = [], tm_name = 'OakBundleManagerDeletedBundles')
    def disabled(self, disabled):
        self.disabledObjects = [uuidmodule.UUID(uuid) for uuid in disabled]
    
    #http://manual.macromates.com/en/expert_preferences.html
    #When you create a new item in the bundle editor without having selected a bundle first, then the bundle with the UUID held by this defaults key is used as the target
    defaultBundleForNewBundleItems = ConfigurableItem(default = 'B7BC3FFD-6E4B-11D9-91AF-000D93589AF6', tm_name = 'OakDefaultBundleForNewBundleItems')
        
    SETTINGS_GROUP = 'SupportManager'
    
    def __init__(self, **kwargs):
        super(SupportManager, self).__init__(**kwargs)

        self.bundleTreeModel = BundleItemTreeModel(self)
        self.themeStylesTableModel = ThemeStylesTableModel(self)
        self.processTableModel = ExternalProcessTableModel(self)
        
        #STYLE PROXY
        self.themeStyleProxyModel = ThemeStyleProxyTableModel(self)
        self.themeStyleProxyModel.setSourceModel(self.themeStylesTableModel)

        #TREE PROXY
        self.bundleProxyTreeModel = BundleItemProxyTreeModel(self)
        self.bundleProxyTreeModel.setSourceModel(self.bundleTreeModel)

        #BUNDLES
        self.bundleProxyModel = BundleListModel(self)
        self.bundleProxyModel.setSourceModel(self.bundleTreeModel)
        
        #TEMPLATES
        self.templateProxyModel = TemplateListModel(self)
        self.templateProxyModel.setSourceModel(self.bundleTreeModel)
        
        #PROJECTS
        self.projectProxyModel = ProjectListModel(self)
        self.projectProxyModel.setSourceModel(self.bundleTreeModel)

        #SYNTAX
        self.syntaxProxyModel = SyntaxListModel(self)
        self.syntaxProxyModel.setSourceModel(self.bundleTreeModel)
        
        #INTERACTIVEITEMS
        self.actionItemsProxyModel = BundleItemTypeProxyModel(["command", "snippet", "macro"], self)
        self.actionItemsProxyModel.setSourceModel(self.bundleTreeModel)
        
        #PREFERENCES
        self.preferenceProxyModel = BundleItemTypeProxyModel("preference", self)
        self.preferenceProxyModel.setSourceModel(self.bundleTreeModel)
        
        #DRAGCOMMANDS
        self.dragcommandProxyModel = BundleItemTypeProxyModel("dragcommand", self)
        self.dragcommandProxyModel.setSourceModel(self.bundleTreeModel)
        
        #THEMES
        self.themeProxyModel = BundleItemTypeProxyModel("theme", self)
        self.themeProxyModel.setSourceModel(self.bundleTreeModel)
        
        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)

    @classmethod
    def contributeToSettings(cls):
        from prymatex.gui.settings.environment import VariablesSettingsWidget
        return [ VariablesSettingsWidget ]

    def setEditorAvailable(self, available):
        self.editorAvailable = available

    def appendMenuToBundleMenuGroup(self, menu, offset = None):
        self.bundleMenuGroup.appendMenu(menu, offset)

    def menuForBundle(self, bundle):
        return self.bundleMenuGroup.menuForBundle(bundle)

    # Override buildPlistFileStorage for custom storage
    def buildPlistFileStorage(self):
        return self.application.storageManager.singleFileStorage("support-plist")
        
    def buildBundleItemStorage(self):
        return SupportBaseManager.buildBundleItemStorage(self)
        
    #---------------------------------------------------
    # Environment
    #---------------------------------------------------
    def environmentVariables(self):
        environment = SupportBaseManager.environmentVariables(self)
        #Extend wiht the user shell variables
        for var in self.shellVariables:
            if var['enabled']:
                environment[var['variable']] = var['value']
        return environment

    # Override loadSupport for emit signals
    def loadSupport(self, *largs, **kwargs):
        self.bundleProxyTreeModel.setDynamicSortFilter(True)
        SupportBaseManager.loadSupport(self, *largs, **kwargs)
        #self.bundleProxyTreeModel.sort(0, QtCore.Qt.AscendingOrder)

    def runSystemCommand(self, **attrs):
        if attrs.get("asynchronous", False):
            return self.runQtProcessCommand(**attrs)
        else:
            return SupportBaseManager.runSystemCommand(self, **attrs)
            
    #Interface
    def runQtProcessCommand(self, **attrs):
        context = RunningContext(**attrs)
        
        context.process = QtCore.QProcess(self)
        if context.workingDirectory is not None:
            context.process.setWorkingDirectory(context.workingDirectory)
            
        self.processTableModel.appendProcess(context.process, description = context.description())

        environment = QtCore.QProcessEnvironment()
        for key, value in context.scriptFileEnvironment.items():
            environment.insert(key, value)

        context.process.setProcessEnvironment(environment)

        def onQProcessFinished(context):
            def _finished(exitCode, exitStatus):
                self.processTableModel.removeProcess(context.process)
                errorValue = qbytearray_to_text(
                    context.process.readAllStandardError())
                context.errorValue = encoding.from_fs(errorValue)
                outputValue = qbytearray_to_text(
                    context.process.readAllStandardOutput())
                context.outputValue = encoding.from_fs(outputValue)
                context.outputType = exitCode
                context.callback(context)
            return _finished

        context.process.finished[int, QtCore.QProcess.ExitStatus].connect(
            onQProcessFinished(context)
        )
        
        def onQProcessStarted(context):
            def _started():
                if context.inputValue is not None:
                    context.process.write(encoding.to_fs(context.inputValue))
                context.process.closeWriteChannel()
            return _started
        
        context.process.started.connect(onQProcessStarted(context))
        
        context.process.start(context.scriptFilePath)
        
        return context

    def buildAdHocCommand(self, *largs, **kwargs):
        return BundleItemTreeNode(SupportBaseManager.buildAdHocCommand(self, *largs, **kwargs))

    def buildAdHocSnippet(self, *largs, **kwargs):
        return BundleItemTreeNode(SupportBaseManager.buildAdHocSnippet(self, *largs, **kwargs))

    #---------------------------------------------------
    # MANAGED OBJECTS OVERRIDE INTERFACE
    #---------------------------------------------------
    def setDeleted(self, uuid):
        """
        Marcar un managed object como eliminado
        """
        self.deletedObjects.append(uuid)
        deleted = [str(uuid).upper() for uuid in self.deletedObjects]
        self.settings.setValue('deleted', deleted)

    def isDeleted(self, uuid):
        return uuid in self.deletedObjects

    def isEnabled(self, uuid):
        return uuid not in self.disabledObjects
    
    def setDisabled(self, uuid):
        self.disabledObjects.append(uuid)
        disabled = [str(uuid).upper() for uuid in self.disabledObjects]
        self.settings.setValue('disabled', disabled)
        
    def setEnabled(self, uuid):
        self.disabledObjects.remove(uuid)
        disabled = [str(uuid).upper() for uuid in self.disabledObjects]
        self.settings.setValue('disabled', disabled)
    
    #---------------------------------------------------
    # BUNDLE OVERRIDE INTERFACE 
    #---------------------------------------------------
    def addBundle(self, bundle):
        bundleNode = BundleItemTreeNode(bundle)
        self.bundleTreeModel.appendBundle(bundleNode)
        self.bundleAdded.emit(bundleNode)
        return bundleNode
    
    def modifyBundle(self, bundle):
        self.bundleChanged.emit(bundle)
    
    def removeBundle(self, bundle):
        self.bundleTreeModel.removeBundle(bundle)
        self.bundleRemoved.emit(bundle)
    
    def getAllBundles(self):
        return self.bundleProxyModel.nodes()
    
    def getDefaultBundle(self):
        return self.getBundle(self.defaultBundleForNewBundleItems)
    
    def populatedBundle(self, bundle):
        self.bundlePopulated.emit(bundle)
        
    #---------------------------------------------------
    # BUNDLEITEM OVERRIDE INTERFACE 
    #---------------------------------------------------
    def addBundleItem(self, bundleItem):
        bundleItemNode = BundleItemTreeNode(bundleItem)
        self.bundleTreeModel.appendBundleItem(bundleItemNode)
        self.bundleItemAdded.emit(bundleItemNode)
        return bundleItemNode

    def modifyBundleItem(self, bundleItem):
        self.bundleItemChanged.emit(bundleItem)
        
    def removeBundleItem(self, bundleItem):
        self.bundleTreeModel.removeBundleItem(bundleItem)
        self.bundleItemRemoved.emit(bundleItem)
        
    def getAllBundleItems(self):
        nodes = []
        for bundle in self.getAllBundles():
            for node in bundle.childNodes():
                nodes.append(node)
        return nodes
        
    #---------------------------------------------------
    # STATICFILE OVERRIDE INTERFACE
    #---------------------------------------------------
    def addStaticFile(self, staticFile):
        bundleStaticFileNode = BundleItemTreeNode(staticFile)
        self.bundleTreeModel.appendStaticFile(bundleStaticFileNode)
        return bundleStaticFileNode
    
    def removeStaticFile(self, file):
        pass
    
    #---------------------------------------------------
    # THEME STYLE OVERRIDE INTERFACE
    #---------------------------------------------------
    def addThemeStyle(self, style):
        themeStyle = ThemeStyleTableRow(style)
        self.themeStylesTableModel.appendStyle(themeStyle)
        return themeStyle
    
    def removeThemeStyle(self, style):
        self.themeStylesTableModel.removeStyle(style)

    #---------------------------------------------------
    # PREFERENCES OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllPreferences(self):
        memoizedKey = ("getAllPreferences", None, None, None)
        if memoizedKey in self.bundleItemCache:
            return self.bundleItemCache.get(memoizedKey)
        return self.bundleItemCache.setdefault(memoizedKey,
            list(self.preferenceProxyModel.nodes()))

    #---------------------------------------------------
    # TABTRIGGERS OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllTabTriggerItems(self):
        memoizedKey = ("getAllTabTriggerItems", None, None, None)
        if memoizedKey in self.bundleItemCache:
            return self.bundleItemCache.get(memoizedKey)
        tabTriggers = []
        for item in self.actionItemsProxyModel.nodes():
            if item.tabTrigger is not None:
                tabTriggers.append(item)
        return self.bundleItemCache.setdefault(memoizedKey,
            tabTriggers)
        
    def getAllBundleItemsByTabTrigger(self, tabTrigger):
        memoizedKey = ("getAllBundleItemsByTabTrigger", tabTrigger, None, None)
        if memoizedKey in self.bundleItemCache:
            return self.bundleItemCache.get(memoizedKey)
        items = []
        for item in self.actionItemsProxyModel.nodes():
            if item.tabTrigger == tabTrigger:
                items.append(item)
        return self.bundleItemCache.setdefault(memoizedKey,
            items)

    #---------------------------------------------------
    # KEYEQUIVALENT OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllKeyEquivalentItems(self):
        memoizedKey = ("getAllBundleItemsByTabTrigger", None, None, None)
        if memoizedKey in self.bundleItemCache:
            return self.bundleItemCache[memoizedKey]
        keyCode = []
        for item in self.actionItemsProxyModel.nodes():
            if item.keyCode() is not None:
                keyCode.append(item)
        for item in self.syntaxProxyModel.nodes():
            if item.keyCode() is not None:
                keyCode.append(item)
        return self.bundleItemCache.setdefault(memoizedKey,
            keyCode)
        
    def getAllBundleItemsByKeyEquivalent(self, keyCode):
        memoizedKey = ("getAllBundleItemsByKeyEquivalent", keyCode, None, None)
        if memoizedKey in self.bundleItemCache:
            return self.bundleItemCache.get(memoizedKey)
        items = []
        for item in self.actionItemsProxyModel.nodes():
            if item.keyCode() == keyCode:
                items.append(item)
        for syntax in self.syntaxProxyModel.nodes():
            if syntax.keyCode() == keyCode:
                items.append(syntax)
        return self.bundleItemCache.setdefault(memoizedKey,
            items)
    
    #---------------------------------------------------
    # FILE EXTENSION OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllBundleItemsByFileExtension(self, path):
        items = []
        for item in self.dragcommandProxyModel.nodes():
            if any([fnmatch.fnmatch(path, "*.%s" % extension) for extension in item.draggedFileExtensions]):
                items.append(item)
        return items
    
    #---------------------------------------------------
    # ACTION ITEMS OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllActionItems(self):
        return self.actionItemsProxyModel.nodes()
    
    #---------------------------------------------------
    # SYNTAXES OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllSyntaxes(self):
        return self.syntaxProxyModel.nodes()