LoadOrderEditorDD/LoadOrderEditorDD.py

195 lines
7.8 KiB
Python

import sys
import os
import json
import shutil
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QListWidget, QPushButton, QListWidgetItem, QMessageBox
from PyQt5.QtCore import Qt
import configparser
import qtvscodestyle
class DragDropApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('Drag and Drop JSON Reorder')
# Initialize window size from config.ini
self.initWindowSize()
self.initUI()
def initWindowSize(self):
self.mod_dir = os.getcwd()
self.config = configparser.ConfigParser()
self.config_path = os.path.join(self.mod_dir, 'config.ini')
if not os.path.exists(self.config_path):
# Create config.ini with default values
self.createDefaultConfig()
# Read width and height from config.ini
self.config.read(self.config_path)
width = int(self.config.get('DEFAULT', 'width', fallback='400'))
height = int(self.config.get('DEFAULT', 'height', fallback='300'))
self.resize(width, height)
def createDefaultConfig(self):
self.config['DEFAULT'] = {
'sptBaseDir': '',
'addNewItemsTo': 'end',
'reminder': 'True',
'width': '400',
'height': '300'
}
with open(self.config_path, 'w') as configfile:
self.config.write(configfile)
def initUI(self):
layout = QVBoxLayout(self)
self.list_widget = QListWidget()
layout.addWidget(self.list_widget)
self.save_button = QPushButton('Save Order')
layout.addWidget(self.save_button)
self.mod_dir = os.getcwd()
self.config = configparser.ConfigParser()
self.config_path = os.path.join(self.mod_dir, 'config.ini')
self.loadConfig()
if not self.checkModsDirectory():
return
self.initial_order = []
self.loadData(self.mod_dir)
self.list_widget.setDragDropMode(QListWidget.InternalMove)
self.list_widget.setAlternatingRowColors(True)
self.save_button.clicked.connect(lambda: self.saveOrder(self.mod_dir))
# Apply the dark theme
stylesheet = qtvscodestyle.load_stylesheet(qtvscodestyle.Theme.DARK_VS)
self.setStyleSheet(stylesheet)
def loadConfig(self):
self.config.read(self.config_path)
self.spt_base_dir = self.config.get('DEFAULT', 'sptBaseDir', fallback='')
self.add_new_items_to = self.config.get('DEFAULT', 'addNewItemsTo', fallback='end')
self.reminder = self.config.getboolean('DEFAULT', 'reminder', fallback=True)
self.width = int(self.config.get('DEFAULT', 'width', fallback='400'))
self.height = int(self.config.get('DEFAULT', 'height', fallback='300'))
def checkModsDirectory(self):
mods_dir = os.path.join(self.mod_dir, 'user', 'mods')
if not os.path.exists(mods_dir):
error_message = f"Could not find user/mods. This exe belongs in the base directory of SPT-AKI!\nCurrent Directory: {self.mod_dir}\nconfig.ini has been created in the current directory, where you can set the path if you prefer."
QMessageBox.critical(self, "Error", error_message)
return False
return True
def loadData(self, mod_dir):
print("Loading mod data...")
mod_info = []
order_file_path = os.path.join(mod_dir, 'user', 'mods', 'order.json')
if os.path.exists(order_file_path):
with open(order_file_path, 'r') as order_file:
order_data = json.load(order_file)
ordered_mods = order_data.get("order", [])
for entry in os.scandir(os.path.join(mod_dir, "user", "mods")):
if entry.is_dir():
package_file = os.path.join(entry.path, "package.json")
if os.path.exists(package_file):
print(f"Found package.json in {entry.path}")
with open(package_file, 'r') as file:
data = json.load(file)
folder_name = os.path.basename(entry.path)
mod_info.append({
"name": data["name"],
"folder_name": folder_name,
"version": data["version"],
"author": data["author"],
"akiVersion": data.get("akiVersion", "")
})
print(f"akiVersion for {folder_name}: {data.get('akiVersion', '')}")
if os.path.exists(order_file_path):
ordered_mod_info = []
for mod_name in ordered_mods:
for mod in mod_info:
if mod["folder_name"] == mod_name:
ordered_mod_info.append(mod)
mod_info.remove(mod)
break
ordered_mod_info.extend(mod_info)
mod_info = ordered_mod_info
if self.add_new_items_to == 'start':
self.list_widget.clear()
for mod in mod_info:
self.addListItem(mod, 0)
elif self.add_new_items_to == 'end':
for mod in mod_info:
self.addListItem(mod)
self.initial_order = [item.text() for item in [self.list_widget.item(i) for i in range(self.list_widget.count())]]
def addListItem(self, mod, position=None):
list_item = QListWidgetItem(mod["folder_name"])
tooltip_text = "\n".join([f"{key}: {value}" for key, value in mod.items()])
list_item.setToolTip(tooltip_text)
if position is None:
self.list_widget.addItem(list_item)
else:
self.list_widget.insertItem(position, list_item)
def saveOrder(self, mod_dir):
print("Saving order...")
print(f"Mod directory: {mod_dir}")
new_order = [self.list_widget.item(i).text() for i in range(self.list_widget.count())]
print(f"New order: {new_order}")
order_file_path = os.path.join(mod_dir, 'user', 'mods', 'order.json')
backup_file_path = os.path.join(mod_dir, 'user', 'mods', 'order.bkp')
try:
shutil.copy(order_file_path, backup_file_path)
print('Backup created successfully!')
except Exception as e:
print(f'Error creating backup: {e}')
with open(order_file_path, 'w') as file:
json.dump({"order": new_order}, file, indent=4)
print('Order saved successfully!')
self.initial_order = new_order
self.config.set('DEFAULT', 'width', str(self.width))
self.config.set('DEFAULT', 'height', str(self.height))
with open(self.config_path, 'w') as configfile:
self.config.write(configfile)
def resizeEvent(self, event):
self.width = self.size().width()
self.height = self.size().height()
event.accept()
def closeEvent(self, event):
if self.reminder and self.list_widget.count() > 0:
current_order = [self.list_widget.item(i).text() for i in range(self.list_widget.count())]
if current_order != self.initial_order:
reply = QMessageBox.question(self, 'Reminder', 'You have unsaved changes.\nSave before closing?', QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if reply == QMessageBox.Yes:
self.saveOrder(self.mod_dir)
print(f"Current width: {self.width}, Current height: {self.height}")
self.config.set('DEFAULT', 'width', str(self.width))
self.config.set('DEFAULT', 'height', str(self.height))
print(f"Updated width: {self.width}, Updated height: {self.height}")
with open(self.config_path, 'w') as configfile:
self.config.write(configfile)
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DragDropApp()
window.show()
sys.exit(app.exec_())