def init_settings(self): if get_config().getboolean("CONFIG", "bFirstTime"): answer = question(self, 'Initialization', "Do you use MO ?") if answer == QMessageBox.Yes: QMessageBox.information( self, "Instructions for MO users", "Next dialog window will ask you where your Mod Organiser mods/ folder is, " "thus allowing to install the plugin directly. " "You will still need to activate it in Mod Organizer left pane. " "If you don't see the mod, refresh the left pane. ") get_config().set("CONFIG", "bUseModOrganizer", "True") else: QMessageBox.information( self, "Instructions for Non-MO users", "Next dialog window will ask you to specify a folder to store the plugin. " "In order to install it with a mod manager, compress the generated folder " "(Unless you specified skyrim/data folder ") get_config().set("CONFIG", "bUseModOrganizer", "False") folder = QFileDialog.getExistingDirectory(self, 'Mod folder location', '', QFileDialog.ShowDirsOnly) if folder: get_config().set("PATHS", "installFolder", str(folder)) get_config().set("CONFIG", "bFirstTime", "False") save_config()
def __init__(self, *__args): super().__init__(*__args) self.setFlags(self.flags()) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value, get_config().get("PLUGIN", "defaultFolderIcon")) self.setTextAlignment( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value, Qt.AlignCenter) self.setCheckState(0, Qt.Checked) self.splitterCounter = 0 self.splitterIndex = 0 self.levelTwoCounter = 0 self.maxChildCount = get_config().getint("PLUGIN", "maxItemStringLength") self.bIsSplitter = False
def load_xml(self): self.toggle_window(False) name = get_config().get("CONFIG", "lastName") or get_config().get( "PLUGIN", "name") xml_file, _filter = QFileDialog.getOpenFileName( self, "Open file", get_config().get("PATHS", "installFolder") + "/" + name + "/" + get_config().get("PATHS", "pluginFolder"), "MyOsa file (*.myo)") if xml_file: logging.info("xml_file given : " + xml_file) logging.info("Loading") found = self.treeAnimFiles.create_from_xml(xml_file) self.after_tree_built() self.toggle_window(True)
def set_install_folder(self): folder = get_config().get("PATHS", "installFolder") if folder: answer = question( self, "Overwrite ?", "Install folder already set to :\n" + str(folder) + "\n\n" + "Do you want to overwrite it ?") if answer == QMessageBox.No: return folder = QFileDialog.getExistingDirectory(self, 'Mod folder location', '', QFileDialog.ShowDirsOnly) if folder: get_config().set("PATHS", "installFolder", str(folder)) get_config().set("CONFIG", "bFirstTime", "False") save_config() return str(folder)
def set_animation(self, animation, i): self.setFlags(self.flags() ^ Qt.ItemIsDropEnabled) self.setText( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.NAME.value, animation.parse_stage_name(i)[slice( -get_config().getint("PLUGIN", "maxItemStringLength"), None)]) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value, get_config().get("PLUGIN", "defaultAnimationIcon")) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.TYPE.value, animation.type.name) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.OPTIONS.value, str([x.name for x in animation.options])) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ID.value, str(animation.stages[i])) self.setText(widget.AnimTreeWidget.AnimTreeWidget.COLUMN.FILE.value, str(animation.stages_file[i])) self.setText( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ANIM_OBJ.value, str(animation.stages_obj[i]))
def to_xml(self, parent, level): if self.bIsSplitter or not self.is_anim(): elt = ET.SubElement(parent, "folder" + str(level)) elt.set( "n", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.NAME.value)) if self.bIsSplitter: elt.set( "i", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value) or get_config().get("PLUGIN", "defaultSetIcon")) else: elt.set( "i", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value) or get_config().get("PLUGIN", "defaultFolderIcon")) for i in range(self.childCount()): child = self.child(i) if child.checkState(0) != Qt.Unchecked: try: test = child.bIsSplitter except AttributeError: AnimTreeItem.convert_to_anim_tree_item(child) child.to_xml(elt, level + 1) else: entry = ET.SubElement(parent, "entry") entry.set( "n", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.NAME.value)) entry.set( "i", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value) or get_config().get("PLUGIN", "defaultAnimationIcon")) entry.set( "id", self.text( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ID.value))
def convert_to_anim_tree_item(cls, obj): obj.__class__ = cls if obj.is_anim(): obj.setFlags(obj.flags() ^ Qt.ItemIsDropEnabled) else: obj.setFlags(obj.flags()) obj.bIsSplitter = False obj.splitterCounter = 0 obj.splitterIndex = 0 obj.levelTwoCounter = 0 obj.maxChildCount = get_config().get("PLUGIN", "maxItemStringLength")
def insert_splitter(self, index=-1): if index == -1: index = self.next_splitter_index() splitter = AnimTreeItem() splitter.setText(0, "Set " + str(index + 1)) splitter.setText( widget.AnimTreeWidget.AnimTreeWidget.COLUMN.ICON.value, get_config().get("PLUGIN", "defaultSetIcon")) splitter.bIsSplitter = True self.insertChild(index, splitter) self.splitterCounter += 1 self.set_next_splitter_index(index + 1) return splitter
def to_xml(self, plugin_name): root = self.invisibleRootItem() folder0 = ET.Element("folder0") folder0.set("n", plugin_name) folder0.set("i", get_config().get("PLUGIN", "defaultPackageIcon")) for i in range(root.childCount()): child = root.child(i) if child.checkState(0) != Qt.Unchecked: try: test = child.bIsSplitter except AttributeError: log.warning("TreeItem detected ! Should be AnimTreeItem, trying to convert it") widget.AnimTreeItem.AnimTreeItem.convert_to_anim_tree_item(child) child.to_xml(folder0, 1) return folder0
def add_item_from_xml(self, parent, elt, animations): counter = 0 duplicate_counter = 0 for child in elt: if child.get("id") in animations: duplicate_counter += 1 log.info("Duplicate found : " + child.get("n")) else: item = widget.AnimTreeItem.AnimTreeItem() item.setText(self.COLUMN.NAME.value, child.get("n")) item.setText(self.COLUMN.ICON.value, child.get("i") or get_config().get("PLUGIN", "defaultFolderIcon")) if child.get("id"): counter += 1 item.setText(self.COLUMN.ID.value, child.get("id")) parent.addChild(item) counter += self.add_item_from_xml(item, child, animations) return counter
def create_from_packages(self, packages): animations = [] duplicate_counter = 0 if self.invisibleRootItem().childCount() > 0: box = QMessageBox() box.setIcon(QMessageBox.Question) box.setWindowTitle('Clear or Append ?') box.setText("Do you want to append new animations to the tree" "or clear the tree and build a new one from the new animations ?") box.setStandardButtons(QMessageBox.Yes | QMessageBox.No) buttonY = box.button(QMessageBox.Yes) buttonY.setText('Clear') buttonN = box.button(QMessageBox.No) buttonN.setText('Append') box.exec_() if box.clickedButton() == buttonY: self.clear() elif box.clickedButton() == buttonN: answer = question(None, "Duplicates ?", "Do you want to ignore already existing animations ?") if answer == QMessageBox.Yes: animations = self.animations_id() root = widget.AnimTreeItem.AnimTreeItem(self) for package in packages: section = widget.AnimTreeItem.AnimTreeItem() section.setText(0, package.name) root.add_nested_child(section) for module in package.items: module_section = widget.AnimTreeItem.AnimTreeItem() module_section.setText(0, module.name) section.add_nested_child(module_section) previous_animation = "" anim_section = None counter = 1 for animation in module.items: if animation.parse_name() != previous_animation or not anim_section: previous_animation = animation.parse_name() counter = 1 anim_section = widget.AnimTreeItem.AnimTreeItem() anim_section.setText(0, animation.parse_name()[slice(0, get_config().getint("PLUGIN", "maxItemStringLength"))]) module_section.add_nested_child(anim_section) for i, stage in enumerate(animation.stages): if animation.stages[i] in animations: duplicate_counter += 1 log.warning("Duplicate found : " + animation.stages[i] + " in " + package.name + " | " + module.name) else: stage_section = widget.AnimTreeItem.AnimTreeItem() stage_section.set_animation(animation, i) anim_section.add_nested_child(stage_section) counter += 1 animations.append(animation.stages[i]) invisible_root = self.invisibleRootItem() for i in range(root.childCount()): child = root.takeChild(0) invisible_root.addChild(child) invisible_root.removeChild(root) return duplicate_counter
def generate_plugin(self): logging.info("=============== GENERATING PLUGIN ===============") if not get_config().get("PATHS", "installFolder"): QMessageBox.information( self, "Folder missing", "Installation folder not set, please specify one") if not self.set_install_folder(): QMessageBox.warning( self, "Folder missing", "No installation folder specified. Aborting") return name = get_config().get("CONFIG", "lastName") or get_config().get( "PLUGIN", "name") plugin_name, ok = QInputDialog.getText(self, "Plugin Name", "Enter the plugin name", text=name) if ok: if plugin_name: get_config().set("CONFIG", "lastName", plugin_name) save_config() path_plugin_folder = get_config().get("PATHS", "installFolder") + "/" + \ plugin_name + "/" + \ get_config().get("PATHS", "pluginFolder") """ path_plugin_install = get_config().get("PATHS", "installFolder") + "/" + \ plugin_name + "/" + \ get_config().get("PATHS", "pluginInstall") create_dir(path_plugin_install) # File allowing the plugin to be recognized by OSA file = open(path_plugin_install + "/" + get_config().get("PLUGIN", "osplug") + ".osplug", "w") file.close() """ create_dir(path_plugin_folder) logging.info("Plugin destination : " + path_plugin_folder) xml_root = self.treeAnimFiles.to_xml(plugin_name) with open(path_plugin_folder + plugin_name + ".myo", "w") as file: data = ET.tostring(xml_root, "unicode") file.write(data) msg_box = QMessageBox() msg_box.setWindowTitle("Results") msg_box.setIcon(QMessageBox.Information) msg_box.setText("Plugin Generation Done !\n" "----- Plugin path -----\n" + path_plugin_folder) msg_box.addButton(QPushButton("Open Folder"), QMessageBox.ActionRole) msg_box.addButton(QPushButton("Ok"), QMessageBox.YesRole) msg_box.exec_() if msg_box.buttonRole( msg_box.clickedButton()) == QMessageBox.ActionRole: os.startfile(os.path.realpath(path_plugin_folder)) else: QMessageBox.warning(self, "Abort", "Enter valid name")
def scan_folder(self): self.toggle_window(False) scan_dir = QFileDialog.getExistingDirectory( self, 'Mod folder location', get_config().get("PATHS", "installFolder"), QFileDialog.ShowDirsOnly) counter = 0 packages = [] previous_package = "" anim_package = None max_item_string_length = get_config().getint("PLUGIN", "maxItemStringLength") if scan_dir: logging.info("=============== SCANNING ===============") logging.info("Scanning directory : " + scan_dir) for root, dirs, files in os.walk(scan_dir): for file in files: if file.startswith("FNIS") and file.endswith("List.txt"): anim_file = os.path.join(root, file) module = file[5:-9] package = anim_file.replace(scan_dir + '\\', '').split( '\\', 1)[0][slice(0, max_item_string_length)] if not package: package = module if package != previous_package: if anim_package: anim_package.items.sort(key=lambda x: x.name, reverse=False) anim_package = NamedContainer(package) anim_module = NamedContainer(module) logging.info(indent("Package : " + str(package), 1)) logging.info(indent("Module : " + str(module), 1)) logging.info(indent("Reading : " + anim_file, 1)) with open(anim_file, 'r') as f: anim = None for line in f: anim_type, anim_options, anim_id, anim_file, anim_obj = Animation.parse_line( line) logging.debug( indent( "animType : " + anim_type.name + " || Line : " + line.strip(), 2)) if anim_type == Animation.TYPE.BASIC: anim = Animation(anim_package.name, anim_module.name, anim_type, anim_options, anim_id, anim_file, anim_obj) anim_module.add_item(anim) counter += 1 logging.info( indent( "Adding basic animation || Line : " + line.strip(), 2)) elif anim_type == Animation.TYPE.ANIM_OBJ: anim = Animation(anim_package.name, anim_module.name, anim_type, anim_options, anim_id, anim_file, anim_obj) anim_module.add_item(anim) counter += 1 logging.info( indent( "Adding AnimObj animation || Line : " + line.strip(), 2)) elif anim_type == Animation.TYPE.SEQUENCE: anim = Animation(anim_package.name, anim_module.name, anim_type, anim_options, anim_id, anim_file, anim_obj) anim_module.add_item(anim) counter += 1 logging.info( indent( "Adding sequence animation || Line : " + line.strip(), 2)) elif anim_type == Animation.TYPE.ADDITIVE: anim.add_stage(anim_id, anim_file, anim_obj) counter += 1 logging.info( indent( "Adding stage || Line : " + line.strip(), 3)) #anim_module.items.sort(key=lambda x: x.parse_name(), reverse=False) if anim_module.items: anim_package.add_item(anim_module) if package != previous_package: previous_package = package packages.append(anim_package) packages.sort(key=lambda x: x.name, reverse=False) duplicate = self.treeAnimFiles.create_from_packages(packages) if duplicate > 0: QMessageBox.information( self, "Results", str(duplicate) + " duplicates found (Not added)\n" "List (WARNING Level) available in logs (if activated)") self.after_tree_built() self.toggle_window(True)
msg_box.addButton(QPushButton("Open Folder"), QMessageBox.ActionRole) msg_box.addButton(QPushButton("Ok"), QMessageBox.YesRole) msg_box.exec_() if msg_box.buttonRole( msg_box.clickedButton()) == QMessageBox.ActionRole: os.startfile(os.path.realpath(path_plugin_folder)) else: QMessageBox.warning(self, "Abort", "Enter valid name") if __name__ == '__main__': logging.basicConfig( filemode="w", filename="logs.log", level=logging.getLevelName(get_config().get("LOG", "level")), format='%(asctime)s - [%(levelname)s] - %(name)s : %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') if not get_config().get("LOG", "enabled"): logger = logging.getLogger() logger.disabled = True logging.info(" =============== STARTING LOGGING ===============") app = QApplication(sys.argv) window = OSelectorWindow() sys.exit(app.exec_())