예제 #1
0
class PlayerSpawnPositionTool(PlayerPositionTool):
    surfaceBuild = True
    toolIconName = "playerspawn"
    tooltipText = "Move Spawn Point"

    def __init__(self, *args):
        PlayerPositionTool.__init__(self, *args)
        self.optionsPanel = PlayerSpawnPositionOptions(self)

    def toolEnabled(self):
        return self.editor.level.dimNo == 0

    def showPanel(self):
        self.panel = Panel()
        button = Button("Goto Spawn", action=self.gotoSpawn)
        self.panel.add(button)
        self.panel.shrink_wrap()

        self.panel.left = self.editor.left
        self.panel.centery = self.editor.centery
        self.editor.add(self.panel)

    def gotoSpawn(self):
        cv = self.editor.mainViewport.cameraVector

        pos = self.editor.level.playerSpawnPosition()
        pos = map(lambda p, c: p - c * 5, pos, cv)

        self.editor.mainViewport.cameraPosition = pos
        self.editor.mainViewport.stopMoving()

    @property
    def statusText(self):
        return "Click to set the spawn position."

    spawnProtection = SpawnSettings.spawnProtection.configProperty()

    def drawToolReticle(self):
        pos, direction = self.editor.blockFaceUnderCursor
        x, y, z = map(lambda p, d: p + d, pos, direction)

        color = (1.0, 1.0, 1.0, 0.5)
        if isinstance(self.editor.level,
                      pymclevel.MCInfdevOldLevel) and self.spawnProtection:
            if not positionValid(self.editor.level, (x, y, z)):
                color = (1.0, 0.0, 0.0, 0.5)

        GL.glColor(*color)
        GL.glEnable(GL.GL_BLEND)
        self.drawCage(x, y, z)
        self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5)
        GL.glDisable(GL.GL_BLEND)

        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCage(x, y, z)
        self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5)
        color2 = map(lambda a: a * 0.4, color)
        drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)), color2,
                               color)
        GL.glDisable(GL.GL_DEPTH_TEST)

    def _drawToolMarkers(self):
        x, y, z = self.editor.level.playerSpawnPosition()
        GL.glColor(1.0, 1.0, 1.0, 1.0)
        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCage(x, y, z)
        self.drawCharacterHead(
            x + 0.5, y + 0.5 + 0.125 * numpy.sin(self.editor.frames * 0.05),
            z + 0.5)
        GL.glDisable(GL.GL_DEPTH_TEST)

    def drawCage(self, x, y, z):
        cageTexVerts = numpy.array(
            pymclevel.MCInfdevOldLevel.materials.blockTextures[52, 0])

        pixelScale = 0.5 if self.editor.level.materials.name in (
            "Pocket", "Alpha") else 1.0
        texSize = 16 * pixelScale
        cageTexVerts *= pixelScale

        cageTexVerts = numpy.array([((tx, ty), (tx + texSize, ty),
                                     (tx + texSize, ty + texSize),
                                     (tx, ty + texSize))
                                    for (tx, ty) in cageTexVerts],
                                   dtype='float32')
        GL.glEnable(GL.GL_ALPHA_TEST)

        drawCube(BoundingBox((x, y, z), (1, 1, 1)),
                 texture=pymclevel.alphaMaterials.terrainTexture,
                 textureVertices=cageTexVerts)
        GL.glDisable(GL.GL_ALPHA_TEST)

    @alertException
    def mouseDown(self, evt, pos, direction):
        pos = map(lambda p, d: p + d, pos, direction)
        op = PlayerSpawnMoveOperation(self, pos)
        try:
            op.perform()

            self.editor.addOperation(op)
            self.editor.addUnsavedEdit()
            self.markerList.invalidate()

        except SpawnPositionInvalid, e:
            if "Okay" != ask(str(e), responses=["Okay", "Fix it for me!"]):
                level = self.editor.level
                status = ""
                if not okayAt63(level, pos):
                    level.setBlockAt(pos[0], 63, pos[2], 1)
                    status += "Block added at y=63.\n"

                if 59 < pos[1] < 63:
                    pos[1] = 63
                    status += "Spawn point moved upward to y=63.\n"

                if not okayAboveSpawn(level, pos):
                    if pos[1] > 63 or pos[1] < 59:
                        lpos = (pos[0], pos[1] - 1, pos[2])
                        if level.blockAt(*pos) == 0 and level.blockAt(
                                *lpos) != 0 and okayAboveSpawn(level, lpos):
                            pos = lpos
                            status += "Spawn point shifted down by one block.\n"
                    if not okayAboveSpawn(level, pos):
                        for i in range(1, 4):
                            level.setBlockAt(pos[0], pos[1] + i, pos[2], 0)

                            status += "Blocks above spawn point cleared.\n"

                self.editor.invalidateChunks([(pos[0] // 16, pos[2] // 16)])
                op = PlayerSpawnMoveOperation(self, pos)
                try:
                    op.perform()
                except SpawnPositionInvalid, e:
                    alert(str(e))
                    return

                self.editor.addOperation(op)
                self.editor.addUnsavedEdit()
                self.markerList.invalidate()
                if len(status):
                    alert("Spawn point fixed. Changes: \n\n" + status)
예제 #2
0
class PlayerSpawnPositionTool(PlayerPositionTool):
    surfaceBuild = True
    toolIconName = "playerspawn"
    tooltipText = "Move Spawn Point\nRight-click for options"

    def __init__(self, *args):
        PlayerPositionTool.__init__(self, *args)
        self.optionsPanel = PlayerSpawnPositionOptions(self)

    def toolEnabled(self):
        return self.editor.level.dimNo == 0

    def showPanel(self):
        self.panel = Panel(name='Panel.PlayerSpawnPositionTool')
        button = Button("Goto Spawn", action=self.gotoSpawn)
        self.panel.add(button)
        self.panel.shrink_wrap()

        self.panel.left = self.editor.left
        self.panel.centery = self.editor.centery
        self.editor.add(self.panel)

    def gotoSpawn(self):
        cv = self.editor.mainViewport.cameraVector

        pos = self.editor.level.playerSpawnPosition()
        pos = map(lambda p, c: p - c * 5, pos, cv)

        self.editor.mainViewport.cameraPosition = pos
        self.editor.mainViewport.stopMoving()

    @property
    def statusText(self):
        return "Click to set the spawn position."

    spawnProtection = config.spawn.spawnProtection.property()

    def drawToolReticle(self):
        pos, direction = self.editor.blockFaceUnderCursor
        x, y, z = map(lambda p, d: p + d, pos, direction)

        color = (1.0, 1.0, 1.0, 0.5)
        if isinstance(self.editor.level, pymclevel.MCInfdevOldLevel) and self.spawnProtection:
            if not positionValid(self.editor.level, (x, y, z)):
                color = (1.0, 0.0, 0.0, 0.5)

        GL.glColor(*color)
        GL.glEnable(GL.GL_BLEND)
        self.drawCage(x, y, z)
        self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5)
        GL.glDisable(GL.GL_BLEND)

        GL.glEnable(GL.GL_DEPTH_TEST)
        self.drawCage(x, y, z)
        self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5)
        color2 = map(lambda a: a * 0.4, color)
        drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)), color2, color)
        GL.glDisable(GL.GL_DEPTH_TEST)

    def _drawToolMarkers(self):
        x, y, z = self.editor.level.playerSpawnPosition()
        
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
        GL.glEnable(GL.GL_BLEND)
        
        color = config.selectionColors.black.get() + (0.35,)
        GL.glColor(*color)
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)
        GL.glLineWidth(2.0)
        drawCube(FloatBox((x, y, z), (1, 1, 1)))
        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        drawCube(FloatBox((x, y, z), (1, 1, 1)))
        GL.glDisable(GL.GL_BLEND)
        
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glColor(1.0, 1.0, 1.0, 1.0)
        self.drawCage(x, y, z)
        self.drawCharacterHead(x + 0.5, y + 0.5 + 0.125 * numpy.sin(self.editor.frames * 0.05), z + 0.5)
        GL.glDisable(GL.GL_DEPTH_TEST)

    def drawCage(self, x, y, z):
        cageTexVerts = numpy.array(pymclevel.MCInfdevOldLevel.materials.blockTextures[52, 0])

        pixelScale = 0.5 if self.editor.level.materials.name in ("Pocket", "Alpha") else 1.0
        texSize = 16 * pixelScale
        cageTexVerts = cageTexVerts.astype(float) * pixelScale

        cageTexVerts = numpy.array(
            [((tx, ty), (tx + texSize, ty), (tx + texSize, ty + texSize), (tx, ty + texSize)) for (tx, ty) in
             cageTexVerts], dtype='float32')
        GL.glEnable(GL.GL_ALPHA_TEST)

        drawCube(BoundingBox((x, y, z), (1, 1, 1)), texture=pymclevel.alphaMaterials.terrainTexture,
                 textureVertices=cageTexVerts)
        GL.glDisable(GL.GL_ALPHA_TEST)

    @alertException
    def mouseDown(self, evt, pos, direction):
        pos = map(lambda p, d: p + d, pos, direction)
        op = PlayerSpawnMoveOperation(self, pos)
        try:
            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()
            self.markerList.invalidate()

        except SpawnPositionInvalid, e:
            if "Okay" != ask(str(e), responses=["Okay", "Fix it for me!"]):
                level = self.editor.level
                status = ""
                if not okayAt63(level, pos):
                    level.setBlockAt(pos[0], 63, pos[2], 1)
                    status += _("Block added at y=63.\n")

                if 59 < pos[1] < 63:
                    pos[1] = 63
                    status += _("Spawn point moved upward to y=63.\n")

                if not okayAboveSpawn(level, pos):
                    if pos[1] > 63 or pos[1] < 59:
                        lpos = (pos[0], pos[1] - 1, pos[2])
                        if level.blockAt(*pos) == 0 and level.blockAt(*lpos) != 0 and okayAboveSpawn(level, lpos):
                            pos = lpos
                            status += _("Spawn point shifted down by one block.\n")
                    if not okayAboveSpawn(level, pos):
                        for i in xrange(1, 4):
                            level.setBlockAt(pos[0], pos[1] + i, pos[2], 0)

                            status += _("Blocks above spawn point cleared.\n")

                self.editor.invalidateChunks([(pos[0] // 16, pos[2] // 16)])
                op = PlayerSpawnMoveOperation(self, pos)
                try:
                    self.editor.addOperation(op)
                    if op.canUndo:
                        self.editor.addUnsavedEdit()
                    self.markerList.invalidate()
                except SpawnPositionInvalid, e:
                    alert(str(e))
                    return

                if len(status):
                    alert(_("Spawn point fixed. Changes: \n\n") + status)
예제 #3
0
    def askAssignKey(self, configKey, labelString=None):
        if not self.isConfigKey(configKey):
            self.enter = 0
            return

        panel = Panel()
        panel.bg_color = (0.5, 0.5, 0.6, 1.0)

        if labelString is None:
            labelString = _("Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel. Press Shift-ESC to unbind.").format(configKey)
        label = albow.Label(labelString)
        panel.add(label)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            keyname = self.root.getKey(evt)
            panel.dismiss(keyname)

        def panelMouseUp(evt):
            button = remapMouseButton(evt.button)
            if button == 3:
                keyname = "Button 3"
            elif button == 4:
                keyname = "Scroll Up"
            elif button == 5:
                keyname = "Scroll Down"
            elif button == 6:
                keyname = "Button 4"
            elif button == 7:
                keyname = "Button 5"
            if button > 2:
                panel.dismiss(keyname)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        keyname = panel.present()
        if keyname == "Return" and self.enter == 1:
            self.enter = 0
            self.askAssignKey(configKey, _("Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel. Press Shift-ESC to unbind.").format(configKey))
            return True

        self.enter = 0
        if keyname != "Escape" and keyname != "Shift-Escape" and keyname not in ["Alt-F4","F1","F2","F3","F4","F5","1","2","3","4","5","6","7","8","9","Ctrl-Alt-F9","Ctrl-Alt-F10"]:
            if "Modifier" in configKey and keyname != "Ctrl" and keyname != "Alt" and keyname != "Shift":
                self.askAssignKey(configKey,
                                    _("{0} is not a modifier. "
                                    "Press a new key.\n\n"
                                    "Press ESC to cancel. Press Shift-ESC to unbind.")
                                    .format(keyname))
                return True
            if configKey in ['Down','Up','Back','Forward','Left','Right','Pan Down','Pan Up','Pan Left','Pan Right']:
                if 'Ctrl' in keyname:
                    self.askAssignKey(configKey,
                                    _("Movement keys can't use Ctrl. "
                                    "Press a new key.\n\n"
                                    "Press ESC to cancel. Press Shift-ESC to unbind."))
                    return True
            oldkey = config.keys[config.convert(configKey)].get()
            config.keys[config.convert(configKey)].set(keyname)
            if configKey not in self.changes:
                self.changes[configKey] = oldkey
            self.changesNum = True
        elif keyname == "Shift-Escape":
            config.keys[config.convert(configKey)].set("None")
        elif keyname != "Escape":
            self.askAssignKey(configKey,
                                    _("You can't use the key {0}. "
                                    "Press a new key.\n\n"
                                    "Press ESC to cancel. Press Shift-ESC to unbind.")
                                    .format(keyname))
            return True

        else:
            return True
예제 #4
0
class FilterTool(EditorTool):
    tooltipText = "Filter"
    toolIconName = "filter"

    def __init__(self, editor):
        EditorTool.__init__(self, editor)

        self.filterModules = {}

        self.panel = FilterToolPanel(self)

    @property
    def statusText(self):
        return "Choose a filter, then click Filter or press ENTER to apply it."

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def toolSelected(self):
        self.showPanel()

    @alertException
    def showPanel(self):
        if self.panel.parent:
            self.editor.remove(self.panel)

        self.reloadFilters()

        # self.panel = FilterToolPanel(self)
        self.panel.reload()

        self.panel.midleft = self.editor.midleft

        self.editor.add(self.panel)

        self.updatePanel = Panel()
        updateButton = Button("Update Filters", action=self.updateFilters)
        self.updatePanel.add(updateButton)
        self.updatePanel.shrink_wrap()

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        self.editor.add(self.updatePanel)

    def hidePanel(self):
        self.panel.saveOptions()
        if self.panel.parent:
            self.panel.parent.remove(self.panel)
            self.updatePanel.parent.remove(self.updatePanel)

    def updateFilters(self):
        totalFilters = 0
        updatedFilters = 0
        try:
            os.mkdir(mcplatform.filtersDir + "/updates")
        except OSError:
            pass
        for module in self.filterModules.values():
            totalFilters = totalFilters + 1
            if hasattr(module, "UPDATE_URL") and hasattr(module, "VERSION"):
                if isinstance(module.UPDATE_URL, (str, unicode)) and isinstance(module.VERSION, (str, unicode)):
                    versionJSON = json.loads(urllib2.urlopen(module.UPDATE_URL).read())
                    if module.VERSION != versionJSON["Version"]:
                        urllib.urlretrieve(versionJSON["Download-URL"],
                                           mcplatform.filtersDir + "/updates/" + versionJSON["Name"])
                        updatedFilters = updatedFilters + 1
        for f in os.listdir(mcplatform.filtersDir + "/updates"):
            shutil.copy(mcplatform.filtersDir + "/updates/" + f, mcplatform.filtersDir)
        shutil.rmtree(mcplatform.filtersDir + "/updates/")
        self.finishedUpdatingWidget = Widget()
        lbl = Label("Updated " + str(updatedFilters) + " filter(s) out of " + str(totalFilters))
        closeBTN = Button("Close this message", action=self.closeFinishedUpdatingWidget)
        col = Column((lbl, closeBTN))
        self.finishedUpdatingWidget.bg_color = (0.0, 0.0, 0.6)
        self.finishedUpdatingWidget.add(col)
        self.finishedUpdatingWidget.shrink_wrap()
        self.finishedUpdatingWidget.present()

    def closeFinishedUpdatingWidget(self):
        self.finishedUpdatingWidget.dismiss()

    def reloadFilters(self):
        filterDir = mcplatform.filtersDir
        filterFiles = os.listdir(filterDir)
        filterPyfiles = filter(lambda x: x.endswith(".py"), filterFiles)

        def tryImport(name):
            try:
                return __import__(name)
            except Exception, e:
                print traceback.format_exc()
                alert(_(u"Exception while importing filter module {}. See console for details.\n\n{}").format(name, e))
                return object()

        filterModules = (tryImport(x[:-3]) for x in filterPyfiles)
        filterModules = filter(lambda module: hasattr(module, "perform"), filterModules)

        self.filterModules = collections.OrderedDict(sorted((self.moduleDisplayName(x), x) for x in filterModules))
        for m in self.filterModules.itervalues():
            try:
                reload(m)
            except Exception, e:
                print traceback.format_exc()
                alert(
                    _(u"Exception while reloading filter module {}. Using previously loaded module. See console for details.\n\n{}").format(
                        m.__file__, e))
예제 #5
0
class FilterTool(EditorTool):
    tooltipText = "Filter"
    toolIconName = "filter"

    def __init__(self, editor):
        EditorTool.__init__(self, editor)

        self.filterModules = {}
        self.savedOptions = {}

        self.updatePanel = Panel()
        updateButton = Button("Update Filters", action=self.updateFilters)
        self.updatePanel.add(updateButton)
        self.updatePanel.shrink_wrap()

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft

    @property
    def statusText(self):
        return "Choose a filter, then click Filter or press Enter to apply it."

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def toolSelected(self):
        self.showPanel()

    @alertException
    def showPanel(self):
        self.panel = FilterToolPanel(self)

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        self.editor.add(self.updatePanel)
        self.reloadFilters()

        self.panel.reload()
        height = self.editor.mainViewport.height - self.editor.toolbar.height
        self.panel.centery = height / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel is None:
            return
        self.panel.close()
        if self.panel.parent:
            self.panel.parent.remove(self.panel)
            self.updatePanel.parent.remove(self.updatePanel)
        self.panel = None

    def updateFilters(self):
        totalFilters = 0
        updatedFilters = 0
        filtersDir = directories.getFiltersDir()
        try:
            os.mkdir(os.path.join(filtersDir, "updates"))
        except OSError:
            pass
        for module in self.filterModules.values():
            totalFilters += 1
            if hasattr(module, "UPDATE_URL") and hasattr(module, "VERSION"):
                if isinstance(module.UPDATE_URL,
                              (str, unicode)) and isinstance(
                                  module.VERSION, (str, unicode)):
                    versionJSON = json.loads(
                        urllib2.urlopen(module.UPDATE_URL).read())
                    if module.VERSION != versionJSON["Version"]:
                        urllib.urlretrieve(
                            versionJSON["Download-URL"],
                            os.path.join(filtersDir, "updates",
                                         versionJSON["Name"]))
                        updatedFilters += 1
        for f in os.listdir(os.path.join(filtersDir, "updates")):
            shutil.copy(os.path.join(filtersDir, "updates", f), filtersDir)
        shutil.rmtree(os.path.join(filtersDir, "updates"))
        finishedUpdatingWidget = Widget()
        lbl = Label("Updated %s filter(s) out of %s" %
                    (updatedFilters, totalFilters))
        closeBTN = Button("Close this message",
                          action=finishedUpdatingWidget.dismiss)
        col = Column((lbl, closeBTN))
        finishedUpdatingWidget.bg_color = (0.0, 0.0, 0.6)
        finishedUpdatingWidget.add(col)
        finishedUpdatingWidget.shrink_wrap()
        finishedUpdatingWidget.present()

    def reloadFilters(self):
        filterFiles = []
        unicode_module_names = []

        def searchForFiltersInDir(searchFolder, stock=False):
            for root, folders, files in os.walk(os.path.join(searchFolder),
                                                True):
                filter_dir = os.path.basename(root)

                if filter_dir.startswith('demo') or filter_dir.startswith(
                        'lib'):
                    continue

                subFolderString = root.replace(searchFolder, "")
                if subFolderString.endswith(os.sep):
                    subFolderString = subFolderString[:len(os.sep)]
                if subFolderString.startswith(os.sep):
                    subFolderString = subFolderString[len(os.sep):]
                if len(subFolderString) > 0:
                    subFolderString = "[" + subFolderString + "]"

                try:
                    root = str(root)
                    if root not in sys.path:
                        sys.path.append(root)
                except UnicodeEncodeError:
                    unicode_module_names.extend(
                        [filter_name for filter_name in files])

                for possible_filter in files:
                    if possible_filter.endswith(".py"):
                        filterFiles.append(
                            (root, possible_filter, stock, subFolderString))

        searchForFiltersInDir(directories.getFiltersDir(), False)
        searchForFiltersInDir(
            os.path.join(directories.getDataDir(), "stock-filters"), True)

        filterModules = []

        # If the path has unicode chars, there's no way of knowing what order to add the
        # files to the sys.modules. To fix this, we keep trying to import until we import
        # fail to import all leftover files.
        shouldContinue = True
        while shouldContinue:
            shouldContinue = False
            for f in filterFiles:
                module = tryImport(f[0], f[1], f[2], f[3], f[1]
                                   in unicode_module_names)
                if module is None:
                    continue
                filterModules.append(module)
                filterFiles.remove(f)
                shouldContinue |= True

        displayNames = []
        for m in filterModules:
            while m.displayName in displayNames:
                m.displayName += "_"
            displayNames.append(m)

        filterModules = filter(lambda mod: hasattr(mod, "perform"),
                               filterModules)
        self.filterModules = collections.OrderedDict(
            sorted([(FilterTool.moduleDisplayName(x), x)
                    for x in filterModules],
                   key=lambda module_name:
                   (module_name[0].lower(), module_name[1])))

    @staticmethod
    def moduleDisplayName(module):
        subFolderString = getattr(module, 'foldersForDisplayName', "")
        subFolderString = subFolderString if len(
            subFolderString) < 1 else subFolderString + " "
        return subFolderString + getattr(module, "displayName",
                                         module.__name__)

    @property
    def filterNames(self):
        return [
            FilterTool.moduleDisplayName(module)
            for module in self.filterModules.itervalues()
        ]
예제 #6
0
    def askAssignKey(self, configKey, labelString=None):
        if not self.isConfigKey(configKey):
            self.enter = 0
            return

        panel = Panel()
        panel.bg_color = (0.5, 0.5, 0.6, 1.0)

        if labelString is None and configKey != "Fast Nudge":
            labelString = _(
                "Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel."
            ).format(_(configKey))
        elif labelString is None:
            labelString = _(
                "Press a key to assign to the action \"{0}\"\nNo key means right click to fast nudge.\nPress ESC to cancel."
            ).format(_(configKey))
        label = albow.Label(labelString)
        unbind_button = Button("Press to unbind", action=self.unbind)
        column = Column((label, unbind_button))
        panel.add(column)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            keyname = self.root.getKey(evt)
            panel.dismiss(keyname)

        def panelMouseUp(evt):
            button = remapMouseButton(evt.button)
            if button == 3:
                keyname = "Button 3"
            elif button == 4:
                keyname = "Scroll Up"
            elif button == 5:
                keyname = "Scroll Down"
            elif button == 6:
                keyname = "Button 4"
            elif button == 7:
                keyname = "Button 5"
            if button > 2:
                panel.dismiss(keyname)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        self.panel = panel
        keyname = panel.present()
        if type(keyname) is bool:
            return True
        if keyname == "Return" and self.enter == 1:
            self.enter = 0
            self.askAssignKey(configKey)
            return True

        self.enter = 0
        _keyname = _(keyname)
        if keyname != "Escape" and keyname not in [
                "Alt-F4", "F1", "F2", "F3", "F4", "F5", "1", "2", "3", "4",
                "5", "6", "7", "8", "9", "Ctrl-Alt-F9", "Ctrl-Alt-F10"
        ]:
            if "Modifier" in configKey and keyname != "Ctrl" and keyname != "Alt" and keyname != "Shift":
                self.askAssignKey(
                    configKey,
                    _("{0} is not a modifier. Press a new key.\n\nPress ESC to cancel."
                      ).format(_keyname))
                return True
            if configKey in [
                    'Down', 'Up', 'Back', 'Forward', 'Left', 'Right',
                    'Pan Down', 'Pan Up', 'Pan Left', 'Pan Right'
            ]:
                if 'Ctrl' in keyname or '-' in keyname:
                    self.askAssignKey(
                        configKey,
                        "Movement keys can't use Ctrl or be with modifiers. Press a new key.\n\nPress ESC to cancel."
                    )
                    return True
            filter_keys = [
                i for (i, j) in config.config._sections["Filter Keys"].items()
                if j == _keyname
            ]
            if filter_keys:
                self.askAssignKey(
                    configKey,
                    _("Can't bind. {0} is already used by the \"{1}\" filter.\n Press a new key.\n\nPress ESC to cancel."
                      ).format(_keyname, filter_keys[0]))
                return True
            oldkey = config.keys[config.convert(configKey)].get()
            config.keys[config.convert(configKey)].set(keyname)
            if oldkey != keyname and configKey not in self.changes:
                self.changes[configKey] = oldkey
                self.changesNum = True
        elif keyname != "Escape":
            self.askAssignKey(
                configKey,
                _("You can't use the key {0}. Press a new key.\n\nPress ESC to cancel."
                  ).format(_keyname))
            return True

        else:
            return True
예제 #7
0
class FilterTool(EditorTool):
    tooltipText = "Filter"
    toolIconName = "filter"

    def __init__(self, editor):
        EditorTool.__init__(self, editor)

        self.filterModules = {}
        self.savedOptions = {}

        self.updatePanel = Panel()
        updateButton = Button("Update Filters", action=self.updateFilters)
        self.updatePanel.add(updateButton)
        self.updatePanel.shrink_wrap()

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft

    @property
    def statusText(self):
        return "Choose a filter, then click Filter or press Enter to apply it."

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def toolSelected(self):
        self.showPanel()

    @alertException
    def showPanel(self):
        self.panel = FilterToolPanel(self)

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        self.editor.add(self.updatePanel)
        self.reloadFilters()

        self.panel.reload()
        height = self.editor.mainViewport.height - self.editor.toolbar.height
        self.panel.centery = height / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel is None:
            return
        self.panel.close()
        if self.panel.parent:
            self.panel.parent.remove(self.panel)
            self.updatePanel.parent.remove(self.updatePanel)
        self.panel = None

    def updateFilters(self):
        totalFilters = 0
        updatedFilters = 0
        filtersDir = directories.getFiltersDir()
        try:
            os.mkdir(os.path.join(filtersDir, "updates"))
        except OSError:
            pass
        for module in self.filterModules.values():
            totalFilters += 1
            if hasattr(module, "UPDATE_URL") and hasattr(module, "VERSION"):
                if isinstance(module.UPDATE_URL, (str, unicode)) and isinstance(module.VERSION, (str, unicode)):
                    versionJSON = json.loads(urllib2.urlopen(module.UPDATE_URL).read())
                    if module.VERSION != versionJSON["Version"]:
                        urllib.urlretrieve(versionJSON["Download-URL"],
                                           os.path.join(filtersDir, "updates", versionJSON["Name"]))
                        updatedFilters += 1
        for f in os.listdir(os.path.join(filtersDir, "updates")):
            shutil.copy(os.path.join(filtersDir, "updates", f), filtersDir)
        shutil.rmtree(os.path.join(filtersDir, "updates"))
        finishedUpdatingWidget = Widget()
        lbl = Label("Updated %s filter(s) out of %s" % (updatedFilters, totalFilters))
        closeBTN = Button("Close this message", action=finishedUpdatingWidget.dismiss)
        col = Column((lbl, closeBTN))
        finishedUpdatingWidget.bg_color = (0.0, 0.0, 0.6)
        finishedUpdatingWidget.add(col)
        finishedUpdatingWidget.shrink_wrap()
        finishedUpdatingWidget.present()

    def reloadFilters(self):
        filterFiles = []
        unicode_module_names = []

        def searchForFiltersInDir(searchFolder, stock=False):
            for root, folders, files in os.walk(os.path.join(searchFolder), True):
                filter_dir = os.path.basename(root)

                if filter_dir.startswith('demo') or filter_dir.startswith('lib'):
                    continue

                subFolderString = root.replace(searchFolder, "")
                if subFolderString.endswith(os.sep):
                    subFolderString = subFolderString[:len(os.sep)]
                if subFolderString.startswith(os.sep):
                    subFolderString = subFolderString[len(os.sep):]
                if len(subFolderString) > 0:
                    subFolderString = "[" + subFolderString + "]"

                try:
                    root = str(root)
                    if root not in sys.path:
                        sys.path.append(root)
                except UnicodeEncodeError:
                    unicode_module_names.extend([filter_name for filter_name in files])

                for possible_filter in files:
                    if possible_filter.endswith(".py"):
                        filterFiles.append((root, possible_filter, stock, subFolderString))

        searchForFiltersInDir(directories.getFiltersDir(), False)
        searchForFiltersInDir(os.path.join(directories.getDataDir(), "stock-filters"), True)

        filterModules = []

        org_lang = albow.translate.lang


        # If the path has unicode chars, there's no way of knowing what order to add the
        # files to the sys.modules. To fix this, we keep trying to import until we import
        # fail to import all leftover files.
        shouldContinue = True
        while shouldContinue:
            shouldContinue = False
            for f in filterFiles:
                module = tryImport(f[0], f[1], org_lang, f[2], f[3], f[1] in unicode_module_names)
                if module is None:
                    continue
                filterModules.append(module)
                filterFiles.remove(f)
                shouldContinue |= True

        displayNames = []
        for m in filterModules:
            while m.displayName in displayNames:
                m.displayName += "_"
            displayNames.append(m)

        filterModules = filter(lambda mod: hasattr(mod, "perform"), filterModules)
        self.filterModules = collections.OrderedDict(sorted(
            [(FilterTool.moduleDisplayName(x), x) for x in filterModules],
            key=lambda module_name: (module_name[0].lower(),
                                     module_name[1])))

    @staticmethod
    def moduleDisplayName(module):
        subFolderString = getattr(module, 'foldersForDisplayName', "")
        subFolderString = subFolderString if len(subFolderString) < 1 else subFolderString + " "
        name = getattr(module, "displayName", module.__name__)
        return subFolderString + _(name[0].upper() + name[1:])

    @property
    def filterNames(self):
        return [FilterTool.moduleDisplayName(module) for module in self.filterModules.itervalues()]
예제 #8
0
    def bind_key(self, message=None):
        panel = Panel()
        panel.bg_color = (0.5, 0.5, 0.6, 1.0)
        if not message:
            message = _("Press a key to assign to the filter \"{0}\"\n\n"
                        "Press ESC to cancel.").format(self.selectedName)
        label = albow.Label(message)
        unbind_button = Button("Press to unbind", action=self.unbind_key)
        column = Column((label, unbind_button))
        panel.add(column)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            _key_name = self.root.getKey(evt)
            panel.dismiss(_key_name)

        def panelMouseUp(evt):
            button = keys.remapMouseButton(evt.button)
            _key_name = None
            if button == 3:
                _key_name = "Button 3"
            elif button == 4:
                _key_name = "Scroll Up"
            elif button == 5:
                _key_name = "Scroll Down"
            elif button == 6:
                _key_name = "Button 4"
            elif button == 7:
                _key_name = "Button 5"
            if 2 < button < 8:
                panel.dismiss(_key_name)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        self.keys_panel = panel
        key_name = panel.present()

        if type(key_name) is bool:
            return True
        if key_name != "Escape":
            if key_name in [
                    "Alt-F4", "F1", "F2", "F3", "F4", "F5", "1", "2", "3", "4",
                    "5", "6", "7", "8", "9", "Ctrl-Alt-F9", "Ctrl-Alt-F10"
            ]:
                self.bind_key(
                    _("You can't use the key {0}.\n"
                      "Press a key to assign to the filter \"{1}\"\n\n"
                      ""
                      "Press ESC to cancel.").format(_(key_name),
                                                     self.selectedName))
                return True

            keysUsed = [(j, i) for (j, i) in config.config.items("Keys")
                        if i == key_name]
            if keysUsed:
                self.bind_key(
                    _("Can't bind. {0} is already used by {1}.\n"
                      "Press a key to assign to the filter \"{2}\"\n\n"
                      ""
                      "Press ESC to cancel.").format(_(key_name),
                                                     keysUsed[0][0],
                                                     self.selectedName))
                return True

            filter_keys = [
                i for (i, j) in config.config.items("Filter Keys")
                if j == key_name
            ]
            if filter_keys:
                self.bind_key(
                    _("Can't bind. {0} is already used by the \"{1}\" filter.\n"
                      "Press a new key.\n\n"
                      ""
                      "Press ESC to cancel.").format(_(key_name),
                                                     filter_keys[0]))
                return True
            config.config.set("Filter Keys", self.selectedName.lower(),
                              key_name)
        config.save()
        self.reload()
예제 #9
0
    def bind_key(self, message=None):
        panel = Panel()
        panel.bg_color = (0.5, 0.5, 0.6, 1.0)
        if not message:
            message = _("Press a key to assign to the filter \"{0}\"\n\n"
                        "Press ESC to cancel.").format(self.selectedName)
        label = albow.Label(message)
        unbind_button = Button("Press to unbind", action=self.unbind_key)
        column = Column((label, unbind_button))
        panel.add(column)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            _key_name = self.root.getKey(evt)
            panel.dismiss(_key_name)

        def panelMouseUp(evt):
            button = keys.remapMouseButton(evt.button)
            _key_name = None
            if button == 3:
                _key_name = "Button 3"
            elif button == 4:
                _key_name = "Scroll Up"
            elif button == 5:
                _key_name = "Scroll Down"
            elif button == 6:
                _key_name = "Button 4"
            elif button == 7:
                _key_name = "Button 5"
            if 2 < button < 8:
                panel.dismiss(_key_name)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        self.keys_panel = panel
        key_name = panel.present()

        if type(key_name) is bool:
            return True
        if key_name != "Escape":
            if key_name in ["Alt-F4", "F1", "F2", "F3", "F4", "F5", "1", "2", "3",
                            "4", "5", "6", "7", "8", "9", "Ctrl-Alt-F9", "Ctrl-Alt-F10"]:
                self.bind_key(_("You can't use the key {0}.\n"
                                "Press a key to assign to the filter \"{1}\"\n\n"
                                ""
                                "Press ESC to cancel.").format(_(key_name), self.selectedName))
                return True

            keysUsed = [(j, i) for (j, i) in config.config.items("Keys") if i == key_name]
            if keysUsed:
                self.bind_key(_("Can't bind. {0} is already used by {1}.\n"
                                "Press a key to assign to the filter \"{2}\"\n\n"
                                ""
                                "Press ESC to cancel.").format(_(key_name), keysUsed[0][0], self.selectedName))
                return True

            filter_keys = [i for (i, j) in config.config.items("Filter Keys") if j == key_name]
            if filter_keys:
                self.bind_key(_("Can't bind. {0} is already used by the \"{1}\" filter.\n"
                                "Press a new key.\n\n"
                                ""
                                "Press ESC to cancel.").format(_(key_name), filter_keys[0]))
                return True
            config.config.set("Filter Keys", self.selectedName.lower(), key_name)
        config.save()
        self.reload()
예제 #10
0
class FilterTool(EditorTool):
    tooltipText = "Filter"
    toolIconName = "filter"

    def __init__(self, editor):
        EditorTool.__init__(self, editor)

        self.filterModules = {}
        self.savedOptions = {}

        self.updatePanel = Panel(name='Panel.FilterTool.updatePanel')
        updateButton = Button("Update Filters", action=self.updateFilters)
        self.updatePanel.add(updateButton)
        self.updatePanel.shrink_wrap()

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        
        self.optionsPanel = FilterToolOptions(self)

    @property
    def statusText(self):
        return "Choose a filter, then click Filter or press Enter to apply it."

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def toolSelected(self):
        self.showPanel()

    @alertException
    def showPanel(self):
        self.panel = FilterToolPanel(self)

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        self.editor.add(self.updatePanel)
        self.reloadFilters()

        self.panel.reload()
        height = self.editor.mainViewport.height - self.editor.toolbar.height
        self.panel.centery = height / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel is None:
            return
        self.panel.close()
        if self.panel.parent:
            self.panel.parent.remove(self.panel)
            self.updatePanel.parent.remove(self.updatePanel)
        self.panel = None

    def updateFilters(self):
        totalFilters = 0
        updatedFilters = 0
        filtersDir = directories.getFiltersDir()
        try:
            os.mkdir(os.path.join(filtersDir, "updates"))
        except OSError:
            pass
        for module in self.filterModules.values():
            totalFilters += 1
            if hasattr(module, "UPDATE_URL") and hasattr(module, "VERSION"):
                if isinstance(module.UPDATE_URL, (str, unicode)) and isinstance(module.VERSION, (str, unicode)):
                    # Pass on URL or network errors.
                    # This is a basic error hadling, need more refinement to sort errors...
                    update = True
                    try:
                        versionJSON = json.loads(urllib2.urlopen(module.UPDATE_URL).read())
                    except Exception, e:
                        update = False
                        log.warn(" Could not fetch source for %s. System said: %s"%(module.displayName, e))
                    if update and module.VERSION != versionJSON["Version"]:
                        urllib.urlretrieve(versionJSON["Download-URL"],
                                           os.path.join(filtersDir, "updates", versionJSON["Name"]))
                        updatedFilters += 1
        for f in os.listdir(os.path.join(filtersDir, "updates")):
            shutil.copy(os.path.join(filtersDir, "updates", f), filtersDir)
        shutil.rmtree(os.path.join(filtersDir, "updates"))
        finishedUpdatingWidget = Widget()
        lbl = Label("Updated %s filter(s) out of %s" % (updatedFilters, totalFilters))
        closeBTN = Button("Close this message", action=finishedUpdatingWidget.dismiss)
        col = Column((lbl, closeBTN))
        finishedUpdatingWidget.bg_color = (0.0, 0.0, 0.6)
        finishedUpdatingWidget.add(col)
        finishedUpdatingWidget.shrink_wrap()
        finishedUpdatingWidget.present()
예제 #11
0
class FilterTool(EditorTool):
    tooltipText = "Filter"
    toolIconName = "filter"

    def __init__(self, editor):
        EditorTool.__init__(self, editor)

        self.filterModules = {}
        self.savedOptions = {}

        self.updatePanel = Panel()
        updateButton = Button("Update Filters", action=self.updateFilters)
        self.updatePanel.add(updateButton)
        self.updatePanel.shrink_wrap()

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft

    @property
    def statusText(self):
        return "Choose a filter, then click Filter or press Enter to apply it."

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def toolSelected(self):
        self.showPanel()

    @alertException
    def showPanel(self):
        self.panel = FilterToolPanel(self)

        self.updatePanel.bottomleft = self.editor.viewportContainer.bottomleft
        self.editor.add(self.updatePanel)
        self.reloadFilters()

        self.panel.reload()
        height = self.editor.mainViewport.height - self.editor.toolbar.height
        self.panel.centery = height / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left

        self.editor.add(self.panel)

    def hidePanel(self):
        if self.panel is None:
            return
        self.panel.close()
        if self.panel.parent:
            self.panel.parent.remove(self.panel)
            self.updatePanel.parent.remove(self.updatePanel)
        self.panel = None

    def updateFilters(self):
        totalFilters = 0
        updatedFilters = 0
        filtersDir = directories.getFiltersDir()
        try:
            os.mkdir(os.path.join(filtersDir, "updates"))
        except OSError:
            pass
        for module in self.filterModules.values():
            totalFilters += 1
            if hasattr(module, "UPDATE_URL") and hasattr(module, "VERSION"):
                if isinstance(module.UPDATE_URL, (str, unicode)) and isinstance(module.VERSION, (str, unicode)):
                    # Pass on URL or network errors.
                    # This is a basic error hadling, need more refinement to sort errors...
                    update = True
                    try:
                        versionJSON = json.loads(urllib2.urlopen(module.UPDATE_URL).read())
                    except Exception, e:
                        update = False
                        log.warn(" Could not fetch source for %s. System said: %s"%(module.displayName, e))
                    if update and module.VERSION != versionJSON["Version"]:
                        urllib.urlretrieve(versionJSON["Download-URL"],
                                           os.path.join(filtersDir, "updates", versionJSON["Name"]))
                        updatedFilters += 1
        for f in os.listdir(os.path.join(filtersDir, "updates")):
            shutil.copy(os.path.join(filtersDir, "updates", f), filtersDir)
        shutil.rmtree(os.path.join(filtersDir, "updates"))
        finishedUpdatingWidget = Widget()
        lbl = Label("Updated %s filter(s) out of %s" % (updatedFilters, totalFilters))
        closeBTN = Button("Close this message", action=finishedUpdatingWidget.dismiss)
        col = Column((lbl, closeBTN))
        finishedUpdatingWidget.bg_color = (0.0, 0.0, 0.6)
        finishedUpdatingWidget.add(col)
        finishedUpdatingWidget.shrink_wrap()
        finishedUpdatingWidget.present()
예제 #12
0
    def askAssignKey(self, configKey, labelString=None):
        if not self.isConfigKey(configKey):
            self.enter = 0
            return

        panel = Panel()
        panel.bg_color = (0.5, 0.5, 0.6, 1.0)

        if labelString is None:
            labelString = _(
                "Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel. Press Shift-ESC to unbind."
            ).format(configKey)
        label = albow.Label(labelString)
        panel.add(label)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            keyname = self.root.getKey(evt)
            panel.dismiss(keyname)

        def panelMouseUp(evt):
            button = remapMouseButton(evt.button)
            if button == 3:
                keyname = "Button 3"
            elif button == 4:
                keyname = "Scroll Up"
            elif button == 5:
                keyname = "Scroll Down"
            elif button == 6:
                keyname = "Button 4"
            elif button == 7:
                keyname = "Button 5"
            if button > 2:
                panel.dismiss(keyname)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        keyname = panel.present()
        if keyname == "Return" and self.enter == 1:
            self.enter = 0
            self.askAssignKey(
                configKey,
                _("Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel. Press Shift-ESC to unbind."
                  ).format(configKey))
            return True

        self.enter = 0
        if keyname != "Escape" and keyname != "Shift-Escape" and keyname not in [
                "Alt-F4", "F1", "F2", "F3", "F4", "F5", "1", "2", "3", "4",
                "5", "6", "7", "8", "9", "Ctrl-Alt-F9", "Ctrl-Alt-F10"
        ]:
            if "Modifier" in configKey and keyname != "Ctrl" and keyname != "Alt" and keyname != "Shift":
                self.askAssignKey(
                    configKey,
                    _("{0} is not a modifier. "
                      "Press a new key.\n\n"
                      "Press ESC to cancel. Press Shift-ESC to unbind.").
                    format(keyname))
                return True
            if configKey in [
                    'Down', 'Up', 'Back', 'Forward', 'Left', 'Right',
                    'Pan Down', 'Pan Up', 'Pan Left', 'Pan Right'
            ]:
                if 'Ctrl' in keyname:
                    self.askAssignKey(
                        configKey,
                        _("Movement keys can't use Ctrl. "
                          "Press a new key.\n\n"
                          "Press ESC to cancel. Press Shift-ESC to unbind."))
                    return True
            oldkey = config.keys[config.convert(configKey)].get()
            config.keys[config.convert(configKey)].set(keyname)
            if configKey not in self.changes:
                self.changes[configKey] = oldkey
            self.changesNum = True
        elif keyname == "Shift-Escape":
            config.keys[config.convert(configKey)].set("None")
        elif keyname != "Escape":
            self.askAssignKey(
                configKey,
                _("You can't use the key {0}. "
                  "Press a new key.\n\n"
                  "Press ESC to cancel. Press Shift-ESC to unbind.").format(
                      keyname))
            return True

        else:
            return True
예제 #13
0
    def askAssignKey(self, configKey, labelString=None):
        if not self.isConfigKey(configKey):
            self.enter = 0
            return

        panel = Panel(name='Panel.KeyConfigPanel')
        panel.bg_color = (0.3, 0.3, 0.3, 1.0)

        if labelString is None and configKey != "Fast Nudge":
            labelString = _("Press a key to assign to the action \"{0}\"\n\nPress ESC to cancel.").format(_(configKey))
        elif labelString is None:
            labelString = _("Press a key to assign to the action \"{0}\"\nNo key means right click to fast nudge.\nPress ESC to cancel.").format(_(configKey))
        label = albow.Label(labelString)
        unbind_button = Button("Press to unbind", action=self.unbind)
        column = Column((label, unbind_button))
        panel.add(column)
        panel.shrink_wrap()

        def panelKeyUp(evt):
            keyname = self.root.getKey(evt)
            panel.dismiss(keyname)

        def panelMouseUp(evt):
            button = remapMouseButton(evt.button)
            if button == 3:
                keyname = "Button 3"
            elif button == 4:
                keyname = "Scroll Up"
            elif button == 5:
                keyname = "Scroll Down"
            elif button == 6:
                keyname = "Button 4"
            elif button == 7:
                keyname = "Button 5"
            if button > 2:
                panel.dismiss(keyname)

        panel.key_up = panelKeyUp
        panel.mouse_up = panelMouseUp

        self.panel = panel
        keyname = panel.present()
        if isinstance(keyname, bool):
            return True
        if keyname == "Return" and self.enter == 1:
            self.enter = 0
            self.askAssignKey(configKey)
            return True

        self.enter = 0
        _keyname = _(keyname)
        if keyname != "Escape" and keyname not in ("Alt-F4","F1","F2","F3","F4","F5","1","2","3","4","5","6","7","8","9","Ctrl-Alt-F9","Ctrl-Alt-F10"):
            if "Modifier" in configKey and keyname != "Ctrl" and keyname != "Alt" and keyname != "Shift":
                self.askAssignKey(configKey,
                                    _("{0} is not a modifier. Press a new key.\n\nPress ESC to cancel.")
                                    .format(_keyname))
                return True
            if configKey in ('Down','Up','Back','Forward','Left','Right','Pan Down','Pan Up','Pan Left','Pan Right'):
                if 'Ctrl' in keyname or '-' in keyname:
                    self.askAssignKey(configKey,
                                    "Movement keys can't use Ctrl or be with modifiers. Press a new key.\n\nPress ESC to cancel.")
                    return True
            filter_keys = [i for (i, j) in config.config._sections["Filter Keys"].items() if j == _keyname]
            if filter_keys:
                self.askAssignKey(configKey,
                                    _("Can't bind. {0} is already used by the \"{1}\" filter.\n Press a new key.\n\nPress ESC to cancel.").format(_keyname, filter_keys[0]))
                return True
            oldkey = config.keys[config.convert(configKey)].get()
            config.keys[config.convert(configKey)].set(keyname)
            if oldkey != keyname and configKey not in self.changes:
                self.changes[configKey] = oldkey
                self.changesNum = True
        elif keyname != "Escape":
            self.askAssignKey(configKey,
                                    _("You can't use the key {0}. Press a new key.\n\nPress ESC to cancel.")
                                    .format(_keyname))
            return True

        else:
            return True