Exemple #1
0
class SettingsManager(PrymatexComponent, QtCore.QObject):
    def __init__(self, **kwargs):
        super(SettingsManager, self).__init__(**kwargs)
        self._settings = []

        # Settings Models
        self.settingsTreeModel = SettingsTreeModel(parent=self)
        self.sortFilterSettingsProxyModel = SortFilterSettingsProxyModel(parent=self)
        self.sortFilterSettingsProxyModel.setSourceModel(self.settingsTreeModel)
        
        self.application().aboutToQuit.connect(self.on_application_aboutToQuit)
        
        # Reload settings
        self.fileSystemWatcher = QtCore.QFileSystemWatcher()
        self.fileSystemWatcher.fileChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )
        self.fileSystemWatcher.directoryChanged.connect(
            self.on_fileSystemWatcher_pathChanged
        )

    def on_fileSystemWatcher_pathChanged(self, path):
        settings = [s for s in self._settings if s.source.name == path or s.source.path == path].pop()
        if settings.source.hasChanged():
            if settings.source.exists:
                data = settings.get_data(settings.source.path)
                settings.reload(data)
            else:
                settings.reload({})
            settings.source = settings.source.newUpdatedTime()

    def getSettings(self, path, klass=settings.Settings):
        settings = [s for s in self._settings if s.source.name == path or s.source.path == path]
        if settings:
            return settings[0]
        basename = os.path.basename(path)
        directory = os.path.dirname(path)
        _source = source.Source(directory, path)
        data = klass.get_data(_source.path) if _source.exists else {}
        settings = klass(basename, data)
        settings.source = _source
        self._settings.append(settings)
        self.fileSystemWatcher.addPath(_source.exists and _source.path or _source.name)
        return settings
    
    def initialize(self):
        # Textmate Settings
        self.textmate_settings = self.getSettings(
            self.profile().TM_PREFERENCES_PATH,
            TextMateSettings
        )
        
        # Prymatex Settings
        self.prymatex_settings = self.getSettings(
            self.profile().PMX_SETTINGS_PATH,
            PrymatexSettings
        )
        self.prymatex_settings.setTm(self.textmate_settings)
        
    # ------------------- Signals
    def on_application_aboutToQuit(self):
        # Save textmate
        self.textmate_settings.write(self.profile().TM_PREFERENCES_PATH)
        # Save settings
        self.prymatex_settings.purge()
        self.prymatex_settings.write(self.profile().PMX_SETTINGS_PATH)

        state = self.application().componentState()
        json.write_file(state, self.profile().PMX_STATE_PATH)

    # -------------------- Public API
    def loadSettings(self, message_handler):
        # Load settings
        self.settingsTreeModel.loadSettings()

    def populateConfigurableClass(self, component_class):
        settings = component_class.settings()
        for klass in component_class.contributeToSettings():
            widget = klass(component_class)
            self.settingsTreeModel.addConfigNode(widget)
            settings.addWidget(widget)

    # ------------------------ Setting
    def settingsForClass(self, configurableClass):
        scope_name = getattr(configurableClass, 'SETTINGS',
            "_".join(textutils.camelcase_to_text(configurableClass.__name__).split())
        )
        settings = self.prymatex_settings.scope(scope_name, create=True)
        # --------- Register settings values
        for key, value in configurableClass.__dict__.items():
            if isinstance(value, ConfigurableItem):
                if value.name is None:
                    value.name = key
                settings.addItem(value)
            elif isinstance(value, ConfigurableHook):
                settings.addHook(value)
        return settings

    def registerConfigurableInstance(self, configurable):
        settings = configurable.settings()
        settings.addListener(configurable)
        settings.configure(configurable)
        # Register hooks
        for path, hook in settings.hooks().items():
            handler = hook.fset.__get__(
                configurable, configurable.__class__)
            self.registerSettingCallback(path, handler)
            handler(self.settingValue(path))

    def unregisterConfigurableInstance(self, configurable):
        settings = configurable.settings()
        settings.removeListener(configurable)
        # Unregister hooks
        for path, hook in settings.hooks().items():
            self.unregisterSettingCallback(path, hook.fset)

    def restoreApplicationState(self):
        state = json.read_file(self.profile().PMX_STATE_PATH)
        self.application().setComponentState(state or {})

    def settingValue(self, settingPath, default=None):
        names = settingPath.split(".")
        settings = self.prymatex_settings
        for name in names[:-1]:
            settings = settings.scope(name)
        if settings:
            return settings.get(names[-1], default)
        return default

    def registerSettingCallback(self, settingPath, handler):
        names = settingPath.split(".")
        settings = self.prymatex_settings
        for name in names[:-1]:
            settings = settings.scope(name)
        if settings:
            settings.add_callback(names[-1], handler)

    def unregisterSettingCallback(self, settingPath, handler):
        names = settingPath.split(".")
        settings = self.prymatex_settings
        for name in names[:-1]:
            settings = settings.get(name)
        if settings:
            settings.remove_callback(names[-1], handler)
        
    def clear(self):
        self.prymatex_settings.clear()
Exemple #2
0
class ProfileManager(PrymatexComponent, QtCore.QObject):
    PMX_PROFILES_FILE = "profiles.ini"
    DEFAULT_PROFILE_NAME = "default"

    def __init__(self, **kwargs):
        super(ProfileManager, self).__init__(**kwargs)
        
        self.profilesListModel = ProfilesListModel(self)
        
        self.__dontAsk = True
        
        self.profilesFile = os.path.join(PMX_PROFILES_PATH, self.PMX_PROFILES_FILE)
        config = configparser.RawConfigParser()
        if os.path.exists(self.profilesFile):
            config.read(self.profilesFile)
            for section in config.sections():
                if section.startswith("Profile"):
                    name = config.get(section, "name")
                    path = config.get(section, "path")
                    default = config.getboolean(section, "default")
                    profile = PrymatexProfile(name, path, default)
                    self.profilesListModel.addProfile(profile)
            self.__dontAsk = config.getboolean("General", "dontAsk")
        else:
            self.createProfile(self.DEFAULT_PROFILE_NAME, default = True)

        # Setting models        
        self.settingsTreeModel = SettingsTreeModel(parent = self)
        self.sortFilterSettingsProxyModel = SortFilterSettingsProxyModel(parent = self)
        self.sortFilterSettingsProxyModel.setSourceModel(self.settingsTreeModel)

    # --------------- Profile
    def build_prymatex_profile(self, path):
        # TODO: Algo como ensure paths porque si falta uno que hago?
        os.makedirs(path)
        os.makedirs(os.path.join(path, 'tmp'), mode = 0o0700)
        os.makedirs(os.path.join(path, 'log'), mode = 0o0700)
        os.makedirs(os.path.join(path, 'cache'), mode = 0o0700)
        os.makedirs(os.path.join(path, 'screenshot'), mode = 0o0700)

    def saveProfiles(self):
        config = configparser.RawConfigParser()
        config.add_section("General")
        config.set("General", "dontask", str(self.__dontAsk))
        for index, profile in enumerate(self.profilesListModel.profiles()):
            section = "Profile%d" % index
            config.add_section(section)
            config.set(section, "name", profile.PMX_PROFILE_NAME)
            config.set(section, "path", profile.PMX_PROFILE_PATH)
            config.set(section, "default", profile.PMX_PROFILE_DEFAULT)
        f = open(self.profilesFile, "w")
        config.write(f)
        f.close()

    def createProfile(self, name, path = None, default = False):
        name = name.lower()
        profile = self.profilesListModel.findProfileByName(name)
        if profile is None:
            if path is None:
                path = os.path.abspath(os.path.join(PMX_PROFILES_PATH, name))
            profile = PrymatexProfile(name, path)
            self.profilesListModel.addProfile(profile)
            self.setDefaultProfile(profile)
            self.saveProfiles()
            return profile

    def currentProfile(self, value = None):
        if value is None or not self.__dontAsk:
            profile = ProfileDialog.selectStartupProfile(self)
        elif value == "":
            profile = self.defaultProfile()
        else:
            profile = self.profilesListModel.findProfileByName(value)
        if profile is None:
            profile = self.createProfile(value, default = True)
        if not os.path.exists(profile.PMX_PROFILE_PATH):
            self.build_prymatex_profile(profile.PMX_PROFILE_PATH)
        return profile

    def renameProfile(self, profile, newName):
        newName = newName.lower()
        profile = self.profilesListModel.findProfileByName(profile.PMX_PROFILE_NAME)
        
        profile.PMX_PROFILE_NAME = newName.lower()
        self.profilesListModel.layoutChanged.emit()
        self.saveProfiles()
        return newName

    def deleteProfile(self, profile, files = False):
        self.profilesListModel.removeProfile(profile)
        if files:
            shutil.rmtree(profile.PMX_PROFILE_PATH)
        self.saveProfiles()

    def profileNames(self):
        return [ p.PMX_PROFILE_NAME for p in self.profilesListModel.profiles() ]

    def setDontAsk(self, value):
        self.__dontAsk = value
        self.saveProfiles()

    def dontAsk(self):
        return self.__dontAsk

    def setDefaultProfile(self, profile):
        # Unset all ?
        for p in self.profilesListModel.profiles():
            p.PMX_PROFILE_DEFAULT = False
        profile.PMX_PROFILE_DEFAULT = True
        self.saveProfiles()

    def defaultProfile(self):
        for profile in self.profilesListModel.profiles():
            if profile.PMX_PROFILE_DEFAULT:
                return profile

    # ------------------- Settings
    def registerSettingsWidget(self, widget):
        self.settingsTreeModel.addConfigNode(widget)

    def loadSettings(self, messageHandler = None):
        self.messageHandler = messageHandler
        self.settingsTreeModel.loadSettings()
        self.messageHandler = None