Compare commits

..

No commits in common. "60fc88af75f84c4b9dd610658ed0f18c3884bd58" and "d869017646142208fa7b4113d3efc55c429a1a0d" have entirely different histories.

13 changed files with 165 additions and 379 deletions

View file

@ -3,7 +3,11 @@ from pathlib import Path
from PyQt6.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
from warchron.model.model import Model from warchron.model.model import Model
from warchron.model.exception import DomainError, RequiresConfirmation from warchron.model.exception import (
DeletionForbidden,
DeletionRequiresConfirmation,
UpdateRequiresConfirmation,
)
from warchron.view.view import View from warchron.view.view import View
from warchron.constants import ItemType, RefreshScope from warchron.constants import ItemType, RefreshScope
from warchron.controller.navigation_controller import NavigationController from warchron.controller.navigation_controller import NavigationController
@ -31,7 +35,8 @@ class AppController:
self.navigation.refresh_wars_view() self.navigation.refresh_wars_view()
self.update_window_title() self.update_window_title()
self.view.on_tree_selection_changed = self.navigation.on_tree_selection_changed self.view.on_tree_selection_changed = self.navigation.on_tree_selection_changed
self.view.on_add_item = self.add_item self.view.on_add_campaign = self.campaigns.add_campaign
self.view.on_add_round = self.rounds.add_round
def __connect(self) -> None: def __connect(self) -> None:
self.view.actionExit.triggered.connect(self.view.close) self.view.actionExit.triggered.connect(self.view.close)
@ -40,25 +45,20 @@ class AppController:
self.view.actionSave.triggered.connect(self.save) self.view.actionSave.triggered.connect(self.save)
self.view.actionSave_as.triggered.connect(self.save_as) self.view.actionSave_as.triggered.connect(self.save_as)
self.view.actionAbout.triggered.connect(self.show_about) self.view.actionAbout.triggered.connect(self.show_about)
self.view.addPlayerBtn.clicked.connect(lambda: self.add_item(ItemType.PLAYER)) self.view.addPlayerBtn.clicked.connect(self.players.add_player)
self.view.addWarBtn.clicked.connect(lambda: self.add_item(ItemType.WAR)) self.view.addWarBtn.clicked.connect(self.wars.add_war)
self.view.majorValue.valueChanged.connect(self.wars.set_major_value) self.view.majorValue.valueChanged.connect(self.wars.set_major_value)
self.view.minorValue.valueChanged.connect(self.wars.set_minor_value) self.view.minorValue.valueChanged.connect(self.wars.set_minor_value)
self.view.influenceToken.toggled.connect(self.wars.set_influence_token) self.view.influenceToken.toggled.connect(self.wars.set_influence_token)
self.view.addObjectiveBtn.clicked.connect( self.view.addObjectiveBtn.clicked.connect(self.wars.add_objective)
lambda: self.add_item(ItemType.OBJECTIVE) self.view.addWarParticipantBtn.clicked.connect(self.wars.add_war_participant)
)
self.view.addWarParticipantBtn.clicked.connect(
lambda: self.add_item(ItemType.WAR_PARTICIPANT)
)
self.view.endWarBtn.clicked.connect(self.wars.close_war) self.view.endWarBtn.clicked.connect(self.wars.close_war)
self.view.addSectorBtn.clicked.connect(lambda: self.add_item(ItemType.SECTOR)) self.view.addSectorBtn.clicked.connect(self.campaigns.add_sector)
self.view.addCampaignParticipantBtn.clicked.connect( self.view.addCampaignParticipantBtn.clicked.connect(
lambda: self.add_item(ItemType.CAMPAIGN_PARTICIPANT) self.campaigns.add_campaign_participant
) )
self.view.endCampaignBtn.clicked.connect(self.campaigns.close_campaign) self.view.endCampaignBtn.clicked.connect(self.campaigns.close_campaign)
self.view.endRoundBtn.clicked.connect(self.rounds.close_round) self.view.endRoundBtn.clicked.connect(self.rounds.close_round)
self.view.on_add_item = self.add_item
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
@ -165,72 +165,6 @@ class AppController:
# Command methods # Command methods
def add_item(self, item_type: str) -> None:
try:
if item_type == ItemType.PLAYER:
play = self.players.create_player()
if not play:
return
self.navigation.refresh(RefreshScope.PLAYERS_LIST)
elif item_type == ItemType.WAR:
war = self.wars.create_war()
if not war:
return
self.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id
)
elif item_type == ItemType.CAMPAIGN:
camp = self.campaigns.create_campaign()
if not camp:
return
self.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id
)
elif item_type == ItemType.OBJECTIVE:
obj = self.wars.create_objective()
if not obj:
return
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
elif item_type == ItemType.WAR_PARTICIPANT:
war_part = self.wars.create_war_participant()
if not war_part:
return
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
elif item_type == ItemType.SECTOR:
sect = self.campaigns.create_sector()
if not sect:
return
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
elif item_type == ItemType.CAMPAIGN_PARTICIPANT:
camp_part = self.campaigns.create_campaign_participant()
if not camp_part:
return
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
elif item_type == ItemType.ROUND:
rnd = self.rounds.create_round()
if not rnd:
return
self.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id
)
self.is_dirty = True
except DomainError as e:
QMessageBox.warning(
self.view,
"Deletion forbidden",
str(e),
)
except RequiresConfirmation as e:
reply = QMessageBox.question(
self.view,
"Confirm update",
str(e),
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
)
if reply == QMessageBox.StandardButton.Yes:
e.action()
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def edit_item(self, item_type: str, item_id: str) -> None: def edit_item(self, item_type: str, item_id: str) -> None:
try: try:
if item_type == ItemType.PLAYER: if item_type == ItemType.PLAYER:
@ -265,21 +199,15 @@ class AppController:
self.rounds.edit_round_battle(item_id) self.rounds.edit_round_battle(item_id)
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS) self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
self.is_dirty = True self.is_dirty = True
except DomainError as e: except UpdateRequiresConfirmation as e:
QMessageBox.warning(
self.view,
"Deletion forbidden",
str(e),
)
except RequiresConfirmation as e:
reply = QMessageBox.question( reply = QMessageBox.question(
self.view, self.view,
"Confirm update", "Confirm update",
str(e), e.message,
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
) )
if reply == QMessageBox.StandardButton.Yes: if reply == QMessageBox.StandardButton.Yes:
e.action() e.apply_update()
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS) self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def delete_item(self, item_type: str, item_id: str) -> None: def delete_item(self, item_type: str, item_id: str) -> None:
@ -325,19 +253,19 @@ class AppController:
RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp_id RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp_id
) )
self.is_dirty = True self.is_dirty = True
except DomainError as e: except DeletionForbidden as e:
QMessageBox.warning( QMessageBox.warning(
self.view, self.view,
"Deletion forbidden", "Deletion forbidden",
str(e), e.reason,
) )
except RequiresConfirmation as e: except DeletionRequiresConfirmation as e:
reply = QMessageBox.question( reply = QMessageBox.question(
self.view, self.view,
"Confirm deletion", "Confirm deletion",
str(e), e.message,
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
) )
if reply == QMessageBox.StandardButton.Yes: if reply == QMessageBox.StandardButton.Yes:
e.action() e.cleanup_action()
self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS) self.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)

View file

@ -2,7 +2,7 @@ from typing import List, TYPE_CHECKING
from PyQt6.QtWidgets import QMessageBox, QDialog from PyQt6.QtWidgets import QMessageBox, QDialog
from warchron.constants import RefreshScope from warchron.constants import ItemType, RefreshScope
if TYPE_CHECKING: if TYPE_CHECKING:
from warchron.controller.app_controller import AppController from warchron.controller.app_controller import AppController
@ -13,9 +13,6 @@ from warchron.controller.dtos import (
SectorDTO, SectorDTO,
RoundDTO, RoundDTO,
) )
from warchron.model.campaign import Campaign
from warchron.model.campaign_participant import CampaignParticipant
from warchron.model.sector import Sector
from warchron.model.closure_service import ClosureService from warchron.model.closure_service import ClosureService
from warchron.view.campaign_dialog import CampaignDialog from warchron.view.campaign_dialog import CampaignDialog
from warchron.view.campaign_participant_dialog import CampaignParticipantDialog from warchron.view.campaign_participant_dialog import CampaignParticipantDialog
@ -71,9 +68,9 @@ class CampaignController:
return False return False
return True return True
def create_campaign(self) -> Campaign | None: def add_campaign(self) -> None:
if not self.app.navigation.selected_war_id: if not self.app.navigation.selected_war_id:
return None return
dialog = CampaignDialog( dialog = CampaignDialog(
self.app.view, self.app.view,
default_month=self.app.model.get_default_campaign_values( default_month=self.app.model.get_default_campaign_values(
@ -81,18 +78,18 @@ class CampaignController:
)["month"], )["month"],
) )
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return None return
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 None return
return self.app.model.add_campaign( camp = self.app.model.add_campaign(
self.app.navigation.selected_war_id, name, month self.app.navigation.selected_war_id, name, month
) )
# self.app.is_dirty = True self.app.is_dirty = True
# self.app.navigation.refresh_and_select( self.app.navigation.refresh_and_select(
# RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id
# ) )
def edit_campaign(self, campaign_id: str) -> None: def edit_campaign(self, campaign_id: str) -> None:
camp = self.app.model.get_campaign(campaign_id) camp = self.app.model.get_campaign(campaign_id)
@ -131,9 +128,9 @@ class CampaignController:
# Campaign participant methods # Campaign participant methods
def create_campaign_participant(self) -> CampaignParticipant | None: def add_campaign_participant(self) -> None:
if not self.app.navigation.selected_campaign_id: if not self.app.navigation.selected_campaign_id:
return None return
participants = self.app.model.get_available_war_participants( participants = self.app.model.get_available_war_participants(
self.app.navigation.selected_campaign_id self.app.navigation.selected_campaign_id
) )
@ -143,15 +140,17 @@ class CampaignController:
] ]
dialog = CampaignParticipantDialog(self.app.view, participants=part_opts) dialog = CampaignParticipantDialog(self.app.view, participants=part_opts)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return None return
player_id = dialog.get_player_id() player_id = dialog.get_player_id()
leader = dialog.get_participant_leader() leader = dialog.get_participant_leader()
theme = dialog.get_participant_theme() theme = dialog.get_participant_theme()
if not player_id: if not player_id:
return None return
return self.app.model.add_campaign_participant( self.app.model.add_campaign_participant(
self.app.navigation.selected_campaign_id, player_id, leader, theme self.app.navigation.selected_campaign_id, player_id, leader, theme
) )
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def edit_campaign_participant(self, participant_id: str) -> None: def edit_campaign_participant(self, participant_id: str) -> None:
camp_part = self.app.model.get_campaign_participant(participant_id) camp_part = self.app.model.get_campaign_participant(participant_id)
@ -192,9 +191,9 @@ class CampaignController:
# allow same objectives in different fields? # allow same objectives in different fields?
return True return True
def create_sector(self) -> Sector | None: def add_sector(self) -> None:
if not self.app.navigation.selected_campaign_id: if not self.app.navigation.selected_campaign_id:
return None return
war = self.app.model.get_war_by_campaign( war = self.app.model.get_war_by_campaign(
self.app.navigation.selected_campaign_id self.app.navigation.selected_campaign_id
) )
@ -213,7 +212,7 @@ class CampaignController:
self.app.view, default_name="", rounds=rnd_objs, objectives=obj_dtos self.app.view, default_name="", rounds=rnd_objs, objectives=obj_dtos
) )
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return None return
name = dialog.get_sector_name() name = dialog.get_sector_name()
round_id = dialog.get_round_id() round_id = dialog.get_round_id()
major_id = dialog.get_major_id() major_id = dialog.get_major_id()
@ -224,8 +223,8 @@ class CampaignController:
if not self._validate_sector_inputs( if not self._validate_sector_inputs(
name, round_id, major_id, minor_id, influence_id name, round_id, major_id, minor_id, influence_id
): ):
return None return
return self.app.model.add_sector( self.app.model.add_sector(
self.app.navigation.selected_campaign_id, self.app.navigation.selected_campaign_id,
name, name,
round_id, round_id,
@ -235,6 +234,8 @@ class CampaignController:
mission, mission,
description, description,
) )
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def edit_sector(self, sector_id: str) -> None: def edit_sector(self, sector_id: str) -> None:
sect = self.app.model.get_sector(sector_id) sect = self.app.model.get_sector(sector_id)

View file

@ -3,7 +3,6 @@ from typing import TYPE_CHECKING
from PyQt6.QtWidgets import QMessageBox, QDialog from PyQt6.QtWidgets import QMessageBox, QDialog
from warchron.constants import RefreshScope from warchron.constants import RefreshScope
from warchron.model.player import Player
if TYPE_CHECKING: if TYPE_CHECKING:
from warchron.controller.app_controller import AppController from warchron.controller.app_controller import AppController
@ -22,15 +21,16 @@ class PlayerController:
return False return False
return True return True
def create_player(self) -> Player | None: def add_player(self) -> None:
dialog = PlayerDialog(self.app.view) dialog = PlayerDialog(self.app.view)
result = dialog.exec() result = dialog.exec() # modal blocking dialog
if result != QDialog.DialogCode.Accepted: if result == QDialog.DialogCode.Accepted:
return None
name = dialog.get_player_name() name = dialog.get_player_name()
if not self._validate_player_inputs(name): if not self._validate_player_inputs(name):
return None return
return self.app.model.add_player(name) self.app.model.add_player(name)
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.PLAYERS_LIST)
def edit_player(self, player_id: str) -> None: def edit_player(self, player_id: str) -> None:
play = self.app.model.get_player(player_id) play = self.app.model.get_player(player_id)

View file

@ -3,7 +3,6 @@ from typing import List, TYPE_CHECKING
from PyQt6.QtWidgets import QDialog, QMessageBox from PyQt6.QtWidgets import QDialog, QMessageBox
from warchron.constants import ItemType, RefreshScope, Icons, IconName from warchron.constants import ItemType, RefreshScope, Icons, IconName
from warchron.model.round import Round
if TYPE_CHECKING: if TYPE_CHECKING:
from warchron.controller.app_controller import AppController from warchron.controller.app_controller import AppController
@ -112,11 +111,14 @@ class RoundController:
self.app.view.display_round_battles(battles_for_display) self.app.view.display_round_battles(battles_for_display)
self.app.view.endRoundBtn.setEnabled(not rnd.is_over) self.app.view.endRoundBtn.setEnabled(not rnd.is_over)
def create_round(self) -> Round | None: def add_round(self) -> None:
campaign_id = self.app.navigation.selected_campaign_id if not self.app.navigation.selected_campaign_id:
if not campaign_id: return
return None rnd = self.app.model.add_round(self.app.navigation.selected_campaign_id)
return self.app.model.add_round(campaign_id) self.app.is_dirty = True
self.app.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=rnd.id
)
def close_round(self) -> None: def close_round(self) -> None:
round_id = self.app.navigation.selected_round_id round_id = self.app.navigation.selected_round_id
@ -139,9 +141,7 @@ class RoundController:
return return
self.app.is_dirty = True self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS) self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
self.app.navigation.refresh_and_select( self.app.navigation.refresh(RefreshScope.WARS_TREE)
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=round_id
)
# Choice methods # Choice methods

View file

@ -2,8 +2,7 @@ from typing import List, TYPE_CHECKING
from PyQt6.QtWidgets import QMessageBox, QDialog from PyQt6.QtWidgets import QMessageBox, QDialog
from warchron.constants import RefreshScope from warchron.constants import ItemType, RefreshScope
from warchron.model.exception import DomainError
if TYPE_CHECKING: if TYPE_CHECKING:
from warchron.controller.app_controller import AppController from warchron.controller.app_controller import AppController
@ -12,9 +11,6 @@ from warchron.controller.dtos import (
WarParticipantDTO, WarParticipantDTO,
ObjectiveDTO, ObjectiveDTO,
) )
from warchron.model.war import War
from warchron.model.war_participant import WarParticipant
from warchron.model.objective import Objective
from warchron.model.closure_service import ClosureService from warchron.model.closure_service import ClosureService
from warchron.view.war_dialog import WarDialog from warchron.view.war_dialog import WarDialog
from warchron.view.objective_dialog import ObjectiveDialog from warchron.view.objective_dialog import ObjectiveDialog
@ -64,18 +60,21 @@ class WarController:
return False return False
return True return True
def create_war(self) -> War | None: def add_war(self) -> None:
dialog = WarDialog( dialog = WarDialog(
self.app.view, default_year=self.app.model.get_default_war_values()["year"] self.app.view, default_year=self.app.model.get_default_war_values()["year"]
) )
result = dialog.exec() result = dialog.exec() # modal blocking dialog
if result != QDialog.DialogCode.Accepted: if result == QDialog.DialogCode.Accepted:
return None
name = dialog.get_war_name() name = dialog.get_war_name()
year = dialog.get_war_year() year = dialog.get_war_year()
if not self._validate_war_inputs(name, year): if not self._validate_war_inputs(name, year):
return None return
return self.app.model.add_war(name, year) war = self.app.model.add_war(name, year)
self.app.is_dirty = True
self.app.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war.id
)
def edit_war(self, war_id: str) -> None: def edit_war(self, war_id: str) -> None:
war = self.app.model.get_war(war_id) war = self.app.model.get_war(war_id)
@ -116,46 +115,22 @@ class WarController:
war_id = self.app.navigation.selected_war_id war_id = self.app.navigation.selected_war_id
if not war_id: if not war_id:
return return
try:
self.app.model.set_major_value(war_id, value) self.app.model.set_major_value(war_id, value)
except DomainError as e:
QMessageBox.warning(
self.app.view,
"Setting forbidden",
str(e),
)
self.app.is_dirty = True self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def set_minor_value(self, value: int) -> None: def set_minor_value(self, value: int) -> None:
war_id = self.app.navigation.selected_war_id war_id = self.app.navigation.selected_war_id
if not war_id: if not war_id:
return return
try:
self.app.model.set_minor_value(war_id, value) self.app.model.set_minor_value(war_id, value)
except DomainError as e:
QMessageBox.warning(
self.app.view,
"Setting forbidden",
str(e),
)
self.app.is_dirty = True self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def set_influence_token(self, checked: bool) -> None: def set_influence_token(self, checked: bool) -> None:
war_id = self.app.navigation.selected_war_id war_id = self.app.navigation.selected_war_id
if not war_id: if not war_id:
return return
try:
self.app.model.set_influence_token(war_id, checked) self.app.model.set_influence_token(war_id, checked)
except DomainError as e:
QMessageBox.warning(
self.app.view,
"Setting forbidden",
str(e),
)
self.app.is_dirty = True self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
# Objective methods # Objective methods
@ -167,19 +142,21 @@ class WarController:
return False return False
return True return True
def create_objective(self) -> Objective | None: def add_objective(self) -> None:
if not self.app.navigation.selected_war_id: if not self.app.navigation.selected_war_id:
return None return
dialog = ObjectiveDialog(self.app.view) dialog = ObjectiveDialog(self.app.view)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return None return
name = dialog.get_objective_name() name = dialog.get_objective_name()
description = dialog.get_objective_description() description = dialog.get_objective_description()
if not self._validate_objective_inputs(name, description): if not self._validate_objective_inputs(name, description):
return None return
return self.app.model.add_objective( self.app.model.add_objective(
self.app.navigation.selected_war_id, name, description self.app.navigation.selected_war_id, name, description
) )
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def edit_objective(self, objective_id: str) -> None: def edit_objective(self, objective_id: str) -> None:
obj = self.app.model.get_objective(objective_id) obj = self.app.model.get_objective(objective_id)
@ -197,9 +174,9 @@ class WarController:
# War participant methods # War participant methods
def create_war_participant(self) -> WarParticipant | None: def add_war_participant(self) -> None:
if not self.app.navigation.selected_war_id: if not self.app.navigation.selected_war_id:
return None return
players = self.app.model.get_available_players( players = self.app.model.get_available_players(
self.app.navigation.selected_war_id self.app.navigation.selected_war_id
) )
@ -208,14 +185,16 @@ class WarController:
] ]
dialog = WarParticipantDialog(self.app.view, players=play_opts) dialog = WarParticipantDialog(self.app.view, players=play_opts)
if dialog.exec() != QDialog.DialogCode.Accepted: if dialog.exec() != QDialog.DialogCode.Accepted:
return None return
player_id = dialog.get_player_id() player_id = dialog.get_player_id()
faction = dialog.get_participant_faction() faction = dialog.get_participant_faction()
if not player_id: if not player_id:
return None return
return self.app.model.add_war_participant( self.app.model.add_war_participant(
self.app.navigation.selected_war_id, player_id, faction self.app.navigation.selected_war_id, player_id, faction
) )
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
def edit_war_participant(self, participant_id: str) -> None: def edit_war_participant(self, participant_id: str) -> None:
war_part = self.app.model.get_war_participant(participant_id) war_part = self.app.model.get_war_participant(participant_id)

View file

@ -2,7 +2,10 @@ from __future__ import annotations
from uuid import uuid4 from uuid import uuid4
from typing import Any, Dict, List from typing import Any, Dict, List
from warchron.model.exception import ForbiddenOperation, RequiresConfirmation from warchron.model.exception import (
DeletionRequiresConfirmation,
UpdateRequiresConfirmation,
)
from warchron.model.campaign_participant import CampaignParticipant from warchron.model.campaign_participant import CampaignParticipant
from warchron.model.sector import Sector from warchron.model.sector import Sector
from warchron.model.round import Round from warchron.model.round import Round
@ -75,8 +78,6 @@ class Campaign:
def add_campaign_participant( def add_campaign_participant(
self, war_participant_id: str, leader: str, theme: str self, war_participant_id: str, leader: str, theme: str
) -> CampaignParticipant: ) -> CampaignParticipant:
if self.is_over:
raise ForbiddenOperation("Can't add participant in a closed campaign.")
if self.has_war_participant(war_participant_id): if self.has_war_participant(war_participant_id):
raise ValueError("Player already registered in this campaign") raise ValueError("Player already registered in this campaign")
participant = CampaignParticipant( participant = CampaignParticipant(
@ -97,16 +98,12 @@ class Campaign:
def update_campaign_participant( def update_campaign_participant(
self, participant_id: str, *, leader: str, theme: str self, participant_id: str, *, leader: str, theme: str
) -> None: ) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update participant in a closed campaign.")
part = self.get_campaign_participant(participant_id) part = self.get_campaign_participant(participant_id)
# Can't change referred War.participant # Can't change referred War.participant
part.set_leader(leader) part.set_leader(leader)
part.set_theme(theme) part.set_theme(theme)
def remove_campaign_participant(self, participant_id: str) -> None: def remove_campaign_participant(self, participant_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove participant in a closed campaign.")
rounds_blocking: list[Round] = [] rounds_blocking: list[Round] = []
for rnd in self.rounds: for rnd in self.rounds:
if rnd.has_choice_with_participant( if rnd.has_choice_with_participant(
@ -126,11 +123,13 @@ class Campaign:
rounds_str = ", ".join( rounds_str = ", ".join(
str(self.get_round_index(rnd.id)) for rnd in rounds_blocking str(self.get_round_index(rnd.id)) for rnd in rounds_blocking
) )
raise RequiresConfirmation( raise DeletionRequiresConfirmation(
message=(
f"This participant is used in round(s): {rounds_str}.\n" f"This participant is used in round(s): {rounds_str}.\n"
"Related choices and battles will be cleared.\n" "Related choices and battles will be cleared.\n"
"Do you want to continue?", "Do you want to continue?"
action=cleanup, ),
cleanup_action=cleanup,
) )
# Sector methods # Sector methods
@ -156,8 +155,6 @@ class Campaign:
mission: str | None, mission: str | None,
description: str | None, description: str | None,
) -> Sector: ) -> Sector:
if self.is_over:
raise ForbiddenOperation("Can't add sector in a closed campaign.")
sect = Sector( sect = Sector(
name, round_id, major_id, minor_id, influence_id, mission, description name, round_id, major_id, minor_id, influence_id, mission, description
) )
@ -187,8 +184,6 @@ class Campaign:
mission: str | None, mission: str | None,
description: str | None, description: str | None,
) -> None: ) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update sector in a closed campaign.")
sect = self.get_sector(sector_id) sect = self.get_sector(sector_id)
old_round_id = sect.round_id old_round_id = sect.round_id
@ -224,16 +219,16 @@ class Campaign:
rounds_str = ", ".join( rounds_str = ", ".join(
str(self.get_round_index(rnd.id)) for rnd in affected_rounds str(self.get_round_index(rnd.id)) for rnd in affected_rounds
) )
raise RequiresConfirmation( raise UpdateRequiresConfirmation(
message=(
f"Changing the round of this sector will affect round(s): {rounds_str}." f"Changing the round of this sector will affect round(s): {rounds_str}."
"\nRelated battles and choices will be cleared.\n" "\nRelated battles and choices will be cleared.\n"
"Do you want to continue?", "Do you want to continue?"
action=cleanup_and_update, ),
apply_update=cleanup_and_update,
) )
def remove_sector(self, sector_id: str) -> None: def remove_sector(self, sector_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove sector in a closed campaign.")
rounds_blocking: list[Round] = [] rounds_blocking: list[Round] = []
for rnd in self.rounds: for rnd in self.rounds:
if rnd.has_battle_with_sector(sector_id) or rnd.has_choice_with_sector( if rnd.has_battle_with_sector(sector_id) or rnd.has_choice_with_sector(
@ -253,11 +248,13 @@ class Campaign:
rounds_str = ", ".join( rounds_str = ", ".join(
str(self.get_round_index(rnd.id)) for rnd in rounds_blocking str(self.get_round_index(rnd.id)) for rnd in rounds_blocking
) )
raise RequiresConfirmation( raise DeletionRequiresConfirmation(
message=(
f"This sector is used in round(s): {rounds_str}.\n" f"This sector is used in round(s): {rounds_str}.\n"
"Battles and choices using this sector will be cleared.\n" "Battles and choices using this sector will be cleared.\n"
"Do you want to continue?", "Do you want to continue?"
action=cleanup, ),
cleanup_action=cleanup,
) )
def get_sectors_in_round(self, round_id: str) -> List[Sector]: def get_sectors_in_round(self, round_id: str) -> List[Sector]:
@ -269,15 +266,6 @@ class Campaign:
def has_round(self, round_id: str) -> bool: def has_round(self, round_id: str) -> bool:
return any(r.id == round_id for r in self.rounds) return any(r.id == round_id for r in self.rounds)
def has_finished_round(self) -> bool:
return any(r.is_over for r in self.rounds)
def has_finished_battle(self) -> bool:
return any(r.has_finished_battle() for r in self.rounds)
def all_rounds_finished(self) -> bool:
return all(r.is_over for r in self.rounds)
def get_round(self, round_id: str) -> Round: def get_round(self, round_id: str) -> Round:
for rnd in self.rounds: for rnd in self.rounds:
if rnd.id == round_id: if rnd.id == round_id:
@ -288,21 +276,12 @@ class Campaign:
return list(self.rounds) return list(self.rounds)
def add_round(self) -> Round: def add_round(self) -> Round:
if self.is_over:
raise ForbiddenOperation("Can't add round in a closed campaign.")
round = Round() round = Round()
self.rounds.append(round) self.rounds.append(round)
return round return round
def remove_round(self, round_id: str) -> None: def remove_round(self, round_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove round in a closed campaign.")
rnd = next((r for r in self.rounds if r.id == round_id), None) rnd = next((r for r in self.rounds if r.id == round_id), None)
if rnd:
if rnd.is_over:
raise ForbiddenOperation("Can't remove closed round.")
if rnd.has_finished_battle():
raise ForbiddenOperation("Can't remove round with finished battle(s).")
for sect in self.sectors.values(): for sect in self.sectors.values():
if sect.round_id == round_id: if sect.round_id == round_id:
sect.round_id = None sect.round_id = None
@ -342,6 +321,9 @@ class Campaign:
# Battle methods # Battle methods
def all_rounds_finished(self) -> bool:
return all(r.is_over for r in self.rounds)
def create_battle(self, round_id: str, sector_id: str) -> Battle: def create_battle(self, round_id: str, sector_id: str) -> Battle:
rnd = self.get_round(round_id) rnd = self.get_round(round_id)
return rnd.create_battle(sector_id) return rnd.create_battle(sector_id)

View file

@ -1,19 +0,0 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from warchron.model.war import War
from warchron.model.war import War
from warchron.model.war import War
from warchron.model.closure_service import ClosureService
class RoundClosureWorkflow:
def close_round(self, round_id):
rnd = repo.get_round(round_id)
ties = ClosureService.close_round(rnd)
repo.save()
return ties

View file

@ -1,25 +1,31 @@
from typing import Callable from typing import Callable
class DomainError(Exception): class DeletionForbidden(Exception):
"""Base class for all domain rule violations.""" def __init__(self, reason: str):
self.reason = reason
pass super().__init__(reason)
class ForbiddenOperation(DomainError): class DeletionRequiresConfirmation(Exception):
"""Generic 'you can't do this' rule.""" def __init__(
self,
pass message: str,
*,
cleanup_action: Callable[[], None],
class DomainDecision(Exception): ):
"""Base class for domain actions requiring user decision.""" self.message = message
self.cleanup_action = cleanup_action
pass super().__init__(message)
class RequiresConfirmation(DomainDecision): class UpdateRequiresConfirmation(Exception):
def __init__(self, message: str, action: Callable[[], None]): def __init__(
self,
message: str,
*,
apply_update: Callable[[], None],
):
self.message = message
self.apply_update = apply_update
super().__init__(message) super().__init__(message)
self.action = action

View file

@ -4,7 +4,7 @@ import json
import shutil import shutil
from datetime import datetime from datetime import datetime
from warchron.model.exception import ForbiddenOperation from warchron.model.exception import DeletionForbidden
from warchron.model.player import Player from warchron.model.player import Player
from warchron.model.war import War from warchron.model.war import War
from warchron.model.war_participant import WarParticipant from warchron.model.war_participant import WarParticipant
@ -91,7 +91,7 @@ class Model:
wars_using_player.append(war.name) wars_using_player.append(war.name)
if wars_using_player: if wars_using_player:
wars_str = ", ".join(wars_using_player) wars_str = ", ".join(wars_using_player)
raise ForbiddenOperation( raise DeletionForbidden(
f"This player is participating in war(s): {wars_str}.\n" f"This player is participating in war(s): {wars_str}.\n"
"Remove it from participants first." "Remove it from participants first."
) )
@ -159,42 +159,25 @@ class Model:
def update_war(self, war_id: str, *, name: str, year: int) -> None: def update_war(self, war_id: str, *, name: str, year: int) -> None:
war = self.get_war(war_id) war = self.get_war(war_id)
if war.is_over:
raise ForbiddenOperation("Can't update a closed war.")
war.set_name(name) war.set_name(name)
war.set_year(year) war.set_year(year)
def set_major_value(self, war_id: str, value: int) -> None: def set_major_value(self, war_id: str, value: int) -> None:
war = self.get_war(war_id) war = self.get_war(war_id)
war.set_major_value(value) war.set_major(value)
def set_minor_value(self, war_id: str, value: int) -> None: def set_minor_value(self, war_id: str, value: int) -> None:
war = self.get_war(war_id) war = self.get_war(war_id)
war.set_minor_value(value) war.set_minor(value)
def set_influence_token(self, war_id: str, value: bool) -> None: def set_influence_token(self, war_id: str, value: bool) -> None:
war = self.get_war(war_id) war = self.get_war(war_id)
war.set_influence_token(value) war.set_influence(value)
def get_all_wars(self) -> List[War]: def get_all_wars(self) -> List[War]:
return list(self.wars.values()) return list(self.wars.values())
def remove_war(self, war_id: str) -> None: def remove_war(self, war_id: str) -> None:
war = self.wars[war_id]
if war:
if war.is_over:
raise ForbiddenOperation("Can't remove closed war.")
if war.has_finished_campaign():
raise ForbiddenOperation("Can't remove war with finished campaign(s).")
if war.has_finished_round():
raise ForbiddenOperation(
"Can't remove war with finished round(s) in campaign(s)."
)
if war.has_finished_battle():
raise ForbiddenOperation(
"Can't remove war with finished battle(s) in round(s) "
"in campaign(s)."
)
del self.wars[war_id] del self.wars[war_id]
# Objective methods # Objective methods

View file

@ -2,7 +2,6 @@ from __future__ import annotations
from uuid import uuid4 from uuid import uuid4
from typing import Any, Dict from typing import Any, Dict
from warchron.model.exception import ForbiddenOperation
from warchron.model.choice import Choice from warchron.model.choice import Choice
from warchron.model.battle import Battle from warchron.model.battle import Battle
@ -59,8 +58,6 @@ class Round:
) )
def create_choice(self, participant_id: str) -> Choice: def create_choice(self, participant_id: str) -> Choice:
if self.is_over:
raise ForbiddenOperation("Can't create choice in a closed round.")
if participant_id not in self.choices: if participant_id not in self.choices:
choice = Choice( choice = Choice(
participant_id=participant_id, participant_id=participant_id,
@ -77,8 +74,6 @@ class Round:
secondary_sector_id: str | None, secondary_sector_id: str | None,
comment: str | None, comment: str | None,
) -> None: ) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update choice in a closed round.")
choice = self.get_choice(participant_id) choice = self.get_choice(participant_id)
if choice: if choice:
choice.set_priority(priority_sector_id) choice.set_priority(priority_sector_id)
@ -93,8 +88,6 @@ class Round:
choice.secondary_sector_id = None choice.secondary_sector_id = None
def remove_choice(self, participant_id: str) -> None: def remove_choice(self, participant_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove choice in a closed round.")
del self.choices[participant_id] del self.choices[participant_id]
# Battle methods # Battle methods
@ -111,17 +104,12 @@ class Round:
for bat in self.battles.values() for bat in self.battles.values()
) )
def has_finished_battle(self) -> bool:
return any(b.is_finished() for b in self.battles.values())
def all_battles_finished(self) -> bool: def all_battles_finished(self) -> bool:
return all( return all(
b.winner_id is not None or b.is_draw() for b in self.battles.values() b.winner_id is not None or b.is_draw() for b in self.battles.values()
) )
def create_battle(self, sector_id: str) -> Battle: def create_battle(self, sector_id: str) -> Battle:
if self.is_over:
raise ForbiddenOperation("Can't create battle in a closed round.")
if sector_id not in self.battles: if sector_id not in self.battles:
battle = Battle(sector_id=sector_id, player_1_id=None, player_2_id=None) battle = Battle(sector_id=sector_id, player_1_id=None, player_2_id=None)
self.battles[sector_id] = battle self.battles[sector_id] = battle
@ -137,8 +125,6 @@ class Round:
victory_condition: str | None, victory_condition: str | None,
comment: str | None, comment: str | None,
) -> None: ) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update battle in a closed round.")
bat = self.get_battle(sector_id) bat = self.get_battle(sector_id)
if bat: if bat:
bat.set_player_1(player_1_id) bat.set_player_1(player_1_id)
@ -158,9 +144,4 @@ class Round:
battle.winner_id = None battle.winner_id = None
def remove_battle(self, sector_id: str) -> None: def remove_battle(self, sector_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove battle in a closed round.")
bat = self.battles[sector_id]
if bat and bat.is_finished():
raise ForbiddenOperation("Can't remove finished battle.")
del self.battles[sector_id] del self.battles[sector_id]

View file

@ -37,9 +37,3 @@ class ScoreService:
if sector.minor_objective_id: if sector.minor_objective_id:
totals[sector.minor_objective_id] += war.minor_value totals[sector.minor_objective_id] += war.minor_value
return totals return totals
# def compute_round_results(round)
# def compute_campaign_winner(campaign)
# def compute_war_winner(war)

View file

@ -3,7 +3,7 @@ from uuid import uuid4
from datetime import datetime from datetime import datetime
from typing import Any, Dict, List from typing import Any, Dict, List
from warchron.model.exception import ForbiddenOperation from warchron.model.exception import DeletionForbidden
from warchron.model.war_participant import WarParticipant from warchron.model.war_participant import WarParticipant
from warchron.model.objective import Objective from warchron.model.objective import Objective
from warchron.model.campaign_participant import CampaignParticipant from warchron.model.campaign_participant import CampaignParticipant
@ -36,23 +36,17 @@ class War:
def set_year(self, new_year: int) -> None: def set_year(self, new_year: int) -> None:
self.year = new_year self.year = new_year
def set_major_value(self, new_value: int) -> None: def set_major(self, new_value: int) -> None:
if self.is_over:
raise ForbiddenOperation("Can't set major value of a closed war.")
if new_value < self.minor_value: if new_value < self.minor_value:
raise ValueError("Can' set major value < minor value") raise ValueError("major_value cannot be < minor_value")
self.major_value = new_value self.major_value = new_value
def set_minor_value(self, new_value: int) -> None: def set_minor(self, new_value: int) -> None:
if self.is_over:
raise ForbiddenOperation("Can't set minor value of a closed war.")
if new_value > self.major_value: if new_value > self.major_value:
raise ValueError("Can't set minor value > major value") raise ValueError("minor_value cannot be > major_value")
self.minor_value = new_value self.minor_value = new_value
def set_influence_token(self, new_state: bool) -> None: def set_influence(self, new_state: bool) -> None:
if self.is_over:
raise ForbiddenOperation("Can't set influence token of a closed war.")
self.influence_token = new_state self.influence_token = new_state
def set_state(self, new_state: bool) -> None: def set_state(self, new_state: bool) -> None:
@ -93,8 +87,6 @@ class War:
# Objective methods # Objective methods
def add_objective(self, name: str, description: str | None) -> Objective: def add_objective(self, name: str, description: str | None) -> Objective:
if self.is_over:
raise ForbiddenOperation("Can't add objective in a closed war.")
obj = Objective(name, description) obj = Objective(name, description)
self.objectives[obj.id] = obj self.objectives[obj.id] = obj
return obj return obj
@ -114,22 +106,18 @@ class War:
def update_objective( def update_objective(
self, objective_id: str, *, name: str, description: str | None self, objective_id: str, *, name: str, description: str | None
) -> None: ) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update objective in a closed war.")
obj = self.get_objective(objective_id) obj = self.get_objective(objective_id)
obj.set_name(name) obj.set_name(name)
obj.set_description(description) obj.set_description(description)
def remove_objective(self, objective_id: str) -> None: def remove_objective(self, objective_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove objective in a closed war.")
camp_using_obj: List[str] = [] camp_using_obj: List[str] = []
for camp in self.campaigns: for camp in self.campaigns:
if camp.has_sector_with_objective(objective_id): if camp.has_sector_with_objective(objective_id):
camp_using_obj.append(camp.name) camp_using_obj.append(camp.name)
if camp_using_obj: if camp_using_obj:
camps_str = ", ".join(camp_using_obj) camps_str = ", ".join(camp_using_obj)
raise ForbiddenOperation( raise DeletionForbidden(
f"This objective is used in campaign(s) sector(s): {camps_str}.\n" f"This objective is used in campaign(s) sector(s): {camps_str}.\n"
"Remove it from campaign(s) first." "Remove it from campaign(s) first."
) )
@ -147,8 +135,6 @@ class War:
return any(part.player_id == player_id for part in self.participants.values()) return any(part.player_id == player_id for part in self.participants.values())
def add_war_participant(self, player_id: str, faction: str) -> WarParticipant: def add_war_participant(self, player_id: str, faction: str) -> WarParticipant:
if self.is_over:
raise ForbiddenOperation("Can't add participant in a closed war.")
if self.has_player(player_id): if self.has_player(player_id):
raise ValueError("Player already registered in this war") raise ValueError("Player already registered in this war")
participant = WarParticipant(player_id=player_id, faction=faction) participant = WarParticipant(player_id=player_id, faction=faction)
@ -162,22 +148,18 @@ class War:
return list(self.participants.values()) return list(self.participants.values())
def update_war_participant(self, participant_id: str, *, faction: str) -> None: def update_war_participant(self, participant_id: str, *, faction: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update participant in a closed war.")
part = self.get_war_participant(participant_id) part = self.get_war_participant(participant_id)
# Can't change referred Model.players # Can't change referred Model.players
part.set_faction(faction) part.set_faction(faction)
def remove_war_participant(self, participant_id: str) -> None: def remove_war_participant(self, participant_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove participant in a closed war.")
camp_using_part: List[str] = [] camp_using_part: List[str] = []
for camp in self.campaigns: for camp in self.campaigns:
if camp.has_war_participant(participant_id): if camp.has_war_participant(participant_id):
camp_using_part.append(camp.name) camp_using_part.append(camp.name)
if camp_using_part: if camp_using_part:
camps_str = ", ".join(camp_using_part) camps_str = ", ".join(camp_using_part)
raise ForbiddenOperation( raise DeletionForbidden(
f"This war participant is used in campaign(s): {camps_str}.\n" f"This war participant is used in campaign(s): {camps_str}.\n"
"Remove it from campaign(s) first." "Remove it from campaign(s) first."
) )
@ -191,21 +173,10 @@ class War:
def get_default_campaign_values(self) -> Dict[str, Any]: def get_default_campaign_values(self) -> Dict[str, Any]:
return {"month": datetime.now().month} return {"month": datetime.now().month}
def has_finished_campaign(self) -> bool:
return any(c.is_over for c in self.campaigns)
def has_finished_round(self) -> bool:
return any(c.has_finished_round() for c in self.campaigns)
def has_finished_battle(self) -> bool:
return any(c.has_finished_battle() for c in self.campaigns)
def all_campaigns_finished(self) -> bool: def all_campaigns_finished(self) -> bool:
return all(c.is_over for c in self.campaigns) return all(c.is_over for c in self.campaigns)
def add_campaign(self, name: str, month: int | None = None) -> Campaign: def add_campaign(self, name: str, month: int | None = None) -> Campaign:
if self.is_over:
raise ForbiddenOperation("Can't add campaign in a closed war.")
if month is None: if month is None:
month = self.get_default_campaign_values()["month"] month = self.get_default_campaign_values()["month"]
campaign = Campaign(name, month) campaign = Campaign(name, month)
@ -241,11 +212,7 @@ class War:
raise KeyError(f"Participant {participant_id} not found in any Campaign") raise KeyError(f"Participant {participant_id} not found in any Campaign")
def update_campaign(self, campaign_id: str, *, name: str, month: int) -> None: def update_campaign(self, campaign_id: str, *, name: str, month: int) -> None:
if self.is_over:
raise ForbiddenOperation("Can't update campaign in a closed war.")
camp = self.get_campaign(campaign_id) camp = self.get_campaign(campaign_id)
if camp.is_over:
raise ForbiddenOperation("Can't update a closed campaign.")
camp.set_name(name) camp.set_name(name)
camp.set_month(month) camp.set_month(month)
@ -253,20 +220,7 @@ class War:
return list(self.campaigns) return list(self.campaigns)
def remove_campaign(self, campaign_id: str) -> None: def remove_campaign(self, campaign_id: str) -> None:
if self.is_over:
raise ForbiddenOperation("Can't remove campaign in a closed war.")
camp = self.get_campaign(campaign_id) camp = self.get_campaign(campaign_id)
if camp:
if camp.is_over:
raise ForbiddenOperation("Can't remove closed campaign.")
if camp.has_finished_round():
raise ForbiddenOperation(
"Can't remove campaign with finished round(s)."
)
if camp.has_finished_battle():
raise ForbiddenOperation(
"Can't remove campaign with finished battle(s) in round(s)."
)
self.campaigns.remove(camp) self.campaigns.remove(camp)
# Sector methods # Sector methods

View file

@ -41,7 +41,8 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
self.majorValue.setMinimum(0) self.majorValue.setMinimum(0)
self.minorValue.setMinimum(0) self.minorValue.setMinimum(0)
self.on_influence_token_changed: Callable[[int], None] | None = None self.on_influence_token_changed: Callable[[int], None] | None = None
self.on_add_item: Callable[[str], None] | None = None self.on_add_campaign: Callable[[], None] | None = None
self.on_add_round: Callable[[], None] | None = None
self.on_edit_item: Callable[[str, str], None] | None = None self.on_edit_item: Callable[[str, str], None] | None = None
self.on_delete_item: Callable[[str, str], None] | None = None self.on_delete_item: Callable[[str, str], None] | None = None
self.splitter.setSizes([200, 800]) self.splitter.setSizes([200, 800])
@ -201,12 +202,12 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
# Wars view # Wars view
def _on_add_campaign_clicked(self) -> None: def _on_add_campaign_clicked(self) -> None:
if self.on_add_item: if self.on_add_campaign:
self.on_add_item(ItemType.CAMPAIGN) self.on_add_campaign()
def _on_add_round_clicked(self) -> None: def _on_add_round_clicked(self) -> None:
if self.on_add_item: if self.on_add_round:
self.on_add_item(ItemType.ROUND) self.on_add_round()
def set_add_campaign_enabled(self, enabled: bool) -> None: def set_add_campaign_enabled(self, enabled: bool) -> None:
self.addCampaignBtn.setEnabled(enabled) self.addCampaignBtn.setEnabled(enabled)
@ -237,10 +238,6 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
def display_wars_tree(self, wars: List[WarDTO]) -> None: def display_wars_tree(self, wars: List[WarDTO]) -> None:
tree = self.warsTree tree = self.warsTree
try:
tree.currentItemChanged.disconnect()
except TypeError:
pass
tree.clear() tree.clear()
tree.setColumnCount(1) tree.setColumnCount(1)
tree.setHeaderLabels(["Wars"]) tree.setHeaderLabels(["Wars"])