コード例 #1
0
ファイル: mainwindow.py プロジェクト: Tsunder/starcheat
 def new_item_browser(self):
     """Launch a standalone item browser dialog that does write any changes."""
     self.item_browser = ItemBrowser(self.window, True)
     self.item_browser.dialog.show()
コード例 #2
0
ファイル: itemedit.py プロジェクト: Flagowy/starcheat
class ItemEdit():
    def __init__(self, parent, item, player, assets, browser_category="<all>"):
        """Takes an item widget and displays an edit dialog for it."""
        self.dialog = QDialog(parent)
        self.ui = qt_itemedit.Ui_Dialog()
        self.ui.setupUi(self.dialog)

        self.assets = assets
        self.player = player

        self.remember_browser = browser_category
        self.item = item

        # set up signals
        self.ui.load_button.clicked.connect(self.new_item_browser)
        self.ui.variant.itemDoubleClicked.connect(lambda: self.new_item_edit_options(False))
        self.ui.max_button.clicked.connect(self.max_count)
        self.ui.add_option_button.clicked.connect(lambda: self.new_item_edit_options(True))
        self.ui.remove_option_button.clicked.connect(self.remove_option)
        self.ui.edit_option_button.clicked.connect(self.edit_option)
        self.ui.export_button.clicked.connect(self.export_item)
        self.ui.import_button.clicked.connect(self.import_item)
        self.ui.count.valueChanged.connect(self.toggle_max)

        self.make_context_menu()
        self.ui.item_type.setFocus()

    def launch(self):
        if self.item["name"] == "":
            # empty slot
            self.new_item_browser()
            if self.ui.item_type.text() == "":
                return False
        else:
            self.ui.item_type.setText(self.item["name"])
            self.ui.count.setValue(int(self.item["count"]))
            self.update()
        return True

    def update(self):
        self.populate_options()
        self.update_item_info(self.item["name"], self.item["parameters"])

    def make_context_menu(self):
        self.ui.variant.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)

        edit_action = QAction("Edit...", self.ui.variant)
        edit_action.triggered.connect(lambda: self.new_item_edit_options(False))
        self.ui.variant.addAction(edit_action)

        edit_raw_action = QAction("Edit Raw JSON...", self.ui.variant)
        edit_raw_action.triggered.connect(lambda: self.new_item_edit_options(False, True))
        self.ui.variant.addAction(edit_raw_action)

        remove_action = QAction("Remove", self.ui.variant)
        remove_action.triggered.connect(self.remove_option)
        self.ui.variant.addAction(remove_action)

        sep_action = QAction(self.ui.variant)
        sep_action.setSeparator(True)
        self.ui.variant.addAction(sep_action)

        remove_action = QAction("Remove All", self.ui.variant)
        remove_action.triggered.connect(self.clear_item_options)
        self.ui.variant.addAction(remove_action)

    def update_item_info(self, name, data):
        merged = {}
        defaults = self.assets.items().get_item(name)
        if defaults is not None:
            merged.update(defaults[0])
        merged.update(data)

        item_info = "<html><body>"
        item_info += generate_item_info(merged)
        item_info += "</body></html>"
        self.ui.desc.setText(item_info)

        inv_icon = self.assets.items().get_item_icon(name)
        image = self.assets.items().get_item_image(name)

        if inv_icon is not None:
            inv_icon = self.assets.images().color_image(inv_icon, data)
            icon = QPixmap.fromImage(ImageQt(inv_icon))
        elif image is not None:
            image = self.assets.images().color_image(image, data)
            icon = QPixmap.fromImage(ImageQt(image))
        else:
            logging.warning("Unable to load image for %s", name)
            icon = QPixmap.fromImage(QImage.fromData(self.assets.items().missing_icon()))

        icon = self.scale_image_icon(icon, 64, 64)
        self.ui.icon.setPixmap(icon)

    def scale_image_icon(self, qpix, width, height):
        """Scales the image icon to best fit in the width and height bounds
        given. Preserves aspect ratio."""
        scaled_qpix = qpix
        src_width = qpix.width()
        src_height = qpix.height()

        if src_width == src_height and width == height:
            # square image and square bounds
            scaled_qpix = qpix.scaled(width, height)
        elif src_width > src_height:
            # wider than tall needs width scaling to fit
            scaled_qpix = qpix.scaledToWidth(width)
        elif src_height > src_width:
            # taller than wide needs height scaling to fit
            scaled_qpix = qpix.scaledToHeight(height)

        return scaled_qpix

    def update_item(self):
        """Update main item view with current item browser data."""
        name = self.ui.item_type.text()
        item = self.assets.items().get_item(name)
        uuid = self.player.get_uuid()

        generated_item = {
            "generatedgun": lambda: self.assets.items().generate_gun(item),
            "generatedsword": lambda: self.assets.items().generate_sword(item),
            "generatedshield": lambda: self.assets.items().generate_shield(item),
            "sapling": lambda: self.assets.items().generate_sapling(item),
            "filledcapturepod": lambda: self.assets.items().generate_filledcapturepod(item, uuid)
        }

        if item is not None:
            category = re.search("\..+$", item[1])
            gen_match_cat = (category is not None and
                             category.group()[1:] in generated_item.keys())
            gen_match_name = name in generated_item.keys()

            if gen_match_cat:
                name = category.group()[1:]
                self.ui.item_type.setText(name)
                generated = generated_item[name]()
                self.item = saves.new_item_data(name, 1, generated)
            elif gen_match_name:
                generated = generated_item[name]()
                self.item = saves.new_item_data(name, 1, generated)
            else:
                self.item = saves.new_item_data(name, 1, item[0])

            self.ui.count.setValue(1)
            self.update()
            return True
        else:
            self.item = saves.new_item_data("", 1)
            self.ui.desc.setText("<html><body><strong>Empty Slot</strong></body></html>")
            self.update()
            return False

    def get_item(self):
        """Return an ItemWidget of the currently open item."""
        name = self.ui.item_type.text()
        count = self.ui.count.value()
        data = self.item["parameters"]
        return saves.new_item_data(name, count, data)

    def clear_item_options(self):
        self.ui.variant.clear()
        self.ui.variant.setHorizontalHeaderLabels(["Parameters"])
        self.ui.variant.setRowCount(0)
        if self.item is not None:
            self.item["parameters"] = {}
            self.update()

    def new_item_edit_options(self, new=False, raw=False):
        """Edit the selected item option with custom dialog."""

        if new:
            selected = ItemOptionWidget("", None)
        else:
            selected = self.ui.variant.currentItem()

        dialog = None
        name, value = selected.option

        # TODO: drawable images
        # TODO: status effects
        # TODO: color editing

        if new or raw:
            dialog = ItemEditOptions(self.dialog, name, value)

            def save():
                name, value = dialog.get_option()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()
        elif name in ["inventoryIcon", "image", "largeImage"] and type(value) is str:
            dialog = ImageBrowser(self.dialog, self.assets, False)

            def save():
                value = dialog.get_key()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()
        elif type(value) is str:
            text, ok = QInputDialog.getText(self.dialog, "Edit Text", name, text=value)
            if ok:
                value = text
                self.item["parameters"][name] = value
        elif type(value) is int:
            num, ok = QInputDialog.getInt(self.dialog, "Edit Integer", name, value)
            if ok:
                value = num
                self.item["parameters"][name] = value
        elif type(value) is float:
            num, ok = QInputDialog.getDouble(self.dialog, "Edit Double", name, value, decimals=2)
            if ok:
                value = num
                self.item["parameters"][name] = value
        elif type(value) is bool:
            value = not value
            self.item["parameters"][name] = value
        else:
            dialog = ItemEditOptions(self.dialog, name, value)

            def save():
                name, value = dialog.get_option()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()

        self.update()

    def remove_option(self):
        """Remove the currently selected item option."""
        current = self.ui.variant.currentItem()
        if current is None:
            return
        self.item["parameters"].pop(current.option[0])
        self.update()

    def edit_option(self):
        """Edit currently selected item option."""
        current = self.ui.variant.currentItem()
        if current is not None:
            self.new_item_edit_options()
            self.update()

    def new_item_browser(self):
        self.item_browser = ItemBrowser(self.dialog, category=self.remember_browser)
        self.item_browser.dialog.accepted.connect(self.set_item_browser_selection)
        self.item_browser.dialog.exec()

    def set_item_browser_selection(self):
        name = self.item_browser.get_selection()
        if name is None:
            return
        self.remember_browser = self.item_browser.remember_category
        self.ui.item_type.setText(name)
        self.update_item()

    def populate_options(self):
        self.ui.variant.setRowCount(len(self.item["parameters"]))
        self.ui.variant.setHorizontalHeaderLabels(["Parameters"])
        row = 0
        for k in sorted(self.item["parameters"].keys()):
            variant = ItemOptionWidget(k, self.item["parameters"][k])
            self.ui.variant.setItem(row, 0, variant)
            row += 1

    def max_count(self):
        if "maxStack" in self.item["parameters"]:
            max = int(self.item["parameters"]["maxStack"])
        else:
            max = 1000
        self.ui.count.setValue(max)

    def toggle_max(self):
        value = self.ui.count.value()
        self.ui.max_button.setEnabled(value != 1000)

    def export_item(self):
        json_data = json.dumps(self.item, sort_keys=True,
                               indent=4, separators=(',', ': '))
        filename = QFileDialog.getSaveFileName(self.dialog,
                                               "Export Item As",
                                               filter="JSON (*.json);;All Files (*)")
        if filename[0] != "":
            json_file = open(filename[0], "w")
            json_file.write(json_data)
            json_file.close()

    def import_item(self):
        item = import_json(self.dialog)
        if item is False:
            dialog = QMessageBox(self.dialog)
            dialog.setWindowTitle("Import Error")
            dialog.setText("Could not import requested item file.")
            dialog.setInformativeText("See starcheat log for more details.")
            dialog.setStandardButtons(QMessageBox.Close)
            dialog.setIcon(QMessageBox.Critical)
            dialog.exec()
        elif item is None:
            pass
        else:
            self.ui.item_type.setText(item["name"])
            self.ui.count.setValue(item["count"])
            self.item = item
            self.update()
コード例 #3
0
ファイル: itemedit.py プロジェクト: Flagowy/starcheat
 def new_item_browser(self):
     self.item_browser = ItemBrowser(self.dialog, category=self.remember_browser)
     self.item_browser.dialog.accepted.connect(self.set_item_browser_selection)
     self.item_browser.dialog.exec()
コード例 #4
0
ファイル: itemedit.py プロジェクト: Saxithon/starcheat
class ItemEdit():
    def __init__(self, parent, item, player, browser_category="<all>"):
        """Takes an item widget and displays an edit dialog for it."""
        self.dialog = QDialog(parent)
        self.ui = qt_itemedit.Ui_Dialog()
        self.ui.setupUi(self.dialog)

        assets_db_file = Config().read("assets_db")
        starbound_folder = Config().read("starbound_folder")
        self.assets = assets.Assets(assets_db_file, starbound_folder)

        self.player = player

        self.item_browser = None
        self.remember_browser = browser_category
        self.item = copy.deepcopy(item)

        if self.item["name"] != "":
            # set name text box
            self.ui.item_type.setText(self.item["name"])
            # set item count spinbox
            self.ui.count.setValue(int(self.item["count"]))
            # set up variant table
            self.populate_options()
            self.update_item_info(self.item["name"], self.item["parameters"])
        else:
            # empty slot
            self.new_item_browser()
            self.update_item()

        # set up signals
        self.ui.load_button.clicked.connect(self.new_item_browser)
        self.ui.item_type.textChanged.connect(self.update_item)
        self.ui.variant.itemDoubleClicked.connect(lambda: self.new_item_edit_options(False))
        self.ui.max_button.clicked.connect(self.max_count)
        self.ui.add_option_button.clicked.connect(lambda: self.new_item_edit_options(True))
        self.ui.remove_option_button.clicked.connect(self.remove_option)
        self.ui.edit_option_button.clicked.connect(self.edit_option)
        self.ui.export_button.clicked.connect(self.export_item)
        self.ui.import_button.clicked.connect(self.import_item)

        self.ui.item_type.setFocus()

    def update_item_info(self, name, data):
        item_info = "<html><body>"
        item_info += generate_item_info(data)
        item_info += "</body></html>"
        self.ui.desc.setText(item_info)

        inv_icon_file = self.assets.items().get_item_icon(name)
        if inv_icon_file is not None:
            icon = QPixmap.fromImage(ImageQt(inv_icon_file))
        else:
            image_file = self.assets.items().get_item_image(name)
            if image_file is not None:
                icon = QPixmap.fromImage(ImageQt(image_file))
            else:
                icon = QPixmap.fromImage(QImage.fromData(self.assets.items().missing_icon()))
        # last ditch
        try:
            icon = self.scale_image_icon(icon,64,64)
            self.ui.icon.setPixmap(icon)
        except TypeError:
            logging.warning("Unable to load item image: "+name)
            self.ui.icon.setPixmap(QPixmap())

    def scale_image_icon(self, qpix, width, height):
        """Scales the image icon to best fit in the width and height bounds given. Preserves aspect ratio."""
        scaled_qpix = qpix
        src_width = qpix.width()
        src_height = qpix.height()

        if src_width == src_height and width == height: #square image and square bounds
            scaled_qpix = qpix.scaled(width,height)
        elif src_width > src_height: #wider than tall needs width scaling to fit
            scaled_qpix = qpix.scaledToWidth(width)
        elif src_height > src_width: #taller than wide needs height scaling to fit
            scaled_qpix = qpix.scaledToHeight(height)
        return scaled_qpix

    def update_item(self):
        """Update main item view with current item browser data."""
        name = self.ui.item_type.text()

        # TODO: i guess eventually we're gonna need like.. some sort of generic
        # generate item function
        try:
            item = self.assets.items().get_item(name)
            if item[1].endswith("generatedgun"):
                options = self.assets.items().generate_gun(item)
                name = options["itemName"]
            elif item[1].endswith("generatedsword"):
                options = self.assets.items().generate_sword(item)
                name = options["itemName"]
            elif item[1].endswith("generatedshield"):
                options = self.assets.items().generate_shield(item)
                name = options["itemName"]
            elif item[1].endswith("sapling"):
                options = self.assets.items().generate_sapling(item)
            elif name == "filledcapturepod":
                options = self.assets.items().generate_filledcapturepod(item,
                                                                        self.player.get_uuid())
            else:
                options = item[0]
        except TypeError:
            self.item = empty_slot().item
            self.ui.desc.setText("<html><body><strong>Empty Slot</strong></body></html>")
            self.ui.icon.setPixmap(QPixmap())
            self.clear_item_options()
            return

        self.ui.item_type.setText(name)

        self.item = saves.new_item_data(name, 1, options)

        self.ui.count.setValue(1)
        self.update_item_info(name, options)
        self.populate_options()

    def get_item(self):
        """Return an ItemWidget of the currently open item."""
        name = self.ui.item_type.text()
        count = self.ui.count.value()
        data = self.item["parameters"]
        return saves.new_item_data(name, count, data)

    def clear_item_options(self):
        self.ui.variant.clear()
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        self.ui.variant.setRowCount(0)
        if self.item is not None:
            self.item["parameters"] = {}

    def new_item_edit_options(self, new):
        """Edit the selected item option with custom dialog."""

        if new:
            selected = ItemOptionWidget("", None)
        else:
            selected = self.ui.variant.currentItem()

        # TODO: need a better way to lay this out. it's going to get big and messy fast

        # this is for the qinputdialog stuff. can't set signals on them
        generic = False
        if new:
            # needs to be here or new opts get detected as string (?)
            dialog = ItemEditOptions(self.dialog, selected.option[0], selected.option[1])
            def get_option():
                data = dialog.ui.options.toPlainText()
                return dialog.ui.name.text(), json.loads(data)
        #elif selected.option[0] in ["inventoryIcon", "image", "largeImage"]:
        #    dialog = ImageBrowser(self.dialog, self.assets)
        #    def get_option():
        #        return selected.option[0], dialog.get_key()
        elif type(self.item["parameters"][selected.option[0]]) is str:
            generic = True
            text, ok = QInputDialog.getText(self.dialog, "Edit Text", selected.option[0],
                                            text=self.item["parameters"][selected.option[0]])
            if ok:
                self.item["parameters"][selected.option[0]] = text
        elif type(self.item["parameters"][selected.option[0]]) is int:
            generic = True
            num, ok = QInputDialog.getInt(self.dialog, "Edit Integer", selected.option[0],
                                          self.item["parameters"][selected.option[0]])
            if ok:
                self.item["parameters"][selected.option[0]] = num
        elif type(self.item["parameters"][selected.option[0]]) is float:
            generic = True
            num, ok = QInputDialog.getDouble(self.dialog, "Edit Double", selected.option[0],
                                             self.item["parameters"][selected.option[0]], decimals=2)
            if ok:
                self.item["parameters"][selected.option[0]] = num
        elif type(self.item["parameters"][selected.option[0]]) is bool:
            generic = True
            self.item["parameters"][selected.option[0]] = not self.item["parameters"][selected.option[0]]
        else:
            dialog = ItemEditOptions(self.dialog, selected.option[0], selected.option[1])
            def get_option():
                data = dialog.ui.options.toPlainText()
                return dialog.ui.name.text(), json.loads(data)

        def save():
            new_option = get_option()
            self.item["parameters"][new_option[0]] = new_option[1]

        if not generic:
            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()

        self.populate_options()
        self.update_item_info(self.item["name"], self.item["parameters"])

    def remove_option(self):
        """Remove the currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.item["parameters"].pop(option_name)
        self.populate_options()

    def edit_option(self):
        """Edit currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.new_item_edit_options(False)

    def new_item_browser(self):
        self.item_browser = ItemBrowser(self.dialog, category=self.remember_browser)
        self.item_browser.dialog.accepted.connect(self.set_item_browser_selection)
        self.item_browser.dialog.exec()

    def populate_options(self):
        self.ui.variant.setRowCount(len(self.item["parameters"]))
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        row = 0
        for k in sorted(self.item["parameters"].keys()):
            variant = ItemOptionWidget(k, self.item["parameters"][k])
            self.ui.variant.setItem(row, 0, variant)
            row += 1

    def set_item_browser_selection(self):
        name = self.item_browser.get_selection()
        if name is None:
            return
        self.remember_browser = self.item_browser.remember_category
        self.ui.item_type.setText(name)

    def max_count(self):
        if "maxStack" in self.item["parameters"]:
            max = int(self.item["parameters"]["maxStack"])
        else:
            max = 1000
        self.ui.count.setValue(max)

    def export_item(self):
        json_data = json.dumps(self.item, sort_keys=True,
                               indent=4, separators=(',', ': '))
        filename = QFileDialog.getSaveFileName(self.dialog,
                                               "Export Item As")
        if filename[0] != "":
            json_file = open(filename[0], "w")
            json_file.write(json_data)
            json_file.close()

    def import_item(self):
        filename = QFileDialog.getOpenFileName(self.dialog,
                                               "Import Item File")
        def parse():
            try:
                item_data = json.load(open(filename[0], "r"))
            except:
                logging.exception("Error parsing item: %s", filename[0])
                return False
            if "name" not in item_data:
                return False
            if "count" not in item_data:
                item_data["count"] = 1
            if "data" not in item_data:
                item_data["parameters"] = {}
            return item_data

        item = parse()
        if not item:
            logging.warning("Invalid item file: %s", filename[0])
            return
        else:
            self.ui.item_type.setText(item["name"])
            self.item = item
            self.ui.count.setValue(self.item["count"])
            self.update_item_info(self.item["name"], self.item["parameters"])
            self.populate_options()
コード例 #5
0
 def new_item_browser(self):
     self.item_browser = ItemBrowser(self.dialog,
                                     category=self.remember_browser)
     self.item_browser.dialog.accepted.connect(
         self.set_item_browser_selection)
     self.item_browser.dialog.exec()
コード例 #6
0
class ItemEdit():
    def __init__(self, parent, item, player, assets, browser_category="<all>"):
        """Takes an item widget and displays an edit dialog for it."""
        self.dialog = QDialog(parent)
        self.ui = qt_itemedit.Ui_Dialog()
        self.ui.setupUi(self.dialog)

        self.assets = assets
        self.player = player

        self.remember_browser = browser_category
        self.item = item

        # set up signals
        self.ui.load_button.clicked.connect(self.new_item_browser)
        self.ui.variant.itemDoubleClicked.connect(
            lambda: self.new_item_edit_options(False))
        self.ui.max_button.clicked.connect(self.max_count)
        self.ui.add_option_button.clicked.connect(
            lambda: self.new_item_edit_options(True))
        self.ui.remove_option_button.clicked.connect(self.remove_option)
        self.ui.edit_option_button.clicked.connect(self.edit_option)
        self.ui.export_button.clicked.connect(self.export_item)
        self.ui.import_button.clicked.connect(self.import_item)
        self.ui.count.valueChanged.connect(self.toggle_max)

        self.make_context_menu()
        self.ui.item_type.setFocus()

    def launch(self):
        if self.item["name"] == "":
            # empty slot
            self.new_item_browser()
            if self.ui.item_type.text() == "":
                return False
        else:
            self.ui.item_type.setText(self.item["name"])
            self.ui.count.setValue(int(self.item["count"]))
            self.update()
        return True

    def update(self):
        self.populate_options()
        self.update_item_info(self.item["name"], self.item["parameters"])

    def make_context_menu(self):
        self.ui.variant.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)

        edit_action = QAction("Edit...", self.ui.variant)
        edit_action.triggered.connect(
            lambda: self.new_item_edit_options(False))
        self.ui.variant.addAction(edit_action)

        edit_raw_action = QAction("Edit Raw JSON...", self.ui.variant)
        edit_raw_action.triggered.connect(
            lambda: self.new_item_edit_options(False, True))
        self.ui.variant.addAction(edit_raw_action)

        remove_action = QAction("Remove", self.ui.variant)
        remove_action.triggered.connect(self.remove_option)
        self.ui.variant.addAction(remove_action)

        sep_action = QAction(self.ui.variant)
        sep_action.setSeparator(True)
        self.ui.variant.addAction(sep_action)

        remove_action = QAction("Remove All", self.ui.variant)
        remove_action.triggered.connect(self.clear_item_options)
        self.ui.variant.addAction(remove_action)

    def update_item_info(self, name, data):
        merged = {}
        defaults = self.assets.items().get_item(name)
        if defaults is not None:
            merged.update(defaults[0])
        merged.update(data)

        item_info = "<html><body>"
        item_info += generate_item_info(merged)
        item_info += "</body></html>"
        self.ui.desc.setText(item_info)

        inv_icon = self.assets.items().get_item_icon(name)
        image = self.assets.items().get_item_image(name)

        if inv_icon is not None:
            inv_icon = self.assets.images().color_image(inv_icon, data)
            icon = QPixmap.fromImage(ImageQt(inv_icon))
        elif image is not None:
            image = self.assets.images().color_image(image, data)
            icon = QPixmap.fromImage(ImageQt(image))
        else:
            logging.warning("Unable to load image for %s", name)
            icon = QPixmap.fromImage(
                QImage.fromData(self.assets.items().missing_icon()))

        icon = self.scale_image_icon(icon, 64, 64)
        self.ui.icon.setPixmap(icon)

    def scale_image_icon(self, qpix, width, height):
        """Scales the image icon to best fit in the width and height bounds
        given. Preserves aspect ratio."""
        scaled_qpix = qpix
        src_width = qpix.width()
        src_height = qpix.height()

        if src_width == src_height and width == height:
            # square image and square bounds
            scaled_qpix = qpix.scaled(width, height)
        elif src_width > src_height:
            # wider than tall needs width scaling to fit
            scaled_qpix = qpix.scaledToWidth(width)
        elif src_height > src_width:
            # taller than wide needs height scaling to fit
            scaled_qpix = qpix.scaledToHeight(height)

        return scaled_qpix

    def update_item(self):
        """Update main item view with current item browser data."""
        name = self.ui.item_type.text()
        item = self.assets.items().get_item(name)
        uuid = self.player.get_uuid()

        generated_item = {
            "generatedgun":
            lambda: self.assets.items().generate_gun(item),
            "generatedsword":
            lambda: self.assets.items().generate_sword(item),
            "generatedshield":
            lambda: self.assets.items().generate_shield(item),
            "sapling":
            lambda: self.assets.items().generate_sapling(item),
            "filledcapturepod":
            lambda: self.assets.items().generate_filledcapturepod(item, uuid)
        }

        if item is not None:
            category = re.search("\..+$", item[1])
            gen_match_cat = (category is not None
                             and category.group()[1:] in generated_item.keys())
            gen_match_name = name in generated_item.keys()

            if gen_match_cat:
                name = category.group()[1:]
                self.ui.item_type.setText(name)
                generated = generated_item[name]()
                self.item = saves.new_item_data(name, 1, generated)
            elif gen_match_name:
                generated = generated_item[name]()
                self.item = saves.new_item_data(name, 1, generated)
            else:
                self.item = saves.new_item_data(name, 1, item[0])

            self.ui.count.setValue(1)
            self.update()
            return True
        else:
            self.item = saves.new_item_data("", 1)
            self.ui.desc.setText(
                "<html><body><strong>Empty Slot</strong></body></html>")
            self.update()
            return False

    def get_item(self):
        """Return an ItemWidget of the currently open item."""
        name = self.ui.item_type.text()
        count = self.ui.count.value()
        data = self.item["parameters"]
        return saves.new_item_data(name, count, data)

    def clear_item_options(self):
        self.ui.variant.clear()
        self.ui.variant.setHorizontalHeaderLabels(["Parameters"])
        self.ui.variant.setRowCount(0)
        if self.item is not None:
            self.item["parameters"] = {}
            self.update()

    def new_item_edit_options(self, new=False, raw=False):
        """Edit the selected item option with custom dialog."""

        if new:
            selected = ItemOptionWidget("", None)
        else:
            selected = self.ui.variant.currentItem()

        dialog = None
        name, value = selected.option

        # TODO: drawable images
        # TODO: status effects
        # TODO: color editing

        if new or raw:
            dialog = ItemEditOptions(self.dialog, name, value)

            def save():
                name, value = dialog.get_option()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()
        elif name in ["inventoryIcon", "image", "largeImage"
                      ] and type(value) is str:
            dialog = ImageBrowser(self.dialog, self.assets, False)

            def save():
                value = dialog.get_key()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()
        elif type(value) is str:
            text, ok = QInputDialog.getText(self.dialog,
                                            "Edit Text",
                                            name,
                                            text=value)
            if ok:
                value = text
                self.item["parameters"][name] = value
        elif type(value) is int:
            num, ok = QInputDialog.getInt(self.dialog, "Edit Integer", name,
                                          value)
            if ok:
                value = num
                self.item["parameters"][name] = value
        elif type(value) is float:
            num, ok = QInputDialog.getDouble(self.dialog,
                                             "Edit Double",
                                             name,
                                             value,
                                             decimals=2)
            if ok:
                value = num
                self.item["parameters"][name] = value
        elif type(value) is bool:
            value = not value
            self.item["parameters"][name] = value
        else:
            dialog = ItemEditOptions(self.dialog, name, value)

            def save():
                name, value = dialog.get_option()
                self.item["parameters"][name] = value

            dialog.dialog.accepted.connect(save)
            dialog.dialog.exec()

        self.update()

    def remove_option(self):
        """Remove the currently selected item option."""
        current = self.ui.variant.currentItem()
        if current is None:
            return
        self.item["parameters"].pop(current.option[0])
        self.update()

    def edit_option(self):
        """Edit currently selected item option."""
        current = self.ui.variant.currentItem()
        if current is not None:
            self.new_item_edit_options()
            self.update()

    def new_item_browser(self):
        self.item_browser = ItemBrowser(self.dialog,
                                        category=self.remember_browser)
        self.item_browser.dialog.accepted.connect(
            self.set_item_browser_selection)
        self.item_browser.dialog.exec()

    def set_item_browser_selection(self):
        name = self.item_browser.get_selection()
        if name is None:
            return
        self.remember_browser = self.item_browser.remember_category
        self.ui.item_type.setText(name)
        self.update_item()

    def populate_options(self):
        self.ui.variant.setRowCount(len(self.item["parameters"]))
        self.ui.variant.setHorizontalHeaderLabels(["Parameters"])
        row = 0
        for k in sorted(self.item["parameters"].keys()):
            variant = ItemOptionWidget(k, self.item["parameters"][k])
            self.ui.variant.setItem(row, 0, variant)
            row += 1

    def max_count(self):
        if "maxStack" in self.item["parameters"]:
            max = int(self.item["parameters"]["maxStack"])
        else:
            max = 1000
        self.ui.count.setValue(max)

    def toggle_max(self):
        value = self.ui.count.value()
        self.ui.max_button.setEnabled(value != 1000)

    def export_item(self):
        json_data = json.dumps(self.item,
                               sort_keys=True,
                               indent=4,
                               separators=(',', ': '))
        filename = QFileDialog.getSaveFileName(
            self.dialog,
            "Export Item As",
            filter="JSON (*.json);;All Files (*)")
        if filename[0] != "":
            json_file = open(filename[0], "w")
            json_file.write(json_data)
            json_file.close()

    def import_item(self):
        item = import_json(self.dialog)
        if item is False:
            dialog = QMessageBox(self.dialog)
            dialog.setWindowTitle("Import Error")
            dialog.setText("Could not import requested item file.")
            dialog.setInformativeText("See Starcheat log for more details.")
            dialog.setStandardButtons(QMessageBox.Close)
            dialog.setIcon(QMessageBox.Critical)
            dialog.exec()
        elif item is None:
            pass
        else:
            self.ui.item_type.setText(item["name"])
            self.ui.count.setValue(item["count"])
            self.item = item
            self.update()
コード例 #7
0
ファイル: itemedit.py プロジェクト: Septarius/starcheat
class ItemEdit():
    def __init__(self, parent, item, player, browser_category="<all>"):
        """Takes an item widget and displays an edit dialog for it."""
        self.dialog = QDialog(parent)
        self.ui = qt_itemedit.Ui_Dialog()
        self.ui.setupUi(self.dialog)

        assets_db_file = Config().read("assets_db")
        starbound_folder = Config().read("starbound_folder")
        self.assets = assets.Assets(assets_db_file, starbound_folder)

        self.player = player

        self.item_browser = None
        self.remember_browser = browser_category
        self.item = copy.deepcopy(item)

        if self.item["name"] != "":
            # set name text box
            self.ui.item_type.setText(self.item["name"])
            # set item count spinbox
            self.ui.count.setValue(int(self.item["count"]))
            # set up variant table
            self.populate_options()
            self.update_item_info(self.item["name"], self.item["data"])
        else:
            # empty slot
            self.new_item_browser()
            self.update_item()

        # set up signals
        self.ui.load_button.clicked.connect(self.new_item_browser)
        self.ui.item_type.textChanged.connect(self.update_item)
        self.ui.variant.itemDoubleClicked.connect(lambda: self.new_item_edit_options(False))
        self.ui.max_button.clicked.connect(self.max_count)
        self.ui.add_option_button.clicked.connect(lambda: self.new_item_edit_options(True))
        self.ui.remove_option_button.clicked.connect(self.remove_option)
        self.ui.edit_option_button.clicked.connect(self.edit_option)
        self.ui.export_button.clicked.connect(self.export_item)
        self.ui.import_button.clicked.connect(self.import_item)

        self.ui.item_type.setFocus()

    def update_item_info(self, name, data):
        item_info = "<html><body>"

        try:
            item_info += "<strong>" + data["shortdescription"] + "</strong>"
        except KeyError:
            try:
                item_info += "<strong>" + self.assets.items().get_item(name)[0]["shortdescription"] + "</strong>"
            except:
                pass

        try:
            item_info += "<p>" + data["description"] + "</p>"
        except KeyError:
            pass

        item_info += "</body></html>"
        self.ui.desc.setText(item_info)

        try:
            self.ui.icon.setPixmap(inv_icon(name))
        except TypeError:
            # TODO: change this to the x.png?
            self.ui.icon.setPixmap(QPixmap())

    def update_item(self):
        """Update main item view with current item browser data."""
        name = self.ui.item_type.text()

        # TODO: i guess eventually we're gonna need like.. some sort of generic
        # generate item function
        try:
            item = self.assets.items().get_item(name)
            if item[1].endswith("generatedgun"):
                options = self.assets.items().generate_gun(item)
                name = options["itemName"]
            elif item[1].endswith("generatedsword"):
                options = self.assets.items().generate_sword(item)
                name = options["itemName"]
            elif item[1].endswith("generatedshield"):
                options = self.assets.items().generate_shield(item)
                name = options["itemName"]
            elif item[1].endswith("sapling"):
                options = self.assets.items().generate_sapling(item)
            elif name == "filledcapturepod":
                options = self.assets.items().generate_filledcapturepod(item,
                                                                        self.player.get_uuid())
            else:
                options = item[0]
        except TypeError:
            self.item = empty_slot().item
            self.ui.desc.setText("<html><body><strong>Empty Slot</strong></body></html>")
            self.ui.icon.setPixmap(QPixmap())
            self.clear_item_options()
            return

        self.ui.item_type.setText(name)

        self.item = saves.new_item(name, 1, options)
        self.ui.count.setValue(1)
        self.update_item_info(name, options)
        self.populate_options()

    def get_item(self):
        """Return an ItemWidget of the currently open item."""
        name = self.ui.item_type.text()
        count = self.ui.count.value()
        data = self.item["data"]
        return saves.new_item(name, count, data)

    def clear_item_options(self):
        self.ui.variant.clear()
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        self.ui.variant.setRowCount(0)
        # don't understand why i need to do this check either...
        if self.item is not None:
            self.item["data"] = {}

    def new_item_edit_options(self, new):
        if new:
            selected = ItemOptionWidget("", None)
        else:
            selected = self.ui.variant.currentItem()
        item_edit_options = ItemEditOptions(self.dialog, selected.option[0], selected.option[1])
        def save():
            new_option = json.loads(item_edit_options.ui.options.toPlainText())
            name = item_edit_options.ui.name.text()
            self.item["data"][name] = new_option
            # TODO: update the item info. not working for some reason
            self.populate_options()
        item_edit_options.dialog.accepted.connect(save)
        item_edit_options.dialog.exec()

    def remove_option(self):
        """Remove the currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.item["data"].pop(option_name)
        self.populate_options()

    def edit_option(self):
        """Edit currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.new_item_edit_options(False)

    def new_item_browser(self):
        self.item_browser = ItemBrowser(self.dialog, category=self.remember_browser)
        self.item_browser.dialog.accepted.connect(self.set_item_browser_selection)
        self.item_browser.dialog.exec()

    def populate_options(self):
        self.ui.variant.setRowCount(len(self.item["data"]))
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        row = 0
        for k in sorted(self.item["data"].keys()):
            variant = ItemOptionWidget(k, self.item["data"][k])
            self.ui.variant.setItem(row, 0, variant)
            row += 1

    def set_item_browser_selection(self):
        name = self.item_browser.get_selection()
        if name is None:
            return
        self.remember_browser = self.item_browser.remember_category
        self.ui.item_type.setText(name)

    def max_count(self):
        if "maxStack" in self.item["data"]:
            max = int(self.item["data"]["maxStack"])
        else:
            max = 999
        self.ui.count.setValue(max)

    def export_item(self):
        json_data = json.dumps(self.item, sort_keys=True,
                               indent=4, separators=(',', ': '))
        filename = QFileDialog.getSaveFileName(self.dialog,
                                               "Export Item As")
        if filename[0] != "":
            json_file = open(filename[0], "w")
            json_file.write(json_data)
            json_file.close()

    def import_item(self):
        filename = QFileDialog.getOpenFileName(self.dialog,
                                               "Import Item File")
        def parse():
            try:
                item_data = json.load(open(filename[0], "r"))
            except:
                logging.exception("Error parsing item: %s", filename[0])
                return False
            if "name" not in item_data:
                return False
            if "count" not in item_data:
                item_data["count"] = 1
            if "data" not in item_data:
                item_data["data"] = {}
            return item_data

        item = parse()
        if not item:
            logging.warning("Invalid item file: %s", filename[0])
            return
        else:
            self.ui.item_type.setText(item["name"])
            self.item = item
            self.ui.count.setValue(self.item["count"])
            self.update_item_info(self.item["name"], self.item["data"])
            self.populate_options()
コード例 #8
0
class ItemEdit():
    def __init__(self, parent, item, player, browser_category="<all>"):
        """Takes an item widget and displays an edit dialog for it."""
        self.dialog = QDialog(parent)
        self.ui = qt_itemedit.Ui_Dialog()
        self.ui.setupUi(self.dialog)

        assets_db_file = Config().read("assets_db")
        starbound_folder = Config().read("starbound_folder")
        self.assets = assets.Assets(assets_db_file, starbound_folder)

        self.player = player

        self.item_browser = None
        self.remember_browser = browser_category
        self.item = copy.deepcopy(item)

        if self.item["name"] != "":
            # set name text box
            self.ui.item_type.setText(self.item["name"])
            # set item count spinbox
            self.ui.count.setValue(int(self.item["count"]))
            # set up variant table
            self.populate_options()
            self.update_item_info(self.item["name"], self.item["data"])
        else:
            # empty slot
            self.new_item_browser()
            self.update_item()

        # set up signals
        self.ui.load_button.clicked.connect(self.new_item_browser)
        self.ui.item_type.textChanged.connect(self.update_item)
        self.ui.variant.itemDoubleClicked.connect(
            lambda: self.new_item_edit_options(False))
        self.ui.max_button.clicked.connect(self.max_count)
        self.ui.add_option_button.clicked.connect(
            lambda: self.new_item_edit_options(True))
        self.ui.remove_option_button.clicked.connect(self.remove_option)
        self.ui.edit_option_button.clicked.connect(self.edit_option)
        self.ui.export_button.clicked.connect(self.export_item)
        self.ui.import_button.clicked.connect(self.import_item)

        self.ui.item_type.setFocus()

    def update_item_info(self, name, data):
        item_info = "<html><body>"

        #try:
        #    item_info += "<strong>" + data["shortdescription"] + "</strong><br>"
        #except KeyError:
        #    try:
        #        item_info += "<strong>" + self.assets.items().get_item(name)[0]["shortdescription"] + "</strong><br>"
        #    except:
        #        pass

        item_info += generate_item_info(data)

        item_info += "</body></html>"
        self.ui.desc.setText(item_info)

        try:
            self.ui.icon.setPixmap(inv_icon(name))
        except TypeError:
            # TODO: change this to the x.png?
            self.ui.icon.setPixmap(QPixmap())

    def update_item(self):
        """Update main item view with current item browser data."""
        name = self.ui.item_type.text()

        # TODO: i guess eventually we're gonna need like.. some sort of generic
        # generate item function
        try:
            item = self.assets.items().get_item(name)
            if item[1].endswith("generatedgun"):
                options = self.assets.items().generate_gun(item)
                name = options["itemName"]
            elif item[1].endswith("generatedsword"):
                options = self.assets.items().generate_sword(item)
                name = options["itemName"]
            elif item[1].endswith("generatedshield"):
                options = self.assets.items().generate_shield(item)
                name = options["itemName"]
            elif item[1].endswith("sapling"):
                options = self.assets.items().generate_sapling(item)
            elif name == "filledcapturepod":
                options = self.assets.items().generate_filledcapturepod(
                    item, self.player.get_uuid())
            else:
                options = item[0]
        except TypeError:
            self.item = empty_slot().item
            self.ui.desc.setText(
                "<html><body><strong>Empty Slot</strong></body></html>")
            self.ui.icon.setPixmap(QPixmap())
            self.clear_item_options()
            return

        self.ui.item_type.setText(name)

        self.item = saves.new_item(name, 1, options)
        self.ui.count.setValue(1)
        self.update_item_info(name, options)
        self.populate_options()

    def get_item(self):
        """Return an ItemWidget of the currently open item."""
        name = self.ui.item_type.text()
        count = self.ui.count.value()
        data = self.item["data"]
        return saves.new_item(name, count, data)

    def clear_item_options(self):
        self.ui.variant.clear()
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        self.ui.variant.setRowCount(0)
        # don't understand why i need to do this check either...
        if self.item is not None:
            self.item["data"] = {}

    def new_item_edit_options(self, new):
        if new:
            selected = ItemOptionWidget("", None)
        else:
            selected = self.ui.variant.currentItem()
        item_edit_options = ItemEditOptions(self.dialog, selected.option[0],
                                            selected.option[1])

        def save():
            new_option = json.loads(item_edit_options.ui.options.toPlainText())
            name = item_edit_options.ui.name.text()
            self.item["data"][name] = new_option
            # TODO: update the item info. not working for some reason
            self.populate_options()

        item_edit_options.dialog.accepted.connect(save)
        item_edit_options.dialog.exec()

    def remove_option(self):
        """Remove the currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.item["data"].pop(option_name)
        self.populate_options()

    def edit_option(self):
        """Edit currently selected item option."""
        try:
            option_name = self.ui.variant.currentItem().option[0]
        except AttributeError:
            return
        self.new_item_edit_options(False)

    def new_item_browser(self):
        self.item_browser = ItemBrowser(self.dialog,
                                        category=self.remember_browser)
        self.item_browser.dialog.accepted.connect(
            self.set_item_browser_selection)
        self.item_browser.dialog.exec()

    def populate_options(self):
        self.ui.variant.setRowCount(len(self.item["data"]))
        self.ui.variant.setHorizontalHeaderLabels(["Options"])
        row = 0
        for k in sorted(self.item["data"].keys()):
            variant = ItemOptionWidget(k, self.item["data"][k])
            self.ui.variant.setItem(row, 0, variant)
            row += 1

    def set_item_browser_selection(self):
        name = self.item_browser.get_selection()
        if name is None:
            return
        self.remember_browser = self.item_browser.remember_category
        self.ui.item_type.setText(name)

    def max_count(self):
        if "maxStack" in self.item["data"]:
            max = int(self.item["data"]["maxStack"])
        else:
            max = 999
        self.ui.count.setValue(max)

    def export_item(self):
        json_data = json.dumps(self.item,
                               sort_keys=True,
                               indent=4,
                               separators=(',', ': '))
        filename = QFileDialog.getSaveFileName(self.dialog, "Export Item As")
        if filename[0] != "":
            json_file = open(filename[0], "w")
            json_file.write(json_data)
            json_file.close()

    def import_item(self):
        filename = QFileDialog.getOpenFileName(self.dialog, "Import Item File")

        def parse():
            try:
                item_data = json.load(open(filename[0], "r"))
            except:
                logging.exception("Error parsing item: %s", filename[0])
                return False
            if "name" not in item_data:
                return False
            if "count" not in item_data:
                item_data["count"] = 1
            if "data" not in item_data:
                item_data["data"] = {}
            return item_data

        item = parse()
        if not item:
            logging.warning("Invalid item file: %s", filename[0])
            return
        else:
            self.ui.item_type.setText(item["name"])
            self.item = item
            self.ui.count.setValue(self.item["count"])
            self.update_item_info(self.item["name"], self.item["data"])
            self.populate_options()