Beispiel #1
0
 def choosePreset(self):
     preset = self.choiceButton.selectedChoice
     keypairs = self.presets[preset]
     for configKey, k in keypairs:
         oldOne = config.keys[config.convert(configKey)].get()
         if k != oldOne:
             self.changesNum = True
             if configKey not in self.changes:
                 self.changes[configKey] = oldOne
             config.keys[config.convert(configKey)].set(k)
Beispiel #2
0
    def key_down(self, evt):
        keyname = self.root.getKey(evt)
        if keyname == 'Escape':
            if self.changesNum:
                result = albow.ask("Do you want to save your changes?",
                                   ["Save", "Don't Save", "Cancel"])
                if result == "Save":
                    self.done()
                elif result == "Don't Save":
                    for k in self.changes.keys():
                        config.keys[config.convert(k)].set(self.changes[k])
                    self.changesNum = False
                    self.changes = {}
                    self.choiceButton.selectedChoice = self.oldChoice
                    config.save()
                    self.dismiss()
            else:
                self.dismiss()
        elif keyname == 'Up' and self.selectedKeyIndex > 0:
            self.selectedKeyIndex -= 1
        elif keyname == 'Down' and self.selectedKeyIndex < len(
                self.keyConfigKeys) - 1:
            self.selectedKeyIndex += 1
        elif keyname == 'Return':
            self.enter += 1
            self.askAssignSelectedKey()

        self.root.handling_ctrl(evt)
Beispiel #3
0
    def __init__(self, editor):
        GLBackground.__init__(self)
        nudgeLabel = Label("Nudge", margin=8)

        self.editor = editor
        self.add(nudgeLabel)
        self.shrink_wrap()
        self.root = self.get_root()

        # tooltipBacking = Panel()
        # tooltipBacking.bg_color = (0, 0, 0, 0.6)
        keys = [
            _(config.keys[config.convert(k)].get())
            for k in ("forward", "back", "left", "right", "up", "down",
                      "fast nudge")
        ]
        if config.keys[config.convert("fast nudge")].get() == "None":
            keys[6] = _("Right mouse")

        nudgeLabel.tooltipText = _(
            "Click and hold.  While holding, use the movement keys ({0}/{1}/{2}/{3}/{4}/{5}) to nudge. Left mouse to nudge a block.\n{6} to nudge a greater distance."
        ).format(*keys)
Beispiel #4
0
    def getRowData(self, i):
        if self.root is None:
            self.root = self.get_root()
        if self.editor is None:
            self.editor = self.root.editor
        configKey = self.keyConfigKeys[i]
        if self.isConfigKey(configKey):
            key = config.keys[config.convert(configKey)].get()
            try:
                oldKey = key
                key = self.editor.different_keys[key]
                if key != oldKey:
                    config.keys[config.convert(configKey)].set(key)
                    config.save()
            except:
                pass

            if configKey in self.otherNames.keys():
                configKey = self.otherNames[configKey]

        else:
            key = ""
        return configKey, key
Beispiel #5
0
 def cancel(self):
     if self.changesNum:
         result = albow.ask("Do you want to save your changes?", ["Save", "Don't Save", "Cancel"])
         if result == "Save":
             self.done()
         elif result == "Don't Save":
             for k in self.changes.keys():
                 config.keys[config.convert(k)].set(self.changes[k])
             self.changesNum = False
             self.changes = {}
             self.choiceButton.selectedChoice = self.oldChoice
             config.save()
             self.dismiss()
     else:
         self.dismiss()
Beispiel #6
0
    def getRowData(self, i):
        if self.root is None:
            self.root = self.get_root()
        if self.editor is None:
            self.editor = self.root.editor
        configKey = self.keyConfigKeys[i]
        if self.isConfigKey(configKey):
            key = config.keys[config.convert(configKey)].get()
            try:
                key = self.editor.different_keys[key]
            except:
                pass

        else:
            key = ""
        return configKey, key
Beispiel #7
0
    def main(cls):
        PlayerCache().load()
        displayContext = GLDisplayContext(splash.splash, caption=(
        ('MCEdit ~ ' + release.get_version() % _("for")).encode('utf-8'), 'MCEdit'))

        os.environ['SDL_VIDEO_CENTERED'] = '0'

        rootwidget = RootWidget(displayContext.display)
        mcedit = MCEdit(displayContext)
        rootwidget.displayContext = displayContext
        rootwidget.confirm_quit = mcedit.confirm_quit
        rootwidget.mcedit = mcedit

        rootwidget.add(mcedit)
        rootwidget.focus_switch = mcedit

        if mcedit.droppedLevel:
            mcedit.loadFile(mcedit.droppedLevel)

        cls.version_lock = threading.Lock()
        cls.version_info = None
        cls.version_checked = False

        fetch_version_thread = threading.Thread(target=cls.fetch_version)
        fetch_version_thread.start()

        if config.settings.closeMinecraftWarning.get():
            answer = albow.ask(
                "Warning: Only open a world in one program at a time. If you open a world at the same time in MCEdit and in Minecraft, you will lose your work and possibly damage your save file.\n\n If you are using Minecraft 1.3 or earlier, you need to close Minecraft completely before you use MCEdit.",
                ["Don't remind me again.", "OK"], default=1, cancel=1)
            if answer == "Don't remind me again.":
                config.settings.closeMinecraftWarning.set(False)

        if not config.settings.reportCrashesAsked.get():
            answer = albow.ask(
                'Would you like to send anonymous error reports to the MCEdit-Unified Team to help with improving future releases?\n\nError reports are stripped of any identifying user information before being sent.\n\nPyClark, the library used, is open source under the GNU LGPL v3 license and is maintained by Podshot. The source code can be located here: https://github.com/Podshot/pyClark.\n\nThere has been no modification to the library in any form.',
                ['Allow', 'Deny'], default=1, cancel=1
            )
            if answer == 'Allow':
                albow.alert("Error reporting will be enabled next time MCEdit-Unified is launched")
            config.settings.reportCrashes.set(answer == 'Allow')
            config.settings.reportCrashesAsked.set(True)



        config.save()
        if "update" in config.version.version.get():
            answer = albow.ask(
                "There are new default controls. Do you want to replace your current controls with the new ones?",
                ["Yes", "No"])
            if answer == "Yes":
                for configKey, k in keys.KeyConfigPanel.presets["WASD"]:
                    config.keys[config.convert(configKey)].set(k)
        config.version.version.set("1.6.0.0")
        config.save()
        if "-causeError" in sys.argv:
            raise ValueError("Error requested via -causeError")

        while True:
            try:
                rootwidget.run()
            except (SystemExit, KeyboardInterrupt):
                print "Shutting down..."
                exc_txt = traceback.format_exc()
                if mcedit.editor.level:
                    if config.settings.savePositionOnClose.get():
                        mcedit.editor.waypointManager.saveLastPosition(mcedit.editor.mainViewport,
                                                                       mcedit.editor.level.dimNo)
                    mcedit.editor.waypointManager.save()
                # The following Windows specific code won't be executed if we're using '--debug-wm' switch.
                if not USE_WM and sys.platform == "win32" and config.settings.setWindowPlacement.get():
                    (flags, showCmd, ptMin, ptMax, rect) = mcplatform.win32gui.GetWindowPlacement(
                        display.get_wm_info()['window'])
                    X, Y, r, b = rect
                    if (showCmd == mcplatform.win32con.SW_MINIMIZE or
                                showCmd == mcplatform.win32con.SW_SHOWMINIMIZED):
                        showCmd = mcplatform.win32con.SW_SHOWNORMAL

                    config.settings.windowX.set(X)
                    config.settings.windowY.set(Y)
                    config.settings.windowShowCmd.set(showCmd)

                # Restore the previous language if we ran with '-tt' (update translation template).
                if albow.translate.buildTemplate:
                    logging.warning('Restoring %s.' % orglang)
                    config.settings.langCode.set(orglang)
                #
                config.save()
                mcedit.editor.renderer.discardAllChunks()
                mcedit.editor.deleteAllCopiedSchematics()
                if mcedit.editor.level:
                    mcedit.editor.level.close()
                mcedit.editor.root.RemoveEditFiles()
                if 'SystemExit' in traceback.format_exc() or 'KeyboardInterrupt' in traceback.format_exc():
                    raise
                else:
                    if 'SystemExit' in exc_txt:
                        raise SystemExit
                    if 'KeyboardInterrupt' in exc_txt:
                        raise KeyboardInterrupt
            except MemoryError:
                traceback.print_exc()
                mcedit.editor.handleMemoryError()
Beispiel #8
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
Beispiel #9
0
 def unbind(self):
     configKey = self.keyConfigKeys[self.selectedKeyIndex]
     if config.keys[config.convert(configKey)].get() != "None":
         self.changesNum = True
     config.keys[config.convert(configKey)].set("None")
     self.panel.dismiss()
Beispiel #10
0
    def main(cls):
        PlayerCache().load()
        displayContext = GLDisplayContext(
            splash.splash,
            caption=(('MCEdit ~ ' +
                      release.get_version() % _("for")).encode('utf-8'),
                     'MCEdit'))

        os.environ['SDL_VIDEO_CENTERED'] = '0'

        rootwidget = RootWidget(displayContext.display)
        mcedit = MCEdit(displayContext)
        rootwidget.displayContext = displayContext
        rootwidget.confirm_quit = mcedit.confirm_quit
        rootwidget.mcedit = mcedit

        rootwidget.add(mcedit)
        rootwidget.focus_switch = mcedit
        if 0 == len(pymclevel.alphaMaterials.yamlDatas):
            albow.alert(
                "Failed to load minecraft.yaml. Check the console window for details."
            )

        if mcedit.droppedLevel:
            mcedit.loadFile(mcedit.droppedLevel)

        cls.version_lock = threading.Lock()
        cls.version_info = None
        cls.version_checked = False

        fetch_version_thread = threading.Thread(target=cls.fetch_version)
        fetch_version_thread.start()

        # Disabled old update code
        #       if hasattr(sys, 'frozen'):
        #           # We're being run from a bundle, check for updates.
        #           import esky
        #
        #           app = esky.Esky(
        #               sys.executable.decode(sys.getfilesystemencoding()),
        #               'https://bitbucket.org/codewarrior0/mcedit/downloads'
        #           )
        #           try:
        #               update_version = app.find_update()
        #           except:
        #               # FIXME: Horrible, hacky kludge.
        #               update_version = None
        #               logging.exception('Error while checking for updates')
        #
        #           if update_version:
        #               answer = albow.ask(
        #                   'Version "%s" is available, would you like to '
        #                   'download it?' % update_version,
        #                   [
        #                       'Yes',
        #                       'No',
        #                   ],
        #                   default=0,
        #                   cancel=1
        #               )
        #               if answer == 'Yes':
        #                   def callback(args):
        #                       status = args['status']
        #                       status_texts = {
        #                           'searching': u"Finding updates...",
        #                           'found':  u"Found version {new_version}",
        #                           'downloading': u"Downloading: {received} / {size}",
        #                           'ready': u"Downloaded {path}",
        #                           'installing': u"Installing {new_version}",
        #                           'cleaning up': u"Cleaning up...",
        #                           'done': u"Done."
        #                       }
        #                       text = status_texts.get(status, 'Unknown').format(**args)
        #
        #                       panel = Dialog()
        #                       panel.idleevent = lambda event: panel.dismiss()
        #                       label = albow.Label(text, width=600)
        #                       panel.add(label)
        #                       panel.size = (500, 250)
        #                       panel.present()
        #
        #                   try:
        #                       app.auto_update(callback)
        #                   except (esky.EskyVersionError, EnvironmentError):
        #                       albow.alert(_("Failed to install update %s") % update_version)
        #                   else:
        #                       albow.alert(_("Version %s installed. Restart MCEdit to begin using it.") % update_version)
        #                       raise SystemExit()

        if config.settings.closeMinecraftWarning.get():
            answer = albow.ask(
                "Warning: Only open a world in one program at a time. If you open a world at the same time in MCEdit and in Minecraft, you will lose your work and possibly damage your save file.\n\n If you are using Minecraft 1.3 or earlier, you need to close Minecraft completely before you use MCEdit.",
                ["Don't remind me again.", "OK"],
                default=1,
                cancel=1)
            if answer == "Don't remind me again.":
                config.settings.closeMinecraftWarning.set(False)


# Disabled Crash Reporting Option
#       if not config.settings.reportCrashesAsked.get():
#           answer = albow.ask(
#               "When an error occurs, MCEdit can report the details of the error to its developers. "
#               "The error report will include your operating system version, MCEdit version, "
#               "OpenGL version, plus the make and model of your CPU and graphics processor. No personal "
#               "information will be collected.\n\n"
#               "Error reporting can be enabled or disabled in the Options dialog.\n\n"
#               "Enable error reporting?",
#               ["Yes", "No"],
#               default=0)
#           config.settings.reportCrashes.set(answer == "Yes")
#           config.settings.reportCrashesAsked.set(True)
        config.settings.reportCrashes.set(False)
        config.settings.reportCrashesAsked.set(True)

        config.save()
        if "update" in config.version.version.get():
            answer = albow.ask(
                "There are new default controls. Do you want to replace your current controls with the new ones?",
                ["Yes", "No"])
            if answer == "Yes":
                for configKey, k in keys.KeyConfigPanel.presets["WASD"]:
                    config.keys[config.convert(configKey)].set(k)
        config.version.version.set("1.1.2.0")
        config.save()
        if "-causeError" in sys.argv:
            raise ValueError("Error requested via -causeError")

        while True:
            try:
                rootwidget.run()
            except (SystemExit, KeyboardInterrupt):
                print "Shutting down..."
                exc_txt = traceback.format_exc()
                if mcedit.editor.level:
                    if config.settings.savePositionOnClose.get():
                        mcedit.editor.waypointManager.saveLastPosition(
                            mcedit.editor.mainViewport,
                            mcedit.editor.level.getPlayerDimension())
                    mcedit.editor.waypointManager.save()
                # The following Windows specific code won't be executed if we're using '--debug-wm' switch.
                if not USE_WM and sys.platform == "win32" and config.settings.setWindowPlacement.get(
                ):
                    (flags, showCmd, ptMin, ptMax,
                     rect) = mcplatform.win32gui.GetWindowPlacement(
                         display.get_wm_info()['window'])
                    X, Y, r, b = rect
                    #w = r-X
                    #h = b-Y
                    if (showCmd == mcplatform.win32con.SW_MINIMIZE or showCmd
                            == mcplatform.win32con.SW_SHOWMINIMIZED):
                        showCmd = mcplatform.win32con.SW_SHOWNORMAL

                    config.settings.windowX.set(X)
                    config.settings.windowY.set(Y)
                    config.settings.windowShowCmd.set(showCmd)

                # Restore the previous language if we ran with '-tt' (update translation template).
                if albow.translate.buildTemplate:
                    logging.warning('Restoring %s.' % orglang)
                    config.settings.langCode.set(orglang)
                #
                config.save()
                mcedit.editor.renderer.discardAllChunks()
                mcedit.editor.deleteAllCopiedSchematics()
                if mcedit.editor.level:
                    mcedit.editor.level.close()
                mcedit.editor.root.RemoveEditFiles()
                if 'SystemExit' in traceback.format_exc(
                ) or 'KeyboardInterrupt' in traceback.format_exc():
                    raise
                else:
                    if 'SystemExit' in exc_txt:
                        raise SystemExit
                    if 'KeyboardInterrupt' in exc_txt:
                        raise KeyboardInterrupt
            except MemoryError:
                traceback.print_exc()
                mcedit.editor.handleMemoryError()
Beispiel #11
0
    def main(self):
        displayContext = GLDisplayContext()

        rootwidget = RootWidget(displayContext.display)
        mcedit = MCEdit(displayContext)
        rootwidget.displayContext = displayContext
        rootwidget.confirm_quit = mcedit.confirm_quit
        rootwidget.mcedit = mcedit

        rootwidget.add(mcedit)
        rootwidget.focus_switch = mcedit
        if 0 == len(pymclevel.alphaMaterials.yamlDatas):
            albow.alert(
                "Failed to load minecraft.yaml. Check the console window for details."
            )

        if mcedit.droppedLevel:
            mcedit.loadFile(mcedit.droppedLevel)

        new_version = release.check_for_new_version()
        if new_version is not False:
            answer = albow.ask(_('Version {} is available').format(
                new_version["tag_name"]), ['Download', 'View', 'Ignore'],
                               default=1,
                               cancel=2)
            if answer == "View":
                platform_open(new_version["html_url"])
            elif answer == "Download":
                platform_open(new_version["asset"]["browser_download_url"])
                albow.alert(
                    _(' {} should now be downloading via your browser. You will still need to extract the downloaded file to use the updated version.'
                      ).format(new_version["asset"]["name"]))

# Disabled old update code
#       if hasattr(sys, 'frozen'):
#           # We're being run from a bundle, check for updates.
#           import esky
#
#           app = esky.Esky(
#               sys.executable.decode(sys.getfilesystemencoding()),
#               'https://bitbucket.org/codewarrior0/mcedit/downloads'
#           )
#           try:
#               update_version = app.find_update()
#           except:
#               # FIXME: Horrible, hacky kludge.
#               update_version = None
#               logging.exception('Error while checking for updates')
#
#           if update_version:
#               answer = albow.ask(
#                   'Version "%s" is available, would you like to '
#                   'download it?' % update_version,
#                   [
#                       'Yes',
#                       'No',
#                   ],
#                   default=0,
#                   cancel=1
#               )
#               if answer == 'Yes':
#                   def callback(args):
#                       status = args['status']
#                       status_texts = {
#                           'searching': u"Finding updates...",
#                           'found':  u"Found version {new_version}",
#                           'downloading': u"Downloading: {received} / {size}",
#                           'ready': u"Downloaded {path}",
#                           'installing': u"Installing {new_version}",
#                           'cleaning up': u"Cleaning up...",
#                           'done': u"Done."
#                       }
#                       text = status_texts.get(status, 'Unknown').format(**args)
#
#                       panel = Dialog()
#                       panel.idleevent = lambda event: panel.dismiss()
#                       label = albow.Label(text, width=600)
#                       panel.add(label)
#                       panel.size = (500, 250)
#                       panel.present()
#
#                   try:
#                       app.auto_update(callback)
#                   except (esky.EskyVersionError, EnvironmentError):
#                       albow.alert(_("Failed to install update %s") % update_version)
#                   else:
#                       albow.alert(_("Version %s installed. Restart MCEdit to begin using it.") % update_version)
#                       raise SystemExit()

        if config.settings.closeMinecraftWarning.get():
            answer = albow.ask(
                "Warning: Only open a world in one program at a time. If you open a world at the same time in MCEdit and in Minecraft, you will lose your work and possibly damage your save file.\n\n If you are using Minecraft 1.3 or earlier, you need to close Minecraft completely before you use MCEdit.",
                ["Don't remind me again.", "OK"],
                default=1,
                cancel=1)
            if answer == "Don't remind me again.":
                config.settings.closeMinecraftWarning.set(False)


# Disabled Crash Reporting Option
#       if not config.settings.reportCrashesAsked.get():
#           answer = albow.ask(
#               "When an error occurs, MCEdit can report the details of the error to its developers. "
#               "The error report will include your operating system version, MCEdit version, "
#               "OpenGL version, plus the make and model of your CPU and graphics processor. No personal "
#               "information will be collected.\n\n"
#               "Error reporting can be enabled or disabled in the Options dialog.\n\n"
#               "Enable error reporting?",
#               ["Yes", "No"],
#               default=0)
#           config.settings.reportCrashes.set(answer == "Yes")
#           config.settings.reportCrashesAsked.set(True)
        config.settings.reportCrashes.set(False)
        config.settings.reportCrashesAsked.set(True)

        config.save()
        if "update" in config.version.version.get():
            answer = albow.ask(
                "There are new default controls. Do you want to replace your current controls with the new ones?",
                ["Yes", "No"])
            if answer == "Yes":
                for configKey, k in keys.KeyConfigPanel.presets["WASD"]:
                    config.keys[config.convert(configKey)].set(k)
        config.version.version.set("1.1.2.0")
        config.save()
        if "-causeError" in sys.argv:
            raise ValueError, "Error requested via -causeError"

        while True:
            try:
                rootwidget.run()
            except SystemExit:
                if sys.platform == "win32" and config.settings.setWindowPlacement.get(
                ):
                    (flags, showCmd, ptMin, ptMax,
                     rect) = mcplatform.win32gui.GetWindowPlacement(
                         display.get_wm_info()['window'])
                    X, Y, r, b = rect
                    #w = r-X
                    #h = b-Y
                    if (showCmd == mcplatform.win32con.SW_MINIMIZE or showCmd
                            == mcplatform.win32con.SW_SHOWMINIMIZED):
                        showCmd = mcplatform.win32con.SW_SHOWNORMAL

                    config.settings.windowX.set(X)
                    config.settings.windowY.set(Y)
                    config.settings.windowShowCmd.set(showCmd)

                config.save()
                mcedit.editor.renderer.discardAllChunks()
                mcedit.editor.deleteAllCopiedSchematics()
                raise
            except MemoryError:
                traceback.print_exc()
                mcedit.editor.handleMemoryError()
Beispiel #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