refacto update ; pretify code

This commit is contained in:
Maxime Réaux 2026-02-02 10:41:16 +01:00
parent 6bd3ee31dc
commit fbb1c913ba
11 changed files with 594 additions and 310 deletions

View file

@ -1,5 +1,6 @@
import sys import sys
import os import os
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src")) sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "src"))
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication

View file

@ -6,6 +6,7 @@ from PyQt6.QtCore import Qt
ROLE_TYPE = Qt.ItemDataRole.UserRole ROLE_TYPE = Qt.ItemDataRole.UserRole
ROLE_ID = Qt.ItemDataRole.UserRole + 1 ROLE_ID = Qt.ItemDataRole.UserRole + 1
class ItemType(StrEnum): class ItemType(StrEnum):
PLAYER = "player" PLAYER = "player"
WAR = "war" WAR = "war"
@ -18,6 +19,7 @@ class ItemType(StrEnum):
CHOICE = "choice" CHOICE = "choice"
BATTLE = "battle" BATTLE = "battle"
class RefreshScope(Enum): class RefreshScope(Enum):
NONE = auto() NONE = auto()
PLAYERS_LIST = auto() PLAYERS_LIST = auto()
@ -25,4 +27,3 @@ class RefreshScope(Enum):
WAR_DETAILS = auto() WAR_DETAILS = auto()
CAMPAIGN_DETAILS = auto() CAMPAIGN_DETAILS = auto()
ROUND_DETAILS = auto() ROUND_DETAILS = auto()

View file

@ -6,7 +6,18 @@ from warchron.view.view import View
from warchron.constants import ItemType, RefreshScope from warchron.constants import ItemType, RefreshScope
from warchron.controller.dtos import ParticipantOption from warchron.controller.dtos import ParticipantOption
from warchron.view.view import PlayerDialog, WarDialog, CampaignDialog, ObjectiveDialog, WarParticipantDialog, CampaignParticipantDialog, SectorDialog, ChoicesDialog, BattlesDialog from warchron.view.view import (
PlayerDialog,
WarDialog,
CampaignDialog,
ObjectiveDialog,
WarParticipantDialog,
CampaignParticipantDialog,
SectorDialog,
ChoicesDialog,
BattlesDialog,
)
class Controller: class Controller:
def __init__(self, model: Model, view: View): def __init__(self, model: Model, view: View):
@ -38,7 +49,9 @@ class Controller:
self.view.addObjectiveBtn.clicked.connect(self.add_objective) self.view.addObjectiveBtn.clicked.connect(self.add_objective)
self.view.addWarParticipantBtn.clicked.connect(self.add_war_participant) self.view.addWarParticipantBtn.clicked.connect(self.add_war_participant)
self.view.addSectorBtn.clicked.connect(self.add_sector) self.view.addSectorBtn.clicked.connect(self.add_sector)
self.view.addCampaignParticipantBtn.clicked.connect(self.add_campaign_participant) self.view.addCampaignParticipantBtn.clicked.connect(
self.add_campaign_participant
)
self.view.on_edit_item = self.edit_item self.view.on_edit_item = self.edit_item
self.view.on_delete_item = self.delete_item self.view.on_delete_item = self.delete_item
@ -48,7 +61,9 @@ class Controller:
self.view, self.view,
"Unsaved changes", "Unsaved changes",
"You have unsaved changes. Do you want to save before quitting?", "You have unsaved changes. Do you want to save before quitting?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel QMessageBox.StandardButton.Yes
| QMessageBox.StandardButton.No
| QMessageBox.StandardButton.Cancel,
) )
if reply == QMessageBox.StandardButton.Yes: if reply == QMessageBox.StandardButton.Yes:
self.save() self.save()
@ -64,7 +79,7 @@ class Controller:
self.view, self.view,
"Unsaved changes", "Unsaved changes",
"Discard current campaign?", "Discard current campaign?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
) )
if reply != QMessageBox.StandardButton.Yes: if reply != QMessageBox.StandardButton.Yes:
return return
@ -81,7 +96,7 @@ class Controller:
self.view, self.view,
"Unsaved changes", "Unsaved changes",
"Discard current campaign?", "Discard current campaign?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
) )
if reply != QMessageBox.StandardButton.Yes: if reply != QMessageBox.StandardButton.Yes:
return return
@ -139,8 +154,7 @@ class Controller:
self.view.display_war_objectives(objectives) self.view.display_war_objectives(objectives)
participants = war.get_all_war_participants() participants = war.get_all_war_participants()
participants_for_display = [ participants_for_display = [
(self.model.get_player_name(p.id), p.faction, p.id) (self.model.get_player_name(p.id), p.faction, p.id) for p in participants
for p in participants
] ]
self.view.display_war_participants(participants_for_display) self.view.display_war_participants(participants_for_display)
@ -155,7 +169,16 @@ class Controller:
major_name = war.get_objective_name(sect.major_objective_id) major_name = war.get_objective_name(sect.major_objective_id)
minor_name = war.get_objective_name(sect.minor_objective_id) minor_name = war.get_objective_name(sect.minor_objective_id)
influence_name = war.get_objective_name(sect.influence_objective_id) influence_name = war.get_objective_name(sect.influence_objective_id)
sectors_for_display.append((sect.name,round_index,major_name,minor_name,influence_name,sect.id)) sectors_for_display.append(
(
sect.name,
round_index,
major_name,
minor_name,
influence_name,
sect.id,
)
)
self.view.display_campaign_sectors(sectors_for_display) self.view.display_campaign_sectors(sectors_for_display)
participants = camp.get_all_campaign_participants() participants = camp.get_all_campaign_participants()
participants_for_display = [ participants_for_display = [
@ -174,29 +197,47 @@ class Controller:
for part in participants: for part in participants:
choice = rnd.get_choice(part.id) choice = rnd.get_choice(part.id)
if not choice: if not choice:
choice=self.model.create_choice(round_id=rnd.id, participant_id=part.id) choice = self.model.create_choice(
priority_name = camp.get_sector_name(choice.priority_sector_id) if choice else "" round_id=rnd.id, participant_id=part.id
secondary_name = camp.get_sector_name(choice.secondary_sector_id) if choice else "" )
choices_for_display.append(( priority_name = (
camp.get_sector_name(choice.priority_sector_id) if choice else ""
)
secondary_name = (
camp.get_sector_name(choice.secondary_sector_id) if choice else ""
)
choices_for_display.append(
(
self.model.get_player_name(part.id), self.model.get_player_name(part.id),
priority_name, priority_name,
secondary_name, secondary_name,
choice.participant_id choice.participant_id,
)) )
)
self.view.display_round_choices(choices_for_display) self.view.display_round_choices(choices_for_display)
battles_for_display = [] battles_for_display = []
for sect in sectors: for sect in sectors:
battle = rnd.get_battle(sect.id) battle = rnd.get_battle(sect.id)
if not battle: if not battle:
battle = self.model.create_battle(round_id=rnd.id, sector_id=sect.id) battle = self.model.create_battle(round_id=rnd.id, sector_id=sect.id)
player_1_name = self.model.get_player_name(battle.player_1_id) if battle.player_1_id else "" player_1_name = (
player_2_name = self.model.get_player_name(battle.player_2_id) if battle.player_2_id else "" self.model.get_player_name(battle.player_1_id)
battles_for_display.append(( if battle.player_1_id
else ""
)
player_2_name = (
self.model.get_player_name(battle.player_2_id)
if battle.player_2_id
else ""
)
battles_for_display.append(
(
camp.get_sector_name(battle.sector_id), camp.get_sector_name(battle.sector_id),
player_1_name, player_1_name,
player_2_name, player_2_name,
battle.sector_id battle.sector_id,
)) )
)
self.view.display_round_battles(battles_for_display) self.view.display_round_battles(battles_for_display)
def on_tree_selection_changed(self, selection): def on_tree_selection_changed(self, selection):
@ -250,7 +291,9 @@ class Controller:
# Common command methods # Common command methods
def refresh_and_select(self, scope: RefreshScope, *, item_type: ItemType, item_id: str): def refresh_and_select(
self, scope: RefreshScope, *, item_type: ItemType, item_id: str
):
self.refresh(scope) self.refresh(scope)
self.view.select_tree_item(item_type=item_type, item_id=item_id) self.view.select_tree_item(item_type=item_type, item_id=item_id)
@ -273,20 +316,28 @@ class Controller:
if not self._validate_war_inputs(name, year): if not self._validate_war_inputs(name, year):
return return
self.model.update_war(item_id, name=name, year=year) self.model.update_war(item_id, name=name, year=year)
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id
)
elif item_type == ItemType.CAMPAIGN: elif item_type == ItemType.CAMPAIGN:
camp = self.model.get_campaign(item_id) camp = self.model.get_campaign(item_id)
dialog = CampaignDialog(self.view, default_name=camp.name, default_month=camp.month) dialog = CampaignDialog(
self.view, default_name=camp.name, default_month=camp.month
)
if dialog.exec() == QDialog.DialogCode.Accepted: if dialog.exec() == QDialog.DialogCode.Accepted:
name = dialog.get_campaign_name() name = dialog.get_campaign_name()
month = dialog.get_campaign_month() month = dialog.get_campaign_month()
if not self._validate_campaign_inputs(name, month): if not self._validate_campaign_inputs(name, month):
return return
self.model.update_campaign(item_id, name=name, month=month) self.model.update_campaign(item_id, name=name, month=month)
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id
)
elif item_type == ItemType.OBJECTIVE: elif item_type == ItemType.OBJECTIVE:
obj = self.model.get_objective(item_id) obj = self.model.get_objective(item_id)
dialog = ObjectiveDialog(self.view, default_name=obj.name, default_description=obj.description) dialog = ObjectiveDialog(
self.view, default_name=obj.name, default_description=obj.description
)
if dialog.exec() == QDialog.DialogCode.Accepted: if dialog.exec() == QDialog.DialogCode.Accepted:
name = dialog.get_objective_name() name = dialog.get_objective_name()
description = dialog.get_objective_description() description = dialog.get_objective_description()
@ -302,7 +353,7 @@ class Controller:
players=[player], players=[player],
default_player_id=part.id, default_player_id=part.id,
default_faction=part.faction, default_faction=part.faction,
editable_player=False editable_player=False,
) )
if dialog.exec() == QDialog.DialogCode.Accepted: if dialog.exec() == QDialog.DialogCode.Accepted:
faction = dialog.get_participant_faction() faction = dialog.get_participant_faction()
@ -336,7 +387,7 @@ class Controller:
round_id=round_id, round_id=round_id,
major_id=major_id, major_id=major_id,
minor_id=minor_id, minor_id=minor_id,
influence_id=influence_id influence_id=influence_id,
) )
self.refresh(RefreshScope.CAMPAIGN_DETAILS) self.refresh(RefreshScope.CAMPAIGN_DETAILS)
elif item_type == ItemType.CAMPAIGN_PARTICIPANT: elif item_type == ItemType.CAMPAIGN_PARTICIPANT:
@ -349,12 +400,14 @@ class Controller:
default_participant_id=part.id, default_participant_id=part.id,
default_leader=part.leader, default_leader=part.leader,
default_theme=part.theme, default_theme=part.theme,
editable_player=False editable_player=False,
) )
if dialog.exec() == QDialog.DialogCode.Accepted: if dialog.exec() == QDialog.DialogCode.Accepted:
leader = dialog.get_participant_leader() leader = dialog.get_participant_leader()
theme = dialog.get_participant_theme() theme = dialog.get_participant_theme()
self.model.update_campaign_participant(item_id, leader=leader, theme=theme) self.model.update_campaign_participant(
item_id, leader=leader, theme=theme
)
self.refresh(RefreshScope.CAMPAIGN_DETAILS) self.refresh(RefreshScope.CAMPAIGN_DETAILS)
elif item_type == ItemType.CHOICE: elif item_type == ItemType.CHOICE:
self.edit_round_choice(item_id) self.edit_round_choice(item_id)
@ -368,7 +421,7 @@ class Controller:
self.view, self.view,
"Confirm deletion", "Confirm deletion",
"Are you sure you want to delete this item?", "Are you sure you want to delete this item?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
) )
if reply != QMessageBox.StandardButton.Yes: if reply != QMessageBox.StandardButton.Yes:
return return
@ -382,7 +435,9 @@ class Controller:
war = self.model.get_war_by_campaign(item_id) war = self.model.get_war_by_campaign(item_id)
war_id = war.id war_id = war.id
self.model.remove_campaign(item_id) self.model.remove_campaign(item_id)
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war_id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war_id
)
elif item_type == ItemType.OBJECTIVE: elif item_type == ItemType.OBJECTIVE:
self.model.remove_objective(item_id) self.model.remove_objective(item_id)
self.refresh(RefreshScope.WAR_DETAILS) self.refresh(RefreshScope.WAR_DETAILS)
@ -399,7 +454,9 @@ class Controller:
camp = self.model.get_campaign_by_round(item_id) camp = self.model.get_campaign_by_round(item_id)
camp_id = camp.id camp_id = camp.id
self.model.remove_round(item_id) self.model.remove_round(item_id)
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp_id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp_id
)
self.is_dirty = True self.is_dirty = True
# Player methods # Player methods
@ -407,9 +464,7 @@ class Controller:
def _validate_player_inputs(self, name: str) -> bool: def _validate_player_inputs(self, name: str) -> bool:
if not name.strip(): if not name.strip():
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid name", "Player name cannot be empty."
"Invalid name",
"Player name cannot be empty."
) )
return False return False
return True return True
@ -429,23 +484,19 @@ class Controller:
def _validate_war_inputs(self, name: str, year: int) -> bool: def _validate_war_inputs(self, name: str, year: int) -> bool:
if not name.strip(): if not name.strip():
QMessageBox.warning( QMessageBox.warning(self.view, "Invalid name", "War name cannot be empty.")
self.view,
"Invalid name",
"War name cannot be empty."
)
return False return False
if not (1970 <= year <= 3000): if not (1970 <= year <= 3000):
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid year", "Year must be between 1970 and 3000."
"Invalid year",
"Year must be between 1970 and 3000."
) )
return False return False
return True return True
def add_war(self): def add_war(self):
dialog = WarDialog(self.view, default_year=self.model.get_default_war_values()["year"]) dialog = WarDialog(
self.view, default_year=self.model.get_default_war_values()["year"]
)
result = dialog.exec() # modal blocking dialog result = dialog.exec() # modal blocking dialog
if result == QDialog.DialogCode.Accepted: if result == QDialog.DialogCode.Accepted:
name = dialog.get_war_name() name = dialog.get_war_name()
@ -454,16 +505,16 @@ class Controller:
return return
war = self.model.add_war(name, year) war = self.model.add_war(name, year)
self.is_dirty = True self.is_dirty = True
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id
)
# Objective methods # Objective methods
def _validate_objective_inputs(self, name: str, description: str) -> bool: def _validate_objective_inputs(self, name: str, description: str) -> bool:
if not name.strip(): if not name.strip():
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid name", "Objective name cannot be empty."
"Invalid name",
"Objective name cannot be empty."
) )
return False return False
return True return True
@ -504,16 +555,12 @@ class Controller:
def _validate_campaign_inputs(self, name: str, month: int) -> bool: def _validate_campaign_inputs(self, name: str, month: int) -> bool:
if not name.strip(): if not name.strip():
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid name", "Campaign name cannot be empty."
"Invalid name",
"Campaign name cannot be empty."
) )
return False return False
if not (1 <= month <= 12): if not (1 <= month <= 12):
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid month", "Month must be between 1 and 12."
"Invalid month",
"Month must be between 1 and 12."
) )
return False return False
return True return True
@ -521,7 +568,12 @@ class Controller:
def add_campaign(self): def add_campaign(self):
if not self.selected_war_id: if not self.selected_war_id:
return return
dialog = CampaignDialog(self.view, default_month=self.model.get_default_campaign_values(self.selected_war_id)["month"]) dialog = CampaignDialog(
self.view,
default_month=self.model.get_default_campaign_values(self.selected_war_id)[
"month"
],
)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
name = dialog.get_campaign_name() name = dialog.get_campaign_name()
@ -530,15 +582,22 @@ class Controller:
return return
camp = self.model.add_campaign(self.selected_war_id, name, month) camp = self.model.add_campaign(self.selected_war_id, name, month)
self.is_dirty = True self.is_dirty = True
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id
)
# Campaign participant methods # Campaign participant methods
def add_campaign_participant(self): def add_campaign_participant(self):
if not self.selected_campaign_id: if not self.selected_campaign_id:
return return
participants = self.model.get_available_war_participants(self.selected_campaign_id) participants = self.model.get_available_war_participants(
part_opts = [ParticipantOption(id=p.id, name=self.model.get_player_name(p.id)) for p in participants] self.selected_campaign_id
)
part_opts = [
ParticipantOption(id=p.id, name=self.model.get_player_name(p.id))
for p in participants
]
dialog = CampaignParticipantDialog(self.view, participants=part_opts) dialog = CampaignParticipantDialog(self.view, participants=part_opts)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
@ -547,18 +606,20 @@ class Controller:
theme = dialog.get_participant_theme() theme = dialog.get_participant_theme()
if not player_id: if not player_id:
return return
self.model.add_campaign_participant(self.selected_campaign_id, player_id, leader, theme) self.model.add_campaign_participant(
self.selected_campaign_id, player_id, leader, theme
)
self.is_dirty = True self.is_dirty = True
self.refresh(RefreshScope.CAMPAIGN_DETAILS) self.refresh(RefreshScope.CAMPAIGN_DETAILS)
# Sector methods # Sector methods
def _validate_sector_inputs(self, name: str, round_id: str, major_id: str, minor_id: str, influence_id:str) -> bool: def _validate_sector_inputs(
self, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str
) -> bool:
if not name.strip(): if not name.strip():
QMessageBox.warning( QMessageBox.warning(
self.view, self.view, "Invalid name", "Sector name cannot be empty."
"Invalid name",
"Sector name cannot be empty."
) )
return False return False
# allow same objectives in different fields? # allow same objectives in different fields?
@ -571,7 +632,9 @@ class Controller:
camp = self.model.get_campaign(self.selected_campaign_id) camp = self.model.get_campaign(self.selected_campaign_id)
rounds = camp.get_all_rounds() rounds = camp.get_all_rounds()
objectives = war.get_all_objectives() objectives = war.get_all_objectives()
dialog = SectorDialog(self.view, default_name="", rounds=rounds, objectives=objectives) dialog = SectorDialog(
self.view, default_name="", rounds=rounds, objectives=objectives
)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
name = dialog.get_sector_name() name = dialog.get_sector_name()
@ -579,9 +642,13 @@ class Controller:
major_id = dialog.get_major_id() major_id = dialog.get_major_id()
minor_id = dialog.get_minor_id() minor_id = dialog.get_minor_id()
influence_id = dialog.get_influence_id() influence_id = dialog.get_influence_id()
if not self._validate_sector_inputs(name, round_id, major_id, minor_id, influence_id): if not self._validate_sector_inputs(
name, round_id, major_id, minor_id, influence_id
):
return return
self.model.add_sector(self.selected_campaign_id, name, round_id, major_id, minor_id, influence_id) self.model.add_sector(
self.selected_campaign_id, name, round_id, major_id, minor_id, influence_id
)
self.is_dirty = True self.is_dirty = True
self.refresh(RefreshScope.CAMPAIGN_DETAILS) self.refresh(RefreshScope.CAMPAIGN_DETAILS)
@ -592,7 +659,9 @@ class Controller:
return return
rnd = self.model.add_round(self.selected_campaign_id) rnd = self.model.add_round(self.selected_campaign_id)
self.is_dirty = True self.is_dirty = True
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id) self.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id
)
# Choice methods # Choice methods
@ -621,12 +690,12 @@ class Controller:
) )
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
# TODO replace by update_choice through self.model... self.model.update_choice(
rnd.update_choice( round_id=round_id,
participant_id=part.id, participant_id=part.id,
priority_sector_id=dialog.get_priority_id(), priority_sector_id=dialog.get_priority_id(),
secondary_sector_id=dialog.get_secondary_id(), secondary_sector_id=dialog.get_secondary_id(),
comment = dialog.get_comment() comment=dialog.get_comment(),
) )
# Battle methods # Battle methods
@ -645,9 +714,7 @@ class Controller:
part_opts: list[ParticipantOption] = [] part_opts: list[ParticipantOption] = []
for part in participants: for part in participants:
player = self.model.get_player(part.id) player = self.model.get_player(part.id)
part_opts.append( part_opts.append(ParticipantOption(id=part.id, name=player.name))
ParticipantOption(id=part.id, name=player.name)
)
dialog = BattlesDialog( dialog = BattlesDialog(
self.view, self.view,
sectors=[sect], sectors=[sect],
@ -662,8 +729,8 @@ class Controller:
) )
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return return
# TODO replace by update_battle through self.model... self.model.update_battle(
rnd.update_battle( round_id=round_id,
sector_id=sect.id, sector_id=sect.id,
player_1_id=dialog.get_player_1_id(), player_1_id=dialog.get_player_1_id(),
player_2_id=dialog.get_player_2_id(), player_2_id=dialog.get_player_2_id(),
@ -672,4 +739,3 @@ class Controller:
victory_condition=dialog.get_victory_condition(), victory_condition=dialog.get_victory_condition(),
comment=dialog.get_comment(), comment=dialog.get_comment(),
) )

View file

@ -1,5 +1,6 @@
from dataclasses import dataclass from dataclasses import dataclass
@dataclass(frozen=True) @dataclass(frozen=True)
class ParticipantOption: class ParticipantOption:
id: str id: str

View file

@ -161,6 +161,15 @@ class Campaign:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
return rnd.create_choice(participant_id) return rnd.create_choice(participant_id)
def update_choice(self,
round_id: str,
participant_id: str,
priority_sector_id: str | None,
secondary_sector_id: str | None,
comment: str | None):
rnd = self.get_round(round_id)
rnd.update_choice(participant_id, priority_sector_id, secondary_sector_id, comment)
def remove_choice(self, round_id: str, participant_id: str) -> Choice: def remove_choice(self, round_id: str, participant_id: str) -> Choice:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
rnd.remove_choice(participant_id) rnd.remove_choice(participant_id)
@ -171,6 +180,18 @@ class Campaign:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
return rnd.create_battle(sector_id) return rnd.create_battle(sector_id)
def update_battle(self,
round_id: str,
sector_id: str,
player_1_id: str | None,
player_2_id: str | None,
winner_id: str | None,
score: str | None,
victory_condition: str | None,
comment: str | None):
rnd = self.get_round(round_id)
rnd.update_battle(sector_id, player_1_id, player_2_id, winner_id, score, victory_condition, comment)
def remove_battle(self, round_id: str, sector_id: str) -> Battle: def remove_battle(self, round_id: str, sector_id: str) -> Battle:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
rnd.remove_battle(sector_id) rnd.remove_battle(sector_id)

View file

@ -8,6 +8,7 @@ from warchron.model.war import War, Objective, WarParticipant
from warchron.model.campaign import Campaign, Sector, CampaignParticipant from warchron.model.campaign import Campaign, Sector, CampaignParticipant
from warchron.model.round import Round, Choice, Battle from warchron.model.round import Round, Choice, Battle
class Model: class Model:
def __init__(self): def __init__(self):
self.players: dict[str, Player] = {} self.players: dict[str, Player] = {}
@ -50,7 +51,7 @@ class Model:
data = { data = {
"version": "1.0", "version": "1.0",
"players": [p.toDict() for p in self.players.values()], "players": [p.toDict() for p in self.players.values()],
"wars": [w.toDict() for w in self.wars.values()] "wars": [w.toDict() for w in self.wars.values()],
} }
with open(path, "w", encoding="utf-8") as f: with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2) json.dump(data, f, indent=2)
@ -82,9 +83,7 @@ class Model:
# War methods # War methods
def get_default_war_values(self) -> dict: def get_default_war_values(self) -> dict:
return { return {"year": datetime.now().year}
"year": datetime.now().year
}
def add_war(self, name: str, year: int) -> War: def add_war(self, name: str, year: int) -> War:
war = War(name, year) war = War(name, year)
@ -174,7 +173,9 @@ class Model:
if not war.has_participant(player.id) if not war.has_participant(player.id)
] ]
def add_war_participant(self, war_id: str, player_id: str, faction: str) -> WarParticipant: def add_war_participant(
self, war_id: str, player_id: str, faction: str
) -> WarParticipant:
war = self.get_war(war_id) war = self.get_war(war_id)
return war.add_war_participant(player_id, faction) return war.add_war_participant(player_id, faction)
@ -242,7 +243,15 @@ class Model:
# Sector methods # Sector methods
def add_sector(self, campaign_id: str, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str) -> Sector: def add_sector(
self,
campaign_id: str,
name: str,
round_id: str,
major_id: str,
minor_id: str,
influence_id: str,
) -> Sector:
camp = self.get_campaign(campaign_id) camp = self.get_campaign(campaign_id)
return camp.add_sector(name, round_id, major_id, minor_id, influence_id) return camp.add_sector(name, round_id, major_id, minor_id, influence_id)
@ -254,9 +263,25 @@ class Model:
return sect return sect
raise KeyError("Sector not found") raise KeyError("Sector not found")
def update_sector(self, sector_id: str, *, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str): def update_sector(
self,
sector_id: str,
*,
name: str,
round_id: str,
major_id: str,
minor_id: str,
influence_id: str,
):
war = self.get_war_by_sector(sector_id) war = self.get_war_by_sector(sector_id)
war.update_sector(sector_id, name=name, round_id=round_id, major_id=major_id, minor_id=minor_id, influence_id=influence_id) war.update_sector(
sector_id,
name=name,
round_id=round_id,
major_id=major_id,
minor_id=minor_id,
influence_id=influence_id,
)
def remove_sector(self, sector_id: str): def remove_sector(self, sector_id: str):
camp = self.get_campaign_by_sector(sector_id) camp = self.get_campaign_by_sector(sector_id)
@ -268,7 +293,9 @@ class Model:
war = self.get_war_by_campaign(campaign_id) war = self.get_war_by_campaign(campaign_id)
return war.get_available_war_participants(campaign_id) return war.get_available_war_participants(campaign_id)
def add_campaign_participant(self, camp_id: str, player_id: str, leader: str, theme: str) -> CampaignParticipant: def add_campaign_participant(
self, camp_id: str, player_id: str, leader: str, theme: str
) -> CampaignParticipant:
camp = self.get_campaign(camp_id) camp = self.get_campaign(camp_id)
return camp.add_campaign_participant(player_id, leader, theme) return camp.add_campaign_participant(player_id, leader, theme)
@ -280,7 +307,9 @@ class Model:
return part return part
raise KeyError("Participant not found") raise KeyError("Participant not found")
def update_campaign_participant(self, participant_id: str, *, leader: str, theme: str): def update_campaign_participant(
self, participant_id: str, *, leader: str, theme: str
):
camp = self.get_campaign_by_campaign_participant(participant_id) camp = self.get_campaign_by_campaign_participant(participant_id)
camp.update_campaign_participant(participant_id, leader=leader, theme=theme) camp.update_campaign_participant(participant_id, leader=leader, theme=theme)
@ -324,27 +353,59 @@ class Model:
war = self.get_war_by_round(round_id) war = self.get_war_by_round(round_id)
return war.create_choice(round_id, participant_id) return war.create_choice(round_id, participant_id)
def remove_choice(self, round_id: str, participant_id: str):
war = self.get_war_by_round(round_id)
war.remove_choice(round_id, participant_id)
def get_round_choices_data(self, round_id: str): def get_round_choices_data(self, round_id: str):
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
participants = camp.participants.values() participants = camp.participants.values()
sectors = [ sectors = [s for s in camp.sectors.values() if s.round_id == round_id]
s for s in camp.sectors.values()
if s.round_id == round_id
]
return camp, rnd, participants, sectors return camp, rnd, participants, sectors
def update_choice(
self,
round_id: str,
participant_id: str,
priority_sector_id: str | None,
secondary_sector_id: str | None,
comment: str | None,
):
war = self.get_war_by_round(round_id)
war.update_choice(
round_id, participant_id, priority_sector_id, secondary_sector_id, comment
)
def remove_choice(self, round_id: str, participant_id: str):
war = self.get_war_by_round(round_id)
war.remove_choice(round_id, participant_id)
# Battle methods # Battle methods
def create_battle(self, round_id: str, sector_id: str) -> Battle: def create_battle(self, round_id: str, sector_id: str) -> Battle:
war = self.get_war_by_round(round_id) war = self.get_war_by_round(round_id)
return war.create_battle(round_id, sector_id) return war.create_battle(round_id, sector_id)
def update_battle(
self,
round_id: str,
sector_id: str,
player_1_id: str | None,
player_2_id: str | None,
winner_id: str | None,
score: str | None,
victory_condition: str | None,
comment: str | None,
):
war = self.get_war_by_round(round_id)
war.update_battle(
round_id,
sector_id,
player_1_id,
player_2_id,
winner_id,
score,
victory_condition,
comment,
)
def remove_battle(self, round_id: str, sector_id: str): def remove_battle(self, round_id: str, sector_id: str):
war = self.get_war_by_round(round_id) war = self.get_war_by_round(round_id)
war.remove_battle(round_id, sector_id) war.remove_battle(round_id, sector_id)

View file

@ -1,5 +1,6 @@
from uuid import uuid4 from uuid import uuid4
class Player: class Player:
def __init__(self, name): def __init__(self, name):
self.id = str(uuid4()) self.id = str(uuid4())
@ -12,10 +13,7 @@ class Player:
self.name = name self.name = name
def toDict(self): def toDict(self):
return { return {"id": self.id, "name": self.name}
"id" : self.id,
"name" : self.name
}
@staticmethod @staticmethod
def fromDict(data: dict): def fromDict(data: dict):

View file

@ -4,6 +4,7 @@ from pathlib import Path
DATA_FILE = Path("data/warmachron.json") DATA_FILE = Path("data/warmachron.json")
def load_data(): def load_data():
if not DATA_FILE.exists() or DATA_FILE.stat().st_size == 0: if not DATA_FILE.exists() or DATA_FILE.stat().st_size == 0:
return {"version": 1, "players": {}, "wars": []} return {"version": 1, "players": {}, "wars": []}
@ -14,6 +15,7 @@ def load_data():
except json.JSONDecodeError: except json.JSONDecodeError:
raise RuntimeError("Data file is corrupted") raise RuntimeError("Data file is corrupted")
def save_data(data): def save_data(data):
if DATA_FILE.exists(): if DATA_FILE.exists():
shutil.copy(DATA_FILE, DATA_FILE.with_suffix(".json.bak")) shutil.copy(DATA_FILE, DATA_FILE.with_suffix(".json.bak"))

View file

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from uuid import uuid4 from uuid import uuid4
class Round: class Round:
def __init__(self): def __init__(self):
self.id: str = str(uuid4()) self.id: str = str(uuid4())
@ -20,7 +21,7 @@ class Round:
# "sectors" : self.sectors, # "sectors" : self.sectors,
# "choices" : self.choices, # "choices" : self.choices,
# "battles" : self.battles, # "battles" : self.battles,
"is_over": self.is_over "is_over": self.is_over,
} }
@staticmethod @staticmethod
@ -43,12 +44,18 @@ class Round:
choice = Choice( choice = Choice(
participant_id=participant_id, participant_id=participant_id,
priority_sector_id=None, priority_sector_id=None,
secondary_sector_id = None secondary_sector_id=None,
) )
self.choices[participant_id] = choice self.choices[participant_id] = choice
return self.choices[participant_id] return self.choices[participant_id]
def update_choice(self, participant_id: str, priority_sector_id: str | None, secondary_sector_id: str | None, comment: str | None): def update_choice(
self,
participant_id: str,
priority_sector_id: str | None,
secondary_sector_id: str | None,
comment: str | None,
):
choice = self.get_choice(participant_id) choice = self.get_choice(participant_id)
choice.set_priority(priority_sector_id) choice.set_priority(priority_sector_id)
choice.set_secondary(secondary_sector_id) choice.set_secondary(secondary_sector_id)
@ -64,15 +71,20 @@ class Round:
def create_battle(self, sector_id: str) -> Battle: def create_battle(self, sector_id: str) -> Battle:
if sector_id not in self.battles: if sector_id not in self.battles:
battle = Battle( battle = Battle(sector_id=sector_id, player_1_id=None, player_2_id=None)
sector_id = sector_id,
player_1_id = None,
player_2_id = None
)
self.battles[sector_id] = battle self.battles[sector_id] = battle
return self.battles[sector_id] return self.battles[sector_id]
def update_battle(self, sector_id: str, player_1_id: str | None, player_2_id: str | None, winner_id: str | None, score: str | None, victory_condition: str | None, comment: str | None): def update_battle(
self,
sector_id: str,
player_1_id: str | None,
player_2_id: str | None,
winner_id: str | None,
score: str | None,
victory_condition: str | None,
comment: str | None,
):
bat = self.get_battle(sector_id) bat = self.get_battle(sector_id)
bat.set_player_1(player_1_id) bat.set_player_1(player_1_id)
bat.set_player_2(player_2_id) bat.set_player_2(player_2_id)
@ -84,11 +96,21 @@ class Round:
def remove_battle(self, sector_id: str): def remove_battle(self, sector_id: str):
del self.battles[sector_id] del self.battles[sector_id]
class Choice: class Choice:
def __init__(self, participant_id: str, priority_sector_id: str | None = None, secondary_sector_id: str | None = None): def __init__(
self,
participant_id: str,
priority_sector_id: str | None = None,
secondary_sector_id: str | None = None,
):
self.participant_id: str = participant_id # ref to Campaign.participants self.participant_id: str = participant_id # ref to Campaign.participants
self.priority_sector_id: str | None = priority_sector_id # ref to Campaign.sectors self.priority_sector_id: str | None = (
self.secondary_sector_id: str | None = secondary_sector_id # ref to Campaign.sectors priority_sector_id # ref to Campaign.sectors
)
self.secondary_sector_id: str | None = (
secondary_sector_id # ref to Campaign.sectors
)
self.comment: str | None = None self.comment: str | None = None
def set_id(self, new_id: str): def set_id(self, new_id: str):
@ -103,8 +125,14 @@ class Choice:
def set_comment(self, new_comment: str): def set_comment(self, new_comment: str):
self.comment = new_comment self.comment = new_comment
class Battle: class Battle:
def __init__(self, sector_id: str, player_1_id: str | None = None, player_2_id: str | None = None): def __init__(
self,
sector_id: str,
player_1_id: str | None = None,
player_2_id: str | None = None,
):
self.sector_id: str = sector_id # ref to Campaign.sector self.sector_id: str = sector_id # ref to Campaign.sector
self.player_1_id: str | None = player_1_id # ref to Campaign.participants self.player_1_id: str | None = player_1_id # ref to Campaign.participants
self.player_2_id: str | None = player_2_id # ref to Campaign.participants self.player_2_id: str | None = player_2_id # ref to Campaign.participants

View file

@ -213,6 +213,10 @@ class War:
camp = self.get_campaign(campaign_id) camp = self.get_campaign(campaign_id)
return camp.add_round() return camp.add_round()
def add_battle(self, campaign_id: str) -> Round:
camp = self.get_campaign(campaign_id)
return camp.add_round()
def remove_round(self, round_id: str): def remove_round(self, round_id: str):
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
camp.remove_round(round_id) camp.remove_round(round_id)
@ -223,6 +227,15 @@ class War:
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
return camp.create_choice(round_id, participant_id) return camp.create_choice(round_id, participant_id)
def update_choice(self,
round_id: str,
participant_id: str,
priority_sector_id: str | None,
secondary_sector_id: str | None,
comment: str | None):
camp = self.get_campaign_by_round(round_id)
camp.update_choice(participant_id, priority_sector_id, secondary_sector_id, comment)
def remove_choice(self, round_id: str, participant_id: str): def remove_choice(self, round_id: str, participant_id: str):
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
camp.remove_choice(round_id, participant_id) camp.remove_choice(round_id, participant_id)
@ -233,6 +246,18 @@ class War:
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
return camp.create_battle(round_id, sector_id) return camp.create_battle(round_id, sector_id)
def update_battle(self,
round_id: str,
sector_id: str,
player_1_id: str | None,
player_2_id: str | None,
winner_id: str | None,
score: str | None,
victory_condition: str | None,
comment: str | None):
camp = self.get_campaign_by_round(round_id)
camp.update_battle(sector_id, player_1_id, player_2_id, winner_id, score, victory_condition, comment)
def remove_battle(self, round_id: str, sector_id: str): def remove_battle(self, round_id: str, sector_id: str):
camp = self.get_campaign_by_round(round_id) camp = self.get_campaign_by_round(round_id)
camp.remove_battle(round_id, sector_id) camp.remove_battle(round_id, sector_id)

View file

@ -21,6 +21,7 @@ from warchron.view.ui.ui_battle_result_dialog import Ui_battleResultDialog
# utils... # utils...
def select_if_exists(combo, value): def select_if_exists(combo, value):
if value is None: if value is None:
return return
@ -28,17 +29,21 @@ def select_if_exists(combo, value):
if idx != -1: if idx != -1:
combo.setCurrentIndex(idx) combo.setCurrentIndex(idx)
def format_war_label(war) -> str: def format_war_label(war) -> str:
return f"{war.name} ({war.year})" return f"{war.name} ({war.year})"
def format_campaign_label(camp) -> str: def format_campaign_label(camp) -> str:
return f"{camp.name} ({calendar.month_name[camp.month]})" return f"{camp.name} ({calendar.month_name[camp.month]})"
def format_round_label(round, index: int) -> str: def format_round_label(round, index: int) -> str:
if index is None: if index is None:
return "" return ""
return f"Round {index}" return f"Round {index}"
class View(QtWidgets.QMainWindow, Ui_MainWindow): class View(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None): def __init__(self, parent=None):
super(View, self).__init__(parent) super(View, self).__init__(parent)
@ -51,24 +56,46 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
self.on_delete_item = None self.on_delete_item = None
self.show_details(None) self.show_details(None)
self.playersTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.playersTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.playersTable.customContextMenuRequested.connect(self._on_players_table_context_menu) self.playersTable.customContextMenuRequested.connect(
self._on_players_table_context_menu
)
self.warsTree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.warsTree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.warsTree.customContextMenuRequested.connect(self._on_wars_tree_context_menu) self.warsTree.customContextMenuRequested.connect(
self._on_wars_tree_context_menu
)
self.addCampaignBtn.clicked.connect(self._on_add_campaign_clicked) self.addCampaignBtn.clicked.connect(self._on_add_campaign_clicked)
self.addRoundBtn.clicked.connect(self._on_add_round_clicked) self.addRoundBtn.clicked.connect(self._on_add_round_clicked)
# Pages # Pages
self.warParticipantsTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.warParticipantsTable.setContextMenuPolicy(
self.warParticipantsTable.customContextMenuRequested.connect(self._on_war_participants_table_context_menu) Qt.ContextMenuPolicy.CustomContextMenu
self.objectivesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) )
self.objectivesTable.customContextMenuRequested.connect(self._on_objectives_table_context_menu) self.warParticipantsTable.customContextMenuRequested.connect(
self.campaignParticipantsTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self._on_war_participants_table_context_menu
self.campaignParticipantsTable.customContextMenuRequested.connect(self._on_campaign_participants_table_context_menu) )
self.objectivesTable.setContextMenuPolicy(
Qt.ContextMenuPolicy.CustomContextMenu
)
self.objectivesTable.customContextMenuRequested.connect(
self._on_objectives_table_context_menu
)
self.campaignParticipantsTable.setContextMenuPolicy(
Qt.ContextMenuPolicy.CustomContextMenu
)
self.campaignParticipantsTable.customContextMenuRequested.connect(
self._on_campaign_participants_table_context_menu
)
self.sectorsTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.sectorsTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.sectorsTable.customContextMenuRequested.connect(self._on_sectors_table_context_menu) self.sectorsTable.customContextMenuRequested.connect(
self._on_sectors_table_context_menu
)
self.choicesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.choicesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.choicesTable.customContextMenuRequested.connect(self._on_choices_table_context_menu) self.choicesTable.customContextMenuRequested.connect(
self._on_choices_table_context_menu
)
self.battlesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.battlesTable.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.battlesTable.customContextMenuRequested.connect(self._on_battles_table_context_menu) self.battlesTable.customContextMenuRequested.connect(
self._on_battles_table_context_menu
)
def _emit_selection_changed(self, current, previous): def _emit_selection_changed(self, current, previous):
if not self.on_tree_selection_changed: if not self.on_tree_selection_changed:
@ -76,10 +103,12 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
if not current: if not current:
self.on_tree_selection_changed(None) self.on_tree_selection_changed(None)
return return
self.on_tree_selection_changed({ self.on_tree_selection_changed(
{
"type": current.data(0, ROLE_TYPE), "type": current.data(0, ROLE_TYPE),
"id": current.data(0, ROLE_ID), "id": current.data(0, ROLE_ID),
}) }
)
def get_current_tab(self) -> str: def get_current_tab(self) -> str:
index = self.tabWidget.currentIndex() index = self.tabWidget.currentIndex()
@ -101,19 +130,13 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
def ask_open_file(self) -> Path | None: def ask_open_file(self) -> Path | None:
filename, _ = QFileDialog.getOpenFileName( filename, _ = QFileDialog.getOpenFileName(
self, self, "Open war history", "", "WarChron files (*.json)"
"Open war history",
"",
"WarChron files (*.json)"
) )
return Path(filename) if filename else None return Path(filename) if filename else None
def ask_save_file(self) -> Path | None: def ask_save_file(self) -> Path | None:
filename, _ = QFileDialog.getSaveFileName( filename, _ = QFileDialog.getSaveFileName(
self, self, "Save war history", "", "WarChron files (*.json)"
"Save war history",
"",
"WarChron files (*.json)"
) )
return Path(filename) if filename else None return Path(filename) if filename else None
@ -216,6 +239,7 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
if walk(item.child(i)): if walk(item.child(i)):
return True return True
return False return False
for i in range(self.warsTree.topLevelItemCount()): for i in range(self.warsTree.topLevelItemCount()):
if walk(self.warsTree.topLevelItem(i)): if walk(self.warsTree.topLevelItem(i)):
return return
@ -224,10 +248,7 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
item = self.warsTree.currentItem() item = self.warsTree.currentItem()
if not item: if not item:
return None return None
return { return {"type": item.data(0, ROLE_TYPE), "id": item.data(0, ROLE_ID)}
"type": item.data(0, ROLE_TYPE),
"id": item.data(0, ROLE_ID)
}
def show_details(self, item_type: str | None): def show_details(self, item_type: str | None):
if item_type == ItemType.WAR: if item_type == ItemType.WAR:
@ -347,13 +368,19 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
self.campaignName.setText(name) self.campaignName.setText(name)
self.campaignMonth.setText(calendar.month_name[month]) self.campaignMonth.setText(calendar.month_name[month])
def display_campaign_sectors(self, sectors: list[tuple[str, str, str, str, str, str]]): def display_campaign_sectors(
self, sectors: list[tuple[str, str, str, str, str, str]]
):
table = self.sectorsTable table = self.sectorsTable
table.clearContents() table.clearContents()
table.setRowCount(len(sectors)) table.setRowCount(len(sectors))
for row, (name, round_index, major, minor, influence, pid) in enumerate(sectors): for row, (name, round_index, major, minor, influence, pid) in enumerate(
sectors
):
name_item = QtWidgets.QTableWidgetItem(name) name_item = QtWidgets.QTableWidgetItem(name)
round_item = QtWidgets.QTableWidgetItem(format_round_label(None, round_index)) round_item = QtWidgets.QTableWidgetItem(
format_round_label(None, round_index)
)
major_item = QtWidgets.QTableWidgetItem(major) major_item = QtWidgets.QTableWidgetItem(major)
minor_item = QtWidgets.QTableWidgetItem(minor) minor_item = QtWidgets.QTableWidgetItem(minor)
influence_item = QtWidgets.QTableWidgetItem(influence) influence_item = QtWidgets.QTableWidgetItem(influence)
@ -365,7 +392,9 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
table.setItem(row, 4, influence_item) table.setItem(row, 4, influence_item)
table.resizeColumnsToContents() table.resizeColumnsToContents()
def display_campaign_participants(self, participants: list[tuple[str, str, str, str]]): def display_campaign_participants(
self, participants: list[tuple[str, str, str, str]]
):
table = self.campaignParticipantsTable table = self.campaignParticipantsTable
table.clearContents() table.clearContents()
table.setRowCount(len(participants)) table.setRowCount(len(participants))
@ -422,7 +451,9 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
table = self.choicesTable table = self.choicesTable
table.clearContents() table.clearContents()
table.setRowCount(len(participants)) table.setRowCount(len(participants))
for row, (participant, priority, secondary, choice_id) in enumerate(participants): for row, (participant, priority, secondary, choice_id) in enumerate(
participants
):
participant_item = QtWidgets.QTableWidgetItem(participant) participant_item = QtWidgets.QTableWidgetItem(participant)
priority_item = QtWidgets.QTableWidgetItem(priority) priority_item = QtWidgets.QTableWidgetItem(priority)
secondary_item = QtWidgets.QTableWidgetItem(secondary) secondary_item = QtWidgets.QTableWidgetItem(secondary)
@ -446,6 +477,7 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
table.setItem(row, 2, player_2_item) table.setItem(row, 2, player_2_item)
table.resizeColumnsToContents() table.resizeColumnsToContents()
class PlayerDialog(QDialog): class PlayerDialog(QDialog):
def __init__(self, parent=None, *, default_name: str = ""): def __init__(self, parent=None, *, default_name: str = ""):
super().__init__(parent) super().__init__(parent)
@ -456,8 +488,11 @@ class PlayerDialog(QDialog):
def get_player_name(self) -> str: def get_player_name(self) -> str:
return self.ui.playerName.text().strip() return self.ui.playerName.text().strip()
class WarDialog(QDialog): class WarDialog(QDialog):
def __init__(self, parent=None, default_name: str = "", default_year: int | None = None): def __init__(
self, parent=None, default_name: str = "", default_year: int | None = None
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_warDialog() self.ui = Ui_warDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -471,8 +506,11 @@ class WarDialog(QDialog):
def get_war_year(self) -> int: def get_war_year(self) -> int:
return int(self.ui.warYear.value()) return int(self.ui.warYear.value())
class CampaignDialog(QDialog): class CampaignDialog(QDialog):
def __init__(self, parent=None, default_name: str = "", default_month: int | None = None): def __init__(
self, parent=None, default_name: str = "", default_month: int | None = None
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_campaignDialog() self.ui = Ui_campaignDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -486,6 +524,7 @@ class CampaignDialog(QDialog):
def get_campaign_month(self) -> int: def get_campaign_month(self) -> int:
return int(self.ui.campaignMonth.value()) return int(self.ui.campaignMonth.value())
class ObjectiveDialog(QDialog): class ObjectiveDialog(QDialog):
def __init__(self, parent=None, *, default_name="", default_description=""): def __init__(self, parent=None, *, default_name="", default_description=""):
super().__init__(parent) super().__init__(parent)
@ -500,8 +539,17 @@ class ObjectiveDialog(QDialog):
def get_objective_description(self) -> str: def get_objective_description(self) -> str:
return self.ui.objectiveDescription.toPlainText().strip() return self.ui.objectiveDescription.toPlainText().strip()
class WarParticipantDialog(QDialog): class WarParticipantDialog(QDialog):
def __init__(self, parent=None, *, players: list, default_player_id=None, default_faction="", editable_player=True): def __init__(
self,
parent=None,
*,
players: list,
default_player_id=None,
default_faction="",
editable_player=True,
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_warParticipantDialog() self.ui = Ui_warParticipantDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -517,8 +565,18 @@ class WarParticipantDialog(QDialog):
def get_participant_faction(self) -> str: def get_participant_faction(self) -> str:
return self.ui.faction.text().strip() return self.ui.faction.text().strip()
class CampaignParticipantDialog(QDialog): class CampaignParticipantDialog(QDialog):
def __init__(self, parent=None, *, participants: list[ParticipantOption], default_participant_id=None, default_leader="", default_theme="", editable_player=True): def __init__(
self,
parent=None,
*,
participants: list[ParticipantOption],
default_participant_id=None,
default_leader="",
default_theme="",
editable_player=True,
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_campaignParticipantDialog() self.ui = Ui_campaignParticipantDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -538,8 +596,20 @@ class CampaignParticipantDialog(QDialog):
def get_participant_theme(self) -> str: def get_participant_theme(self) -> str:
return self.ui.theme.text().strip() return self.ui.theme.text().strip()
class SectorDialog(QDialog): class SectorDialog(QDialog):
def __init__(self, parent=None, *, default_name="", rounds: list, default_round_id=None, objectives: list, default_major_id=None, default_minor_id=None, default_influence_id=None): def __init__(
self,
parent=None,
*,
default_name="",
rounds: list,
default_round_id=None,
objectives: list,
default_major_id=None,
default_minor_id=None,
default_influence_id=None,
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_sectorDialog() self.ui = Ui_sectorDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -573,14 +643,19 @@ class SectorDialog(QDialog):
def get_influence_id(self) -> str: def get_influence_id(self) -> str:
return self.ui.influenceComboBox.currentData() return self.ui.influenceComboBox.currentData()
class ChoicesDialog(QDialog): class ChoicesDialog(QDialog):
def __init__(self, parent = None, *, def __init__(
self,
parent=None,
*,
participants: list, participants: list,
default_participant_id=None, default_participant_id=None,
sectors: list, sectors: list,
default_priority_id=None, default_priority_id=None,
default_secondary_id=None, default_secondary_id=None,
default_comment = None): default_comment=None,
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_choicesDialog() self.ui = Ui_choicesDialog()
self.ui.setupUi(self) self.ui.setupUi(self)
@ -609,8 +684,12 @@ class ChoicesDialog(QDialog):
def get_comment(self) -> str: def get_comment(self) -> str:
return self.ui.choiceComment.toPlainText().strip() return self.ui.choiceComment.toPlainText().strip()
class BattlesDialog(QDialog): class BattlesDialog(QDialog):
def __init__(self, parent = None, *, def __init__(
self,
parent=None,
*,
sectors: list, sectors: list,
default_sector_id=None, default_sector_id=None,
players: list, players: list,
@ -619,7 +698,8 @@ class BattlesDialog(QDialog):
default_winner_id=None, default_winner_id=None,
default_score=None, default_score=None,
default_victory_condition=None, default_victory_condition=None,
default_comment = None): default_comment=None,
):
super().__init__(parent) super().__init__(parent)
self.ui = Ui_battleResultDialog() self.ui = Ui_battleResultDialog()
self.ui.setupUi(self) self.ui.setupUi(self)