Пример #1
0
    def __init__(self, application):
        QtCore.QObject.__init__(self)
        PMXSupportBaseManager.__init__(self)
        self.application = application
        self.bundleTreeModel = BundleItemTreeModel(self)
        self.themeListModel = ThemeListModel(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)

        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)
Пример #2
0
    def __init__(self, **kwargs):
        super(SupportManager, self).__init__(**kwargs)

        self.bundleModel = BundleTreeModel(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.bundleModel)

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

        #SYNTAX
        self.syntaxProxyModel = SyntaxListModel(self)
        self.syntaxProxyModel.setSourceModel(self.bundleModel)
        
        #INTERACTIVEITEMS
        self.actionItemsProxyModel = BundleItemTypeListModel(("command", "snippet", "macro"), self)
        self.actionItemsProxyModel.setSourceModel(self.bundleModel)
        
        #PREFERENCES
        self.preferenceProxyModel = BundleItemTypeListModel(("preference", ), self)
        self.preferenceProxyModel.setSourceModel(self.bundleModel)
        
        #DRAGCOMMANDS
        self.dragcommandProxyModel = BundleItemTypeListModel(("dragcommand", ), self)
        self.dragcommandProxyModel.setSourceModel(self.bundleModel)
        
        #THEMES
        self.themeProxyModel = BundleItemTypeListModel(("theme", ), self)
        self.themeProxyModel.setSourceModel(self.bundleModel)
        
        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)
        
        # File System Watcher
        self.fileSystemWatcher = QtCore.QFileSystemWatcher()
        self.fileSystemWatcher.directoryChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )
        self.fileSystemWatcher.fileChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )
Пример #3
0
    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)
Пример #4
0
class SupportManager(QtCore.QObject, PMXSupportBaseManager):
    #Signals for bundle
    bundleAdded = QtCore.pyqtSignal(object)
    bundleRemoved = QtCore.pyqtSignal(object)
    bundleChanged = QtCore.pyqtSignal(object)
    bundlePopulated = QtCore.pyqtSignal(object)

    #Signals for bundle items
    bundleItemAdded = QtCore.pyqtSignal(object)
    bundleItemRemoved = QtCore.pyqtSignal(object)
    bundleItemChanged = QtCore.pyqtSignal(object)
    bundleItemTriggered = QtCore.pyqtSignal(object)

    #Signals for themes
    themeAdded = QtCore.pyqtSignal(object)
    themeRemoved = QtCore.pyqtSignal(object)
    themeChanged = QtCore.pyqtSignal(object)

    #Settings
    shellVariables = pmxConfigPorperty(default=[], tm_name=u'OakShelVariables')

    @pmxConfigPorperty(default=[], tm_name=u'OakBundleManagerDeletedBundles')
    def deleted(self, deleted):
        self.deletedObjects = map(lambda uuid: uuidmodule.UUID(uuid), deleted)

    @pmxConfigPorperty(default=[], tm_name=u'OakBundleManagerDeletedBundles')
    def disabled(self, disabled):
        self.disabledObjects = map(lambda uuid: uuidmodule.UUID(uuid),
                                   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 = pmxConfigPorperty(
        default=u'B7BC3FFD-6E4B-11D9-91AF-000D93589AF6',
        tm_name=u'OakDefaultBundleForNewBundleItems')

    SETTINGS_GROUP = 'SupportManager'

    def __init__(self, application):
        QtCore.QObject.__init__(self)
        PMXSupportBaseManager.__init__(self)
        self.application = application
        self.bundleTreeModel = BundleItemTreeModel(self)
        self.themeListModel = ThemeListModel(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)

        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)

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

    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)

    #---------------------------------------------------
    # Environment
    #---------------------------------------------------
    def environmentVariables(self):
        environment = PMXSupportBaseManager.buildEnvironment(self)
        #Extend wiht the user shell variables
        for var in self.shellVariables:
            if var['enabled']:
                environment[var['variable']] = var['value']
        return environment

    def buildEnvironment(self, systemEnvironment=True):
        env = PMXSupportBaseManager.buildEnvironment(self, systemEnvironment)
        for var in self.shellVariables:
            if var['enabled']:
                env[var['variable']] = var['value']
        return env

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

    def runProcess(self, context, callback):
        if context.asynchronous:
            return self.runQProcess(context, callback)
        else:
            return PMXSupportBaseManager.runProcess(self, context, callback)

    #Interface
    def runQProcess(self, context, callback):
        process = QtCore.QProcess(self)
        if context.workingDirectory is not None:
            process.setWorkingDirectory(context.workingDirectory)

        self.processTableModel.appendProcess(process,
                                             description=context.description())

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

        process.setProcessEnvironment(environment)

        def onQProcessFinished(process, context, callback):
            def runCallback(exitCode):
                self.processTableModel.removeProcess(process)
                context.errorValue = str(
                    process.readAllStandardError()).decode("utf-8")
                context.outputValue = str(
                    process.readAllStandardOutput()).decode("utf-8")
                context.outputType = exitCode
                callback(context)

            return runCallback

        process.finished[int].connect(
            onQProcessFinished(process, context, callback))

        if context.inputType is not None:
            process.start(context.shellCommand, QtCore.QIODevice.ReadWrite)
            if not process.waitForStarted():
                raise Exception("No puedo correr")
            process.write(unicode(context.inputValue).encode("utf-8"))
            process.closeWriteChannel()
        else:
            process.start(context.shellCommand, QtCore.QIODevice.ReadOnly)

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

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

    #---------------------------------------------------
    # MANAGED OBJECTS OVERRIDE INTERFACE
    #---------------------------------------------------
    def setDeleted(self, uuid):
        """
        Marcar un managed object como eliminado
        """
        self.deletedObjects.append(uuid)
        deleted = map(lambda uuid: unicode(uuid).upper(), 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 = map(lambda uuid: unicode(uuid).upper(),
                       self.disabledObjects)
        self.settings.setValue('disabled', disabled)

    def setEnabled(self, uuid):
        self.disabledObjects.remove(uuid)
        disabled = map(lambda uuid: unicode(uuid).upper(),
                       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.getAllItems()

    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

    #---------------------------------------------------
    # TEMPLATEFILE OVERRIDE INTERFACE
    #---------------------------------------------------
    def addTemplateFile(self, file):
        bundleTemplateFileNode = BundleItemTreeNode(file)
        self.bundleTreeModel.appendTemplateFile(bundleTemplateFileNode)
        return bundleTemplateFileNode

    #---------------------------------------------------
    # THEME OVERRIDE INTERFACE
    #---------------------------------------------------
    def addTheme(self, theme):
        themeRow = ThemeStyleTableRow(theme, self.scores)
        self.themeListModel.appendTheme(themeRow)
        self.themeAdded.emit(themeRow)
        return themeRow

    def modifyTheme(self, theme):
        self.themeChanged.emit(theme)

    def removeTheme(self, theme):
        self.themeListModel.removeTheme(theme)
        self.themeRemoved.emit(theme)

    def getAllThemes(self):
        return self.themeListModel.getAllItems()

    #---------------------------------------------------
    # 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
    #---------------------------------------------------
    @dynamic_memoized
    def getAllPreferences(self):
        return self.preferenceProxyModel.getAllItems()

    #---------------------------------------------------
    # TABTRIGGERS OVERRIDE INTERFACE
    #---------------------------------------------------
    @dynamic_memoized
    def getAllTabTriggerItems(self):
        tabTriggers = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.tabTrigger != None:
                tabTriggers.append(item)
        return tabTriggers

    @dynamic_memoized
    def getAllBundleItemsByTabTrigger(self, tabTrigger):
        items = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.tabTrigger == tabTrigger:
                items.append(item)
        return items

    #---------------------------------------------------
    # KEYEQUIVALENT OVERRIDE INTERFACE
    #---------------------------------------------------
    @dynamic_memoized
    def getAllKeyEquivalentItems(self):
        keyEquivalent = []
        for item in self.actionItemsProxyModel.getAllItems(
        ) + self.syntaxProxyModel.getAllItems():
            if item.keyEquivalent != None:
                keyEquivalent.append(item)
        return keyEquivalent

    @dynamic_memoized
    def getAllBundleItemsByKeyEquivalent(self, keyEquivalent):
        items = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.keyEquivalent == keyEquivalent:
                items.append(item)
        for syntax in self.syntaxProxyModel.getAllItems():
            if syntax.keyEquivalent == keyEquivalent:
                items.append(syntax)
        return items

    #---------------------------------------------------
    # FILE EXTENSION OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllBundleItemsByFileExtension(self, path):
        items = []
        for item in self.dragcommandProxyModel.getAllItems():
            if any(
                    map(
                        lambda extension: fnmatch.fnmatch(
                            path, "*.%s" % extension),
                        item.draggedFileExtensions)):
                items.append(item)
        return items

    #---------------------------------------------------
    # ACTION ITEMS OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllActionItems(self):
        return self.actionItemsProxyModel.getAllItems()

    #---------------------------------------------------
    # SYNTAXES OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllSyntaxes(self):
        return self.syntaxProxyModel.getAllItems()
Пример #5
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()
Пример #6
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)
    
    # Signals for properties
    propertiesChanged = QtCore.Signal(str)
    
    # ------------- Settings
    shell_variables = ConfigurableItem(default=[], tm_name='OakShelVariables')
    
    # TODO: Mejores nombres por aca
    @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
    default_bundle_for_new_bundle_items = ConfigurableItem(default = 'B7BC3FFD-6E4B-11D9-91AF-000D93589AF6', tm_name = 'OakDefaultBundleForNewBundleItems')
    
    def __init__(self, **kwargs):
        super(SupportManager, self).__init__(**kwargs)

        self.bundleModel = BundleTreeModel(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.bundleModel)

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

        #SYNTAX
        self.syntaxProxyModel = SyntaxListModel(self)
        self.syntaxProxyModel.setSourceModel(self.bundleModel)
        
        #INTERACTIVEITEMS
        self.actionItemsProxyModel = BundleItemTypeListModel(("command", "snippet", "macro"), self)
        self.actionItemsProxyModel.setSourceModel(self.bundleModel)
        
        #PREFERENCES
        self.preferenceProxyModel = BundleItemTypeListModel(("preference", ), self)
        self.preferenceProxyModel.setSourceModel(self.bundleModel)
        
        #DRAGCOMMANDS
        self.dragcommandProxyModel = BundleItemTypeListModel(("dragcommand", ), self)
        self.dragcommandProxyModel.setSourceModel(self.bundleModel)
        
        #THEMES
        self.themeProxyModel = BundleItemTypeListModel(("theme", ), self)
        self.themeProxyModel.setSourceModel(self.bundleModel)
        
        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)
        
        # File System Watcher
        self.fileSystemWatcher = QtCore.QFileSystemWatcher()
        self.fileSystemWatcher.directoryChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )
        self.fileSystemWatcher.fileChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )

    @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: SupportManager.namespace
    def namespace(self, name):
        return self.application().namespace(name)

    # OVERRIDE: SupportManager.namespaces
    def namespaces(self):
        return self.application().namespaces()

    # OVERRIDE: SupportManager.protectedNamespace()
    def protectedNamespace(self):
        return self.application().protectedNamespace()
    
    # ------------------- Signals
    def on_fileSystemWatcher_pathChanged(self, path):
        directory = path if os.path.isdir(path) else os.path.dirname(path)
        if self.propertiesHasChanged(directory):
            self.logger().debug("Properties in %s has changed" % directory)
            remove = self.updateProperties(directory)
            self.fileSystemWatcher.removePath(remove)
            self.propertiesChanged.emit(directory)

    #---------------------------------------------------
    # Environment
    #---------------------------------------------------
    def environmentVariables(self):
        environment = SupportBaseManager.environmentVariables(self)
        #Extend wiht the user shell variables
        for var in self.shell_variables:
            if var['enabled']:
                environment[var['variable']] = var['value']
        return environment

    def loadSupport(self, message_handler):
        SupportBaseManager.loadSupport(self, message_handler)
        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 = context.process.readAllStandardError().data()
                context.errorValue = encoding.from_fs(
                    context.process.readAllStandardError().data()
                )
                context.outputValue = encoding.from_fs(
                    context.process.readAllStandardOutput().data()
                )
                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

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

    def isDeleted(self, uuid):
        if isinstance(uuid, uuidmodule.UUID):
            uuid = self.uuidtotext(uuid)
        return uuid in self.deletedObjects

    def isEnabled(self, uuid):
        if isinstance(uuid, uuidmodule.UUID):
            uuid = self.uuidtotext(uuid)
        return uuid not in self.disabledObjects
    
    def setDisabled(self, uuid):
        if isinstance(uuid, uuidmodule.UUID):
            uuid = self.uuidtotext(uuid)
        self.disabledObjects.append(uuid)
        disabled = [uuid for uuid in self.disabledObjects]
        self.settings().setValue('disabled', disabled)
        
    def setEnabled(self, uuid):
        if isinstance(uuid, uuidmodule.UUID):
            uuid = self.uuidtotext(uuid)
        self.disabledObjects.remove(uuid)
        disabled = [uuid for uuid in self.disabledObjects]
        self.settings().setValue('disabled', disabled)
    
    #--------------- MANAGED OBJECTS NODE INTERFACE
    def getManagedObjectNode(self, uuid):
        if isinstance(uuid, uuidmodule.UUID):
            uuid = self.uuidtotext(uuid)
        if not self.isDeleted(uuid):
            return self.bundleModel.findNode(QtCore.Qt.UUIDRole, uuid)

    # -------------------- BUNDLE INTERFACE 
    def onBundleAdded(self, bundle):
        bundle_node = BundleItemTreeNode(bundle)
        icon = self.resources().get_icon("bundle-item-%s" % bundle.type())
        bundle_node.setIcon(icon)
        self.bundleModel.appendBundle(bundle_node)
        self.bundleAdded.emit(bundle_node)
    
    def modifyBundle(self, bundle):
        self.bundleChanged.emit(bundle)
    
    def removeBundle(self, bundle):
        self.bundleModel.removeBundle(bundle)
        self.bundleRemoved.emit(bundle)
    
    def getDefaultBundle(self):
        return self.getManagedObjectNode(self.defaultBundleForNewBundleItems)
    
    def onBundlePopulated(self, bundle):
        bundle_node = self.getManagedObjectNode(bundle.uuid)
        if bundle_node is not None:
            self.bundlePopulated.emit(bundle_node)
        
    # --------------------------- BUNDLEITEM INTERFACE 
    def onBundleItemAdded(self, bundle_item):
        bundle_item_node = BundleItemTreeNode(bundle_item)
        bundle_node = self.getManagedObjectNode(bundle_item.bundle.uuid)
        icon = self.resources().get_icon("bundle-item-%s" % bundle_item.type())
        bundle_item_node.setIcon(icon)
        self.bundleModel.appendBundleItem(bundle_item_node, bundle_node)
        self.bundleItemAdded.emit(bundle_item_node)

    def onBundleItemModified(self, bundle_item):
        bundle_item_node = self.getManagedObjectNode(bundle_item.uuid)
        self.bundleItemChanged.emit(bundle_item_node)
        
    def onBundleItemRemoved(self, bundle_item):
        bundle_item_node = self.getManagedObjectNode(bundle_item.uuid)
        self.bundleModel.removeBundleItem(bundle_item_node)
        self.bundleItemRemoved.emit(bundle_item_node)
    
    # ----------------- THEME INTERFACE
    def getThemePalette(self, theme, scope=None):
        settings = self.getThemeSettings(theme, scope)
        palette = self.application().palette()
        if 'foreground' in settings:
            #QPalette::Foreground	0	This value is obsolete. Use WindowText instead.
            palette.setColor(QtGui.QPalette.Foreground, rgba2color(settings['background']))
            #QPalette::WindowText	0	A general foreground color.
            palette.setColor(QtGui.QPalette.WindowText, rgba2color(settings['foreground']))
            #QPalette::Text	6	The foreground color used with Base. This is usually the same as the WindowText, in which case it must provide good contrast with Window and Base.
            palette.setColor(QtGui.QPalette.Text, rgba2color(settings['foreground']))
            #QPalette::ToolTipText	19	Used as the foreground color for QToolTip and QWhatsThis. Tool tips use the Inactive color group of QPalette, because tool tips are not active windows.
            palette.setColor(QtGui.QPalette.ToolTipText, rgba2color(settings['foreground']))
            #QPalette::ButtonText	    8	A foreground color used with the Button color.
            palette.setColor(QtGui.QPalette.ButtonText, rgba2color(settings['foreground']))
        if 'background' in settings:
            #QPalette::Background	10	This value is obsolete. Use Window instead.
            palette.setColor(QtGui.QPalette.Background, rgba2color(settings['background']))
            #QPalette::Window	10	A general background color.
            palette.setColor(QtGui.QPalette.Window, rgba2color(settings['background']))
            #QPalette::Base	9	Used mostly as the background color for text entry widgets, but can also be used for other painting - such as the background of combobox drop down lists and toolbar handles. It is usually white or another light color.
            palette.setColor(QtGui.QPalette.Base, rgba2color(settings['background']))
            #QPalette::ToolTipBase	18	Used as the background color for QToolTip and QWhatsThis. Tool tips use the Inactive color group of QPalette, because tool tips are not active windows.
            palette.setColor(QtGui.QPalette.ToolTipBase, rgba2color(settings['background']))
            #QPalette::Button	    1	The general button background color. This background can be different from Window as some styles require a different background color for buttons.
            palette.setColor(QtGui.QPalette.Button, rgba2color(settings['background']))
        if 'selection' in settings:
            #QPalette::Highlight	12	A color to indicate a selected item or the current item. By default, the highlight color is Qt::darkBlue.
            palette.setColor(QtGui.QPalette.Highlight, rgba2color(settings['selection']))
        if 'invisibles' in settings:
            #QPalette::LinkVisited	15	A text color used for already visited hyperlinks. By default, the linkvisited color is Qt::magenta.
            palette.setColor(QtGui.QPalette.LinkVisited, rgba2color(settings['invisibles']))
        if 'lineHighlight' in settings:
            #QPalette::AlternateBase	16	Used as the alternate background color in views with alternating row colors (see QAbstractItemView::setAlternatingRowColors()).
            palette.setColor(QtGui.QPalette.AlternateBase, rgba2color(settings['lineHighlight']))
        if 'caret' in settings:
            #QPalette::BrightText	7	A text color that is very different from WindowText, and contrasts well with e.g. Dark. Typically used for text that needs to be drawn where Text or WindowText would give poor contrast, such as on pressed push buttons. Note that text colors can be used for things other than just words; text colors are usually used for text, but it's quite common to use the text color roles for lines, icons, etc.
            palette.setColor(QtGui.QPalette.BrightText, rgba2color(settings['caret']))
            #QPalette::HighlightedText	13	A text color that contrasts with Highlight. By default, the highlighted text color is Qt::white.
            palette.setColor(QtGui.QPalette.HighlightedText, rgba2color(settings['caret']))
        if 'gutterBackground' in settings and settings['gutterBackground'] != DEFAULT_THEME_SETTINGS['gutterBackground']:
            #QPalette::ToolTipBase	18	Used as the background color for QToolTip and QWhatsThis. Tool tips use the Inactive color group of QPalette, because tool tips are not active windows.
            palette.setColor(QtGui.QPalette.ToolTipBase, rgba2color(settings['gutterBackground']))
        if 'gutterForeground' in settings and settings['gutterForeground'] != DEFAULT_THEME_SETTINGS['gutterForeground']:
            #QPalette::ToolTipText	19	Used as the foreground color for QToolTip and QWhatsThis. Tool tips use the Inactive color group of QPalette, because tool tips are not active windows.
            palette.setColor(QtGui.QPalette.ToolTipText, rgba2color(settings['gutterForeground']))
        #QPalette::Link	14	A text color used for unvisited hyperlinks. By default, the link color is Qt::blue.
        return palette

    @memoize(key_function=lambda m, theme, scope=None: "%s-%s" % (str(theme.uuid), str(scope)))
    def getThemeTextCharFormat(self, theme, scope=None):
        settings = self.getThemeSettings(theme, scope)
        frmt = QtGui.QTextCharFormat()
        if 'foreground' in settings:
            frmt.setForeground(rgba2color(settings['foreground']))
        if 'background' in settings:
            frmt.setBackground(rgba2color(settings['background']))
        if 'fontStyle' in settings:
            if 'bold' in settings['fontStyle']:
                frmt.setFontWeight(QtGui.QFont.Bold)
            if 'underline' in settings['fontStyle']:
                frmt.setFontUnderline(True)
            if 'italic' in settings['fontStyle']:
                frmt.setFontItalic(True)
        return frmt

    # --------------- PROPERTIES OVERRIDE INTERFACE
    def addProperties(self, properties):
        watch = [ cfg.source.exists() and cfg.source.path or cfg.source.name for cfg in properties.configs]
        self.fileSystemWatcher.addPaths(watch)
        return properties
        
    # STATICFILE OVERRIDE INTERFACE
    def onStaticFileAdded(self, static_file):
        static_file_node = BundleItemTreeNode(static_file)
        bundle_item_node = self.getManagedObjectNode(static_file.parentItem.uuid)
        self.bundleModel.appendStaticFile(static_file_node, bundle_item_node)
    
    def removeStaticFile(self, file):
        pass

    @memoize(key_function=lambda m: "all-key-sequences")
    def getAllKeySequences(self):
        return [ keyequivalent_to_keysequence(mnemonic) for mnemonic in self.getAllKeyEquivalentMnemonic() ]

    def getKeySequenceItem(self, sequence, left_scope, right_scope):
        eq = keysequence_to_keyequivalent(sequence)
        print("seq", sequence.count(), "equivalente", type(eq), eq)
        return self.getKeyEquivalentItem(keysequence_to_keyequivalent(sequence), left_scope, right_scope)
        
    # THEME STYLE INTERFACE
    def getThemeStyleNode(self, uuid):
        indexes = self.themeStylesTableModel.match(self.bundleModel.index(0, 0, QtCore.QModelIndex()),
            QtCore.Qt.UUIDRole, uuid, 1, QtCore.Qt.MatchFixedString | QtCore.Qt.MatchRecursive)
        if indexes:
            return self.themeStylesTableModel.style(indexes[0])

    def onThemeStyleAdded(self, style):
        theme_style = ThemeStyleTableRow(style)
        self.themeStylesTableModel.appendStyle(theme_style)
        return style

    def removeThemeStyle(self, style):
        self.themeStylesTableModel.removeStyle(style)

    # ACTION NODES INTERFACE
    def getAllActionItemsNodes(self):
        return self.actionItemsProxyModel.nodes()
    
    # SYNTAXES INTERFACE
    def getAllSyntaxesNodes(self):
        return self.syntaxProxyModel.nodes()

    # CURSOR SCOPE
    def cursorScope(self, cursor):
        left_scope = self.scopeFactory("")
        right_scope = self.scopeFactory("")
        leftCursor = QtGui.QTextCursor(cursor)
        rightCursor = QtGui.QTextCursor(cursor)
        leftCursor.setPosition(cursor.selectionStart())
        rightCursor.setPosition(cursor.selectionEnd())
        if cursor.hasSelection():
            # If there is one or more selections: dyn.selection.
            # TODO If there is a single zero-width selection: dyn.caret.mixed.columnar.
            # TODO If there are multiple carets and/or selections: dyn.caret.mixed.
            left_scope.push_scope("dyn.selection")
            right_scope.push_scope("dyn.selection")
        # When there is only a single caret or a single continuous selection
        # the left scope may contain: dyn.caret.begin.line or dyn.caret.begin.document
        if leftCursor.atBlockStart():
            left_scope.push_scope("dyn.caret.begin.line")
        if leftCursor.atStart():
            left_scope.push_scope("dyn.caret.begin.document")
        # Likewise the right scope may contain: dyn.caret.end.line or dyn.caret.end.document.
        if rightCursor.atBlockEnd():
            right_scope.push_scope("dyn.caret.end.line")
        if rightCursor.atEnd():
            right_scope.push_scope("dyn.caret.end.document")
        return left_scope, right_scope
Пример #7
0
class SupportManager(QtCore.QObject, PMXSupportBaseManager):
    #Signals for bundle
    bundleAdded = QtCore.pyqtSignal(object)
    bundleRemoved = QtCore.pyqtSignal(object)
    bundleChanged = QtCore.pyqtSignal(object)
    bundlePopulated = QtCore.pyqtSignal(object)

    #Signals for bundle items
    bundleItemAdded = QtCore.pyqtSignal(object)
    bundleItemRemoved = QtCore.pyqtSignal(object)
    bundleItemChanged = QtCore.pyqtSignal(object)
    bundleItemTriggered = QtCore.pyqtSignal(object)
    
    #Signals for themes
    themeAdded = QtCore.pyqtSignal(object)
    themeRemoved = QtCore.pyqtSignal(object)
    themeChanged = QtCore.pyqtSignal(object)
    
    #Settings
    shellVariables = pmxConfigPorperty(default = [], tm_name = u'OakShelVariables')
    
    @pmxConfigPorperty(default = [], tm_name = u'OakBundleManagerDeletedBundles')
    def deleted(self, deleted):
        self.deletedObjects = map(lambda uuid: uuidmodule.UUID(uuid), deleted)
        
    @pmxConfigPorperty(default = [], tm_name = u'OakBundleManagerDeletedBundles')
    def disabled(self, disabled):
        self.disabledObjects = map(lambda uuid: uuidmodule.UUID(uuid), 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 = pmxConfigPorperty(default = u'B7BC3FFD-6E4B-11D9-91AF-000D93589AF6', tm_name = u'OakDefaultBundleForNewBundleItems')
        
    SETTINGS_GROUP = 'SupportManager'
    
    def __init__(self, application):
        QtCore.QObject.__init__(self)
        PMXSupportBaseManager.__init__(self)
        self.application = application
        self.bundleTreeModel = BundleItemTreeModel(self)
        self.themeListModel = ThemeListModel(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)
        
        #BUNDLEMENUGROUP
        self.bundleMenuGroup = BundleItemMenuGroup(self)

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

    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)
        
    #---------------------------------------------------
    # Environment
    #---------------------------------------------------
    def environmentVariables(self):
        environment = PMXSupportBaseManager.buildEnvironment(self)
        #Extend wiht the user shell variables
        for var in self.shellVariables:
            if var['enabled']:
                environment[var['variable']] = var['value']
        return environment
    
    def buildEnvironment(self, systemEnvironment = True):
        env = PMXSupportBaseManager.buildEnvironment(self, systemEnvironment)
        for var in self.shellVariables:
            if var['enabled']:
                env[var['variable']] = var['value']
        return env
    
    # Override loadSupport for emit signals
    def loadSupport(self, *largs, **kwargs):
        PMXSupportBaseManager.loadSupport(self, *largs, **kwargs)
        self.bundleProxyTreeModel.sort(0, QtCore.Qt.AscendingOrder)
        self.bundleProxyTreeModel.setDynamicSortFilter(True)

    def runProcess(self, context, callback):
        if context.asynchronous:
            return self.runQProcess(context, callback)
        else:
            return PMXSupportBaseManager.runProcess(self, context, callback)
            
    #Interface
    def runQProcess(self, context, callback):
        process = QtCore.QProcess(self)
        if context.workingDirectory is not None:
            process.setWorkingDirectory(context.workingDirectory)
            
        self.processTableModel.appendProcess(process, description = context.description())

        environment = QtCore.QProcessEnvironment()
        for key, value in context.environment.iteritems():
            environment.insert(key, value)
                    
        process.setProcessEnvironment(environment)

        def onQProcessFinished(process, context, callback):
            def runCallback(exitCode):
                self.processTableModel.removeProcess(process)
                context.errorValue = str(process.readAllStandardError()).decode("utf-8")
                context.outputValue = str(process.readAllStandardOutput()).decode("utf-8")
                context.outputType = exitCode
                callback(context)
            return runCallback

        process.finished[int].connect(onQProcessFinished(process, context, callback))

        if context.inputType is not None:
            process.start(context.shellCommand, QtCore.QIODevice.ReadWrite)
            if not process.waitForStarted():
                raise Exception("No puedo correr")
            process.write(unicode(context.inputValue).encode("utf-8"))
            process.closeWriteChannel()
        else:
            process.start(context.shellCommand, QtCore.QIODevice.ReadOnly)

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

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

    #---------------------------------------------------
    # MANAGED OBJECTS OVERRIDE INTERFACE
    #---------------------------------------------------
    def setDeleted(self, uuid):
        """
        Marcar un managed object como eliminado
        """
        self.deletedObjects.append(uuid)
        deleted = map(lambda uuid: unicode(uuid).upper(), 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 = map(lambda uuid: unicode(uuid).upper(), self.disabledObjects)
        self.settings.setValue('disabled', disabled)
        
    def setEnabled(self, uuid):
        self.disabledObjects.remove(uuid)
        disabled = map(lambda uuid: unicode(uuid).upper(), 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.getAllItems()
    
    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
        
    #---------------------------------------------------
    # TEMPLATEFILE OVERRIDE INTERFACE
    #---------------------------------------------------
    def addTemplateFile(self, file):
        bundleTemplateFileNode = BundleItemTreeNode(file)
        self.bundleTreeModel.appendTemplateFile(bundleTemplateFileNode)
        return bundleTemplateFileNode
    
    #---------------------------------------------------
    # THEME OVERRIDE INTERFACE
    #---------------------------------------------------
    def addTheme(self, theme):
        themeRow = ThemeStyleTableRow(theme, self.scores)
        self.themeListModel.appendTheme(themeRow)
        self.themeAdded.emit(themeRow)
        return themeRow
    
    def modifyTheme(self, theme):
        self.themeChanged.emit(theme)
        
    def removeTheme(self, theme):
        self.themeListModel.removeTheme(theme)
        self.themeRemoved.emit(theme)
            
    def getAllThemes(self):
        return self.themeListModel.getAllItems()
    
    #---------------------------------------------------
    # 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
    #---------------------------------------------------
    @dynamic_memoized
    def getAllPreferences(self):
        return self.preferenceProxyModel.getAllItems()
    
    #---------------------------------------------------
    # TABTRIGGERS OVERRIDE INTERFACE
    #---------------------------------------------------
    @dynamic_memoized
    def getAllTabTriggerItems(self):
        tabTriggers = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.tabTrigger != None:
                tabTriggers.append(item)
        return tabTriggers
        
    @dynamic_memoized
    def getAllBundleItemsByTabTrigger(self, tabTrigger):
        items = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.tabTrigger == tabTrigger:
                items.append(item)
        return items

    #---------------------------------------------------
    # KEYEQUIVALENT OVERRIDE INTERFACE
    #---------------------------------------------------
    @dynamic_memoized
    def getAllKeyEquivalentItems(self):
        keyEquivalent = []
        for item in self.actionItemsProxyModel.getAllItems() + self.syntaxProxyModel.getAllItems():
            if item.keyEquivalent != None:
                keyEquivalent.append(item)
        return keyEquivalent
        
    @dynamic_memoized
    def getAllBundleItemsByKeyEquivalent(self, keyEquivalent):
        items = []
        for item in self.actionItemsProxyModel.getAllItems():
            if item.keyEquivalent == keyEquivalent:
                items.append(item)
        for syntax in self.syntaxProxyModel.getAllItems():
            if syntax.keyEquivalent == keyEquivalent:
                items.append(syntax)
        return items
    
    #---------------------------------------------------
    # FILE EXTENSION OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllBundleItemsByFileExtension(self, path):
        items = []
        for item in self.dragcommandProxyModel.getAllItems():
            if any(map(lambda extension: fnmatch.fnmatch(path, "*.%s" % extension), item.draggedFileExtensions)):
                items.append(item)
        return items
    
    #---------------------------------------------------
    # ACTION ITEMS OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllActionItems(self):
        return self.actionItemsProxyModel.getAllItems()
    
    #---------------------------------------------------
    # SYNTAXES OVERRIDE INTERFACE
    #---------------------------------------------------
    def getAllSyntaxes(self):
        return self.syntaxProxyModel.getAllItems()