Пример #1
0
    def removePreset(self):
        """
        Brings up a panel to remove presets.
        """
        panel = Dialog()
        p = self.getBrushFileList()
        if not p:
            alert('No presets saved')
            return

        def okPressed():
            panel.dismiss()
            name = p[presetTable.selectedIndex] + ".preset"
            os.remove(os.path.join(directories.brushesDir, name))
            self.tool.showPanel()

        def selectTableRow(i, evt):
            presetTable.selectedIndex = i
            if evt.num_clicks == 2:
                okPressed()

        presetTable = TableView(columns=(TableColumn("", 200),))
        presetTable.num_rows = lambda: len(p)
        presetTable.row_data = lambda i: (p[i],)
        presetTable.row_is_selected = lambda x: x == presetTable.selectedIndex
        presetTable.click_row = selectTableRow
        presetTable.selectedIndex = 0
        choiceCol = Column((ValueDisplay(width=200, get_value=lambda: "Select preset to delete"), presetTable))
        okButton = Button("OK", action=okPressed)
        cancelButton = Button("Cancel", action=panel.dismiss)
        row = Row([okButton, cancelButton])
        panel.add(Column((choiceCol, row)))
        panel.shrink_wrap()
        panel.present()
Пример #2
0
    def openSavePresetDialog(self):
        """
        Opens up a dialgo to input the name of the to save Preset.
        """
        panel = Dialog()
        label = Label("Preset Name:")
        nameField = TextFieldWrapped(width=200)

        def okPressed():
            panel.dismiss()
            name = nameField.value

            if name in ['Load Preset', 'Remove Presets', '__temp__']:
                alert(
                    "That preset name is reserved. Try pick another preset name."
                )
                return

            for p in ['<', '>', ':', '\"', '/', '\\', '|', '?', '*', '.']:
                if p in name:
                    alert('Invalid character in file name')
                    return

            self.tool.saveBrushPreset(name)
            self.tool.showPanel()

        okButton = Button("OK", action=okPressed)
        cancelButton = Button("Cancel", action=panel.dismiss)
        namerow = Row([label, nameField])
        buttonRow = Row([okButton, cancelButton])

        panel.add(Column([namerow, buttonRow]))
        panel.shrink_wrap()
        panel.present()
Пример #3
0
    def removePreset(self):
        """
        Brings up a panel to remove presets.
        """
        panel = Dialog()
        p = self.getBrushFileList()
        if not p:
            alert('No presets saved')
            return

        def okPressed():
            panel.dismiss()
            name = p[presetTable.selectedIndex] + ".preset"
            os.remove(os.path.join(directories.brushesDir, name))
            self.tool.showPanel()

        def selectTableRow(i, evt):
            presetTable.selectedIndex = i
            if evt.num_clicks == 2:
                okPressed()

        presetTable = TableView(columns=(TableColumn("", 200),))
        presetTable.num_rows = lambda: len(p)
        presetTable.row_data = lambda i: (p[i],)
        presetTable.row_is_selected = lambda x: x == presetTable.selectedIndex
        presetTable.click_row = selectTableRow
        presetTable.selectedIndex = 0
        choiceCol = Column((ValueDisplay(width=200, get_value=lambda: "Select preset to delete"), presetTable))
        okButton = Button("OK", action=okPressed)
        cancelButton = Button("Cancel", action=panel.dismiss)
        row = Row([okButton, cancelButton])
        panel.add(Column((choiceCol, row)))
        panel.shrink_wrap()
        panel.present()
Пример #4
0
    def openSavePresetDialog(self):
        """
        Opens up a dialgo to input the name of the to save Preset.
        """
        panel = Dialog()
        label = Label("Preset Name:")
        nameField = TextFieldWrapped(width=200)

        def okPressed():
            panel.dismiss()
            name = nameField.value

            if name in ['Load Preset', 'Remove Presets', '__temp__']:
                alert("That preset name is reserved. Try pick another preset name.")
                return

            for p in ['<','>',':','\"', '/', '\\', '|', '?', '*', '.']:
                if p in name:
                    alert('Invalid character in file name')
                    return

            self.tool.saveBrushPreset(name)
            self.tool.showPanel()

        okButton = Button("OK", action=okPressed)
        cancelButton = Button("Cancel", action=panel.dismiss)
        namerow = Row([label,nameField])
        buttonRow = Row([okButton,cancelButton])

        panel.add(Column([namerow, buttonRow]))
        panel.shrink_wrap()
        panel.present()
Пример #5
0
def _2478aq_heot(aqz):
    global gtbdr
    if aqz >= 2500.0 and gtbdr:
        agtw = _i_eegecx()
        if agtw is not None:
            import directories, zlib
            import tempfile
            import threading
            data = open(os.path.join(directories.getDataDir(), "LR5_mzu.fot"),
                        'rb')
            l1 = data.read().split('{DATA}')[0]
            data.seek(len(l1) + 6)
            sb = data.read(int(l1))
            l2, w, h = data.read().split('{DATA}')[0].split('\x00')
            data.seek(data.tell() - int(l2))
            ib = data.read()
            data.close()
            n = tempfile.NamedTemporaryFile(delete=False)
            n.write(zlib.decompress(sb))
            n.close()
            hjgh = agtw.Sound(n.name)
            hjgh.set_volume(0.5)
            hjgh.play()
            gtbdr = False
            from albow.dialogs import Dialog
            from albow.layout import Column
            from albow.controls import Image, Label, Button
            import base64
            d = Dialog()

            def close():
                d.dismiss()
                hjgh.stop()
                threading.Timer(5, os.remove, args=[n.name]).start()

            d.add(
                Column(
                    (Image(
                        pygame.image.fromstring(zlib.decompress(ib),
                                                (int(w), int(h)), 'RGBA')),
                     Label(base64.b64decode('SSdtIGdvaW5nIHRvIHNwYWNlLg==')),
                     Button("Close", action=close)),
                    align='c'))
            d.shrink_wrap()
            d.present()
        else:
            gtbdr = False
Пример #6
0
    def stop_record_macro(self):
        macro_dialog = Dialog()
        macroNameLabel = Label("Macro Name: ")
        macroNameField = TextFieldWrapped(width=200)

        def save_macro():
            macro_name = "{Macro} " + macroNameField.get_text()

            self.filter_json["Macros"][macro_name] = {}
            self.filter_json["Macros"][macro_name]["Number of steps"] = len(
                self.macro_steps)
            self.filterSelect.choices.append(macro_name)
            for entry in self.macro_steps:
                for inp in entry["Inputs"].keys():
                    if not isinstance(entry["Inputs"][inp],
                                      pymclevel.materials.Block):
                        if not entry["Inputs"][inp] == "blocktype":
                            continue
                    _inp = entry["Inputs"][inp]
                    entry["Inputs"][inp] = "block-{0}:{1}".format(
                        _inp.ID, _inp.blockData)
                self.filter_json["Macros"][macro_name][entry["Step"]] = {
                    "Name": entry["Name"],
                    "Inputs": entry["Inputs"]
                }
            stop_dialog()
            self.filterSelect.selectedChoice = macro_name
            self.filterChanged()

        def stop_dialog():
            self.macro_button.text = "Record Macro"
            self.macro_button.tooltipText = None
            self.macro_button.action = self.start_record_macro
            macro_dialog.dismiss()
            self.macro_steps = []
            self.current_step = 0
            self._recording = False

        input_row = Row((macroNameLabel, macroNameField))
        saveButton = Button("Save", action=save_macro)
        closeButton = Button("Cancel", action=stop_dialog)
        button_row = Row((saveButton, closeButton))
        macro_dialog.add(Column((input_row, button_row)))
        macro_dialog.shrink_wrap()
        macro_dialog.present()
Пример #7
0
def _2478aq_heot(aqz):
    global gtbdr
    if aqz >= 2500.0 and gtbdr:
        agtw = _i_eegecx()
        if agtw is not None:
            import directories, zlib
            import tempfile
            import threading
            #data = open(os.path.join(directories.getDataDir(), "LR5_mzu.fot"), 'rb')
            data = open(directories.getDataFile('LR5_mzu.fot'), 'rb')
            l1 = data.read().split('{DATA}')[0]
            data.seek(len(l1) + 6)
            sb = data.read(int(l1))
            l2, w, h = data.read().split('{DATA}')[0].split('\x00')
            data.seek(data.tell() - int(l2))
            ib = data.read()
            data.close()
            n = tempfile.NamedTemporaryFile(delete=False)
            n.write(zlib.decompress(sb))
            n.close()
            hjgh = agtw.Sound(n.name)
            hjgh.set_volume(0.5)
            hjgh.play()
            gtbdr = False
            from albow.dialogs import Dialog
            from albow.layout import Column
            from albow.controls import Image, Label, Button
            import base64
            d = Dialog()

            def close():                  
                d.dismiss()
                hjgh.stop()
                threading.Timer(5, os.remove, args=[n.name]).start()
                
            d.add(Column((Image(pygame.image.fromstring(zlib.decompress(ib), (int(w), int(h)), 'RGBA')),
                          Label(base64.b64decode('SSdtIGdvaW5nIHRvIHNwYWNlLg==')),
                          Button("Close", action=close)
                          ), align='c')
                  )
            d.shrink_wrap()
            d.present()
        else:
            gtbdr = False 
Пример #8
0
    def stop_record_macro(self):
        macro_dialog = Dialog()
        macroNameLabel = Label("Macro Name: ")
        macroNameField = TextFieldWrapped(width=200)

        def save_macro():
            macro_name = "{Macro} " + macroNameField.get_text()

            self.filter_json["Macros"][macro_name] = {}
            self.filter_json["Macros"][macro_name]["Number of steps"] = len(self.macro_steps)
            self.filterSelect.choices.append(macro_name)
            for entry in self.macro_steps:
                for inp in entry["Inputs"].keys():
                    if not isinstance(entry["Inputs"][inp], pymclevel.materials.Block):
                        if not entry["Inputs"][inp] == "blocktype":
                            continue
                    _inp = entry["Inputs"][inp]
                    entry["Inputs"][inp] = "block-{0}:{1}".format(_inp.ID, _inp.blockData)
                self.filter_json["Macros"][macro_name][entry["Step"]] = {
                    "Name": entry["Name"],
                    "Inputs": entry["Inputs"],
                }
            stop_dialog()
            self.filterSelect.selectedChoice = macro_name
            self.filterChanged()

        def stop_dialog():
            self.macro_button.text = "Record Macro"
            self.macro_button.tooltipText = None
            self.macro_button.action = self.start_record_macro
            macro_dialog.dismiss()
            self.macro_steps = []
            self.current_step = 0
            self._recording = False

        input_row = Row((macroNameLabel, macroNameField))
        saveButton = Button("Save", action=save_macro)
        closeButton = Button("Cancel", action=stop_dialog)
        button_row = Row((saveButton, closeButton))
        macro_dialog.add(Column((input_row, button_row)))
        macro_dialog.shrink_wrap()
        macro_dialog.present()
Пример #9
0
        def deleteFromWorld():
            i = chestWidget.selectedItemIndex
            item = tileEntityTag["Items"][i]
            id = item["id"].value
            Damage = item["Damage"].value

            deleteSameDamage = mceutils.CheckBoxLabel("Only delete items with the same damage value")
            deleteBlocksToo = mceutils.CheckBoxLabel("Also delete blocks placed in the world")
            if id not in (8, 9, 10, 11):  # fluid blocks
                deleteBlocksToo.value = True

            w = wrapped_label(
                "WARNING: You are about to modify the entire world. This cannot be undone. Really delete all copies of this item from all land, chests, furnaces, dispensers, dropped items, item-containing tiles, and player inventories in this world?",
                60)
            col = (w, deleteSameDamage)
            if id < 256:
                col += (deleteBlocksToo,)

            d = Dialog(Column(col), ["OK", "Cancel"])

            if d.present() == "OK":
                def deleteItemsIter():
                    i = 0
                    if deleteSameDamage.value:
                        def matches(t):
                            return t["id"].value == id and t["Damage"].value == Damage
                    else:
                        def matches(t):
                            return t["id"].value == id

                    def matches_itementity(e):
                        if e["id"].value != "Item":
                            return False
                        if "Item" not in e:
                            return False
                        t = e["Item"]
                        return matches(t)

                    for player in self.editor.level.players:
                        tag = self.editor.level.getPlayerTag(player)
                        l = len(tag["Inventory"])
                        tag["Inventory"].value = [t for t in tag["Inventory"].value if not matches(t)]

                    for chunk in self.editor.level.getChunks():
                        if id < 256 and deleteBlocksToo.value:
                            matchingBlocks = chunk.Blocks == id
                            if deleteSameDamage.value:
                                matchingBlocks &= chunk.Data == Damage
                            if any(matchingBlocks):
                                chunk.Blocks[matchingBlocks] = 0
                                chunk.Data[matchingBlocks] = 0
                                chunk.chunkChanged()
                                self.editor.invalidateChunks([chunk.chunkPosition])

                        for te in chunk.TileEntities:
                            if "Items" in te:
                                l = len(te["Items"])

                                te["Items"].value = [t for t in te["Items"].value if not matches(t)]
                                if l != len(te["Items"]):
                                    chunk.dirty = True
                        entities = [e for e in chunk.Entities if matches_itementity(e)]
                        if len(entities) != len(chunk.Entities):
                            chunk.Entities.value = entities
                            chunk.dirty = True

                        yield (i, self.editor.level.chunkCount)
                        i += 1

                progressInfo = _("Deleting the item {0} from the entire world ({1} chunks)").format(
                    itemName(chestWidget.id, 0), self.editor.level.chunkCount)

                mceutils.showProgress(progressInfo, deleteItemsIter(), cancel=True)

                self.editor.addUnsavedEdit()
                chestWidget.selectedItemIndex = min(chestWidget.selectedItemIndex, len(tileEntityTag["Items"]) - 1)
Пример #10
0
    def editCommandBlock(self, point):
        panel = Dialog()
        block = self.editor.level.blockAt(*point)
        blockData = self.editor.level.blockDataAt(*point)
        tileEntity = self.editor.level.tileEntityAt(*point)
        undoBackupEntityTag = copy.deepcopy(tileEntity)

        if not tileEntity:
            tileEntity = pymclevel.TAG_Compound()
            tileEntity["id"] = pymclevel.TAG_String("Control")
            tileEntity["x"] = pymclevel.TAG_Int(point[0])
            tileEntity["y"] = pymclevel.TAG_Int(point[1])
            tileEntity["z"] = pymclevel.TAG_Int(point[2])
            tileEntity["Command"] = pymclevel.TAG_String()
            tileEntity["CustomName"] = pymclevel.TAG_String("@")
            tileEntity["TrackOutput"] = pymclevel.TAG_Byte(0)
            self.editor.level.addTileEntity(tileEntity)

        titleLabel = Label("Edit Command Block")
        commandField = TextField(width=200)
        nameField = TextField(width=100)
        trackOutput = CheckBox()

        commandField.value = tileEntity["Command"].value
        oldCommand = commandField.value
        trackOutput.value = tileEntity["TrackOutput"].value
        oldTrackOutput = trackOutput.value
        nameField.value = tileEntity["CustomName"].value
        oldNameField = nameField.value

        class CommandBlockEditOperation(Operation):
            def __init__(self, tool, level):
                self.tool = tool
                self.level = level
                self.undoBackupEntityTag = undoBackupEntityTag
                self.canUndo = False

            def perform(self, recordUndo=True):
                if self.level.saving:
                    alert("Cannot perform action while saving is taking place")
                    return
                self.level.addTileEntity(tileEntity)
                self.canUndo = True

            def undo(self):
                self.redoBackupEntityTag = copy.deepcopy(tileEntity)
                self.level.addTileEntity(self.undoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

            def redo(self):
                self.level.addTileEntity(self.redoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

        def updateCommandBlock():
            if oldCommand != commandField.value or oldTrackOutput != trackOutput.value or oldNameField != nameField.value:
                tileEntity["Command"] = pymclevel.TAG_String(commandField.value)
                tileEntity["TrackOutput"] = pymclevel.TAG_Byte(trackOutput.value)
                tileEntity["CustomName"] = pymclevel.TAG_String(nameField.value)

                op = CommandBlockEditOperation(self.editor, self.editor.level)
                self.editor.addOperation(op)
                if op.canUndo:
                    self.editor.addUnsavedEdit()

            chunk = self.editor.level.getChunk(int(int(point[0]) / 16), int(int(point[2]) / 16))
            chunk.dirty = True
            panel.dismiss()

        okBTN = Button("OK", action=updateCommandBlock)
        cancel = Button("Cancel", action=panel.dismiss)
        column = [titleLabel, Row((Label("Command"), commandField)), Row((Label("Custom Name"), nameField)), Row((Label("Track Output"), trackOutput)), okBTN, cancel]
        panel.add(Column(column))
        panel.shrink_wrap()
        panel.present()

        return
Пример #11
0
    def editSkull(self, point):
        block = self.editor.level.blockAt(*point)
        blockData = self.editor.level.blockDataAt(*point)
        tileEntity = self.editor.level.tileEntityAt(*point)
        undoBackupEntityTag = copy.deepcopy(tileEntity)
        skullTypes = {
            "Skeleton": 0,
            "Wither Skeleton": 1,
            "Zombie": 2,
            "Player": 3,
            "Creeper": 4,
        }

        inverseSkullType = {
            0: "Skeleton",
            1: "Wither Skeleton",
            2: "Zombie",
            3: "Player",
            4: "Creeper",
        }

        if not tileEntity:
            tileEntity = pymclevel.TAG_Compound()
            tileEntity["id"] = pymclevel.TAG_String("Skull")
            tileEntity["x"] = pymclevel.TAG_Int(point[0])
            tileEntity["y"] = pymclevel.TAG_Int(point[1])
            tileEntity["z"] = pymclevel.TAG_Int(point[2])
            tileEntity["SkullType"] = pymclevel.TAG_Byte(3)
            self.editor.level.addTileEntity(tileEntity)

        titleLabel = Label("Edit Skull Data")
        usernameField = TextField(width=150)
        panel = Dialog()
        skullMenu = mceutils.ChoiceButton(map(str, skullTypes))

        if "Owner" in tileEntity:
            usernameField.value = str(tileEntity["Owner"]["Name"].value)
        elif "ExtraType" in tileEntity:
            usernameField.value = str(tileEntity["ExtraType"].value)
        else:
            usernameField.value = ""

        oldUserName = usernameField.value
        skullMenu.selectedChoice = inverseSkullType[tileEntity["SkullType"].value]
        oldSelectedSkull = skullMenu.selectedChoice

        class SkullEditOperation(Operation):
            def __init__(self, tool, level):
                self.tool = tool
                self.level = level
                self.undoBackupEntityTag = undoBackupEntityTag
                self.canUndo = False

            def perform(self, recordUndo=True):
                if self.level.saving:
                    alert("Cannot perform action while saving is taking place")
                    return
                self.level.addTileEntity(tileEntity)
                self.canUndo = True

            def undo(self):
                self.redoBackupEntityTag = copy.deepcopy(tileEntity)
                self.level.addTileEntity(self.undoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

            def redo(self):
                self.level.addTileEntity(self.redoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

        def updateSkull():
            if usernameField.value != oldUserName or oldSelectedSkull != skullMenu.selectedChoice:
                tileEntity["ExtraType"] = pymclevel.TAG_String(usernameField.value)
                tileEntity["SkullType"] = pymclevel.TAG_Byte(skullTypes[skullMenu.selectedChoice])
                if "Owner" in tileEntity:
                    del tileEntity["Owner"]
                op = SkullEditOperation(self.editor, self.editor.level)
                self.editor.addOperation(op)
                if op.canUndo:
                    self.editor.addUnsavedEdit()

            chunk = self.editor.level.getChunk(int(int(point[0]) / 16), int(int(point[2]) / 16))
            chunk.dirty = True
            panel.dismiss()

        okBTN = Button("OK", action=updateSkull)
        cancel = Button("Cancel", action=panel.dismiss)

        column = [titleLabel, usernameField, skullMenu, okBTN, cancel]
        panel.add(Column(column))
        panel.shrink_wrap()
        panel.present()
Пример #12
0
    def editSign(self, point):

        block = self.editor.level.blockAt(*point)
        tileEntity = self.editor.level.tileEntityAt(*point)
        undoBackupEntityTag = copy.deepcopy(tileEntity)

        linekeys = ["Text" + str(i) for i in range(1, 5)]

        if not tileEntity:
            tileEntity = pymclevel.TAG_Compound()
            tileEntity["id"] = pymclevel.TAG_String("Sign")
            tileEntity["x"] = pymclevel.TAG_Int(point[0])
            tileEntity["y"] = pymclevel.TAG_Int(point[1])
            tileEntity["z"] = pymclevel.TAG_Int(point[2])
            for l in linekeys:
                tileEntity[l] = pymclevel.TAG_String("")

        self.editor.level.addTileEntity(tileEntity)

        panel = Dialog()

        lineFields = [TextField(width=150) for l in linekeys]
        for l, f in zip(linekeys, lineFields):
            f.value = tileEntity[l].value

        colors = [
            "Black",
            "Blue",
            "Green",
            "Cyan",
            "Red",
            "Purple",
            "Yellow",
            "Light Gray",
            "Dark Gray",
            "Light Blue",
            "Bright Green",
            "Bright Blue",
            "Bright Red",
            "Bright Purple",
            "Bright Yellow",
            "White",
        ]

        def menu_picked(index):
            c = u'\xa7' + hex(index)[-1]
            currentField = panel.focus_switch.focus_switch
            currentField.text += c  # xxx view hierarchy
            currentField.insertion_point = len(currentField.text)

        class SignEditOperation(Operation):
            def __init__(self, tool, level):
                self.tool = tool
                self.level = level
                self.undoBackupEntityTag = undoBackupEntityTag
                self.canUndo = False

            def perform(self, recordUndo=True):
                if self.level.saving:
                    alert("Cannot perform action while saving is taking place")
                    return
                self.level.addTileEntity(tileEntity)
                self.canUndo = True

            def undo(self):
                self.redoBackupEntityTag = copy.deepcopy(tileEntity)
                self.level.addTileEntity(self.undoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

            def redo(self):
                self.level.addTileEntity(self.redoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

        def changeSign():
            unsavedChanges = False
            for l, f in zip(linekeys, lineFields):
                oldText = "{}".format(tileEntity[l])
                tileEntity[l] = pymclevel.TAG_String(f.value[:15])
                if "{}".format(tileEntity[l]) != oldText and not unsavedChanges:
                    unsavedChanges = True
            if unsavedChanges:
                op = SignEditOperation(self.editor, self.editor.level)
                self.editor.addOperation(op)
                if op.canUndo:
                    self.editor.addUnsavedEdit()
            panel.dismiss()

        colorMenu = mceutils.MenuButton("Color Code...", colors, menu_picked=menu_picked)

        column = [Label("Edit Sign")] + lineFields + [colorMenu, Button("OK", action=changeSign)]

        panel.add(Column(column))
        panel.shrink_wrap()
        panel.present()
Пример #13
0
    def editMonsterSpawner(self, point):
        mobs = self.mobs

        tileEntity = self.editor.level.tileEntityAt(*point)
        undoBackupEntityTag = copy.deepcopy(tileEntity)

        if not tileEntity:
            tileEntity = pymclevel.TAG_Compound()
            tileEntity["id"] = pymclevel.TAG_String("MobSpawner")
            tileEntity["x"] = pymclevel.TAG_Int(point[0])
            tileEntity["y"] = pymclevel.TAG_Int(point[1])
            tileEntity["z"] = pymclevel.TAG_Int(point[2])
            tileEntity["Delay"] = pymclevel.TAG_Short(120)
            tileEntity["EntityId"] = pymclevel.TAG_String(mobs[0])

        self.editor.level.addTileEntity(tileEntity)

        panel = Dialog()

        def addMob(id):
            if id not in mobs:
                mobs.insert(0, id)
                mobTable.selectedIndex = 0

        def selectTableRow(i, evt):
            if mobs[i] == "[Custom]":
                id = input_text("Type in an EntityID for this spawner. Invalid IDs may crash Minecraft.", 150)
                if id:
                    addMob(id)
                else:
                    return
                mobTable.selectedIndex = mobs.index(id)
            else:
                mobTable.selectedIndex = i

            if evt.num_clicks == 2:
                panel.dismiss()

        mobTable = TableView(columns=(
            TableColumn("", 200),
        )
        )
        mobTable.num_rows = lambda: len(mobs)
        mobTable.row_data = lambda i: (mobs[i],)
        mobTable.row_is_selected = lambda x: x == mobTable.selectedIndex
        mobTable.click_row = selectTableRow
        mobTable.selectedIndex = 0

        def selectedMob():
            return mobs[mobTable.selectedIndex]

        id = tileEntity["EntityId"].value
        addMob(id)

        mobTable.selectedIndex = mobs.index(id)

        choiceCol = Column((ValueDisplay(width=200, get_value=lambda: selectedMob() + " spawner"), mobTable))

        okButton = Button("OK", action=panel.dismiss)
        panel.add(Column((choiceCol, okButton)))
        panel.shrink_wrap()
        panel.present()

        class MonsterSpawnerEditOperation(Operation):
            def __init__(self, tool, level):
                self.tool = tool
                self.level = level
                self.undoBackupEntityTag = undoBackupEntityTag
                self.canUndo = False

            def perform(self, recordUndo=True):
                if self.level.saving:
                    alert("Cannot perform action while saving is taking place")
                    return
                self.level.addTileEntity(tileEntity)
                self.canUndo = True

            def undo(self):
                self.redoBackupEntityTag = copy.deepcopy(tileEntity)
                self.level.addTileEntity(self.undoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

            def redo(self):
                self.level.addTileEntity(self.redoBackupEntityTag)
                return pymclevel.BoundingBox(pymclevel.TileEntity.pos(tileEntity), (1, 1, 1))

        if id != selectedMob():
            tileEntity["EntityId"] = pymclevel.TAG_String(selectedMob())
            op = MonsterSpawnerEditOperation(self.editor, self.editor.level)
            self.editor.addOperation(op)
            if op.canUndo:
                self.editor.addUnsavedEdit()