diff --git a/src/warchron/constants.py b/src/warchron/constants.py
index 1d431b6..dce34fd 100644
--- a/src/warchron/constants.py
+++ b/src/warchron/constants.py
@@ -13,6 +13,8 @@ class ItemType(StrEnum):
ROUND = "round"
OBJECTIVE = "objective"
WAR_PARTICIPANT = "war_participant"
+ SECTOR = "sector"
+ CAMPAIGN_PARTICIPANT = "campaign_participant"
class RefreshScope(Enum):
NONE = auto()
diff --git a/src/warchron/controller/controller.py b/src/warchron/controller/controller.py
index af71bbd..626e21c 100644
--- a/src/warchron/controller/controller.py
+++ b/src/warchron/controller/controller.py
@@ -1,12 +1,12 @@
from pathlib import Path
-from datetime import datetime
from PyQt6.QtWidgets import QMessageBox, QDialog
from warchron.model.model import Model
from warchron.view.view import View
from warchron.constants import ItemType, RefreshScope
-from warchron.view.view import PlayerDialog, WarDialog, CampaignDialog, ObjectiveDialog, ParticipantDialog
+from warchron.view.view import PlayerDialog, WarDialog, CampaignDialog, ObjectiveDialog, WarParticipantDialog, CampaignParticipantDialog, SectorDialog
+from warchron.controller.dtos import ParticipantOption
class Controller:
def __init__(self, model: Model, view: View):
@@ -37,6 +37,8 @@ class Controller:
self.view.addWarBtn.clicked.connect(self.add_war)
self.view.addObjectiveBtn.clicked.connect(self.add_objective)
self.view.addWarParticipantBtn.clicked.connect(self.add_war_participant)
+ self.view.addSectorBtn.clicked.connect(self.add_sector)
+ self.view.addCampaignParticipantBtn.clicked.connect(self.add_campaign_participant)
self.view.on_edit_item = self.edit_item
self.view.on_delete_item = self.delete_item
@@ -145,6 +147,22 @@ class Controller:
def _fill_campaign_details(self, campaign_id: str):
camp = self.model.get_campaign(campaign_id)
self.view.show_campaign_details(name=camp.name, month=camp.month)
+ sectors = camp.get_all_sectors()
+ sectors_for_display = []
+ war = self.model.get_war_by_campaign(camp.id)
+ for sect in sectors:
+ round_index = camp.get_round_index(sect.round_id)
+ major_name = war.get_objective_name(sect.major_objective_id)
+ minor_name = war.get_objective_name(sect.minor_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))
+ self.view.display_campaign_sectors(sectors_for_display)
+ participants = camp.get_all_campaign_participants()
+ participants_for_display = [
+ (self.model.get_player_name(p.id), p.leader, p.theme, p.id)
+ for p in participants
+ ]
+ self.view.display_campaign_participants(participants_for_display)
def _fill_round_details(self, round_id: str):
index = self.model.get_round_index(round_id)
@@ -248,12 +266,65 @@ class Controller:
elif item_type == ItemType.WAR_PARTICIPANT:
part = self.model.get_war_participant(item_id)
player = self.model.get_player(part.id)
- dialog = ParticipantDialog(self.view, players=[player], default_player_id=part.id, default_faction=part.faction)
+ dialog = WarParticipantDialog(
+ self.view,
+ players=[player],
+ default_player_id=part.id,
+ default_faction=part.faction,
+ editable_player=False
+ )
if dialog.exec() == QDialog.DialogCode.Accepted:
- id = dialog.get_player_id()
faction = dialog.get_participant_faction()
self.model.update_war_participant(item_id, faction=faction)
self.refresh(RefreshScope.WAR_DETAILS)
+ elif item_type == ItemType.SECTOR:
+ sect = self.model.get_sector(item_id)
+ camp = self.model.get_campaign_by_sector(item_id)
+ war = self.model.get_war_by_campaign(camp.id)
+ rounds = camp.get_all_rounds()
+ objectives = war.get_all_objectives()
+ dialog = SectorDialog(
+ self.view,
+ default_name=sect.name,
+ rounds=rounds,
+ default_round_id=sect.round_id,
+ objectives=objectives,
+ default_major_id=sect.major_objective_id,
+ default_minor_id=sect.minor_objective_id,
+ default_influence_id=sect.influence_objective_id,
+ )
+ if dialog.exec() == QDialog.DialogCode.Accepted:
+ name = dialog.get_sector_name()
+ round_id = dialog.get_round_id()
+ major_id = dialog.get_major_id()
+ minor_id = dialog.get_minor_id()
+ influence_id = dialog.get_influence_id()
+ self.model.update_sector(
+ item_id,
+ name=name,
+ round_id=round_id,
+ major_id=major_id,
+ minor_id=minor_id,
+ influence_id=influence_id
+ )
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
+ elif item_type == ItemType.CAMPAIGN_PARTICIPANT:
+ part = self.model.get_campaign_participant(item_id)
+ player = self.model.get_player(part.id)
+ part_opt = [ParticipantOption(id=player.id, name=player.name)]
+ dialog = CampaignParticipantDialog(
+ self.view,
+ participants=part_opt,
+ default_participant_id=part.id,
+ default_leader=part.leader,
+ default_theme=part.theme,
+ editable_player=False
+ )
+ if dialog.exec() == QDialog.DialogCode.Accepted:
+ leader = dialog.get_participant_leader()
+ theme = dialog.get_participant_theme()
+ self.model.update_campaign_participant(item_id, leader=leader, theme=theme)
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
self.is_dirty = True
def delete_item(self, item_type: str, item_id: str):
@@ -282,6 +353,12 @@ class Controller:
elif item_type == ItemType.WAR_PARTICIPANT:
self.model.remove_war_participant(item_id)
self.refresh(RefreshScope.WAR_DETAILS)
+ elif item_type == ItemType.SECTOR:
+ self.model.remove_sector(item_id)
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
+ elif item_type == ItemType.CAMPAIGN_PARTICIPANT:
+ self.model.remove_campaign_participant(item_id)
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
elif item_type == ItemType.ROUND:
camp = self.model.get_campaign_by_round(item_id)
camp_id = camp.id
@@ -345,12 +422,12 @@ class Controller:
# Objective methods
- def _validate_objective_inputs(self, name: str, description: int) -> bool:
+ def _validate_objective_inputs(self, name: str, description: str) -> bool:
if not name.strip():
QMessageBox.warning(
self.view,
"Invalid name",
- "Campaign name cannot be empty."
+ "Objective name cannot be empty."
)
return False
return True
@@ -363,7 +440,7 @@ class Controller:
return
name = dialog.get_objective_name()
description = dialog.get_objective_description()
- if not name:
+ if not self._validate_objective_inputs(name, description):
return
self.model.add_objective(self.selected_war_id, name, description)
self.is_dirty = True
@@ -375,7 +452,7 @@ class Controller:
if not self.selected_war_id:
return
players = self.model.get_available_players(self.selected_war_id)
- dialog = ParticipantDialog(self.view, players=players)
+ dialog = WarParticipantDialog(self.view, players=players)
if dialog.exec() != QDialog.DialogCode.Accepted:
return
player_id = dialog.get_player_id()
@@ -419,6 +496,59 @@ class Controller:
self.is_dirty = True
self.refresh_and_select(RefreshScope.WARS_TREE, item_type=ItemType.CAMPAIGN, item_id=camp.id)
+# Campaign participant methods
+
+ def add_campaign_participant(self):
+ if not self.selected_campaign_id:
+ return
+ participants = self.model.get_available_war_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)
+ if dialog.exec() != QDialog.DialogCode.Accepted:
+ return
+ player_id = dialog.get_player_id()
+ leader = dialog.get_participant_leader()
+ theme = dialog.get_participant_theme()
+ if not player_id:
+ return
+ self.model.add_campaign_participant(self.selected_campaign_id, player_id, leader, theme)
+ self.is_dirty = True
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
+
+# Sector methods
+
+ def _validate_sector_inputs(self, name: str, round_id: str, major_id: str, minor_id: str, influence_id:str) -> bool:
+ if not name.strip():
+ QMessageBox.warning(
+ self.view,
+ "Invalid name",
+ "Sector name cannot be empty."
+ )
+ return False
+ # allow same objectives in different fields?
+ return True
+
+ def add_sector(self):
+ if not self.selected_campaign_id:
+ return
+ war = self.model.get_war_by_campaign(self.selected_campaign_id)
+ camp = self.model.get_campaign(self.selected_campaign_id)
+ rounds = camp.get_all_rounds()
+ objectives = war.get_all_objectives()
+ dialog = SectorDialog(self.view, default_name="", rounds=rounds, objectives=objectives)
+ if dialog.exec() != QDialog.DialogCode.Accepted:
+ return
+ name = dialog.get_sector_name()
+ round_id = dialog.get_round_id()
+ major_id = dialog.get_major_id()
+ minor_id = dialog.get_minor_id()
+ influence_id = dialog.get_influence_id()
+ if not self._validate_sector_inputs(name, round_id, major_id, minor_id, influence_id):
+ return
+ self.model.add_sector(self.selected_campaign_id, name, round_id, major_id, minor_id, influence_id)
+ self.is_dirty = True
+ self.refresh(RefreshScope.CAMPAIGN_DETAILS)
+
# Round methods
def add_round(self):
diff --git a/src/warchron/controller/dtos.py b/src/warchron/controller/dtos.py
new file mode 100644
index 0000000..988e35f
--- /dev/null
+++ b/src/warchron/controller/dtos.py
@@ -0,0 +1,6 @@
+from dataclasses import dataclass
+
+@dataclass(frozen=True)
+class ParticipantOption:
+ id: str
+ name: str
diff --git a/src/warchron/model/campaign.py b/src/warchron/model/campaign.py
index 76c9d9b..e3b5e90 100644
--- a/src/warchron/model/campaign.py
+++ b/src/warchron/model/campaign.py
@@ -1,6 +1,5 @@
from __future__ import annotations
from uuid import uuid4
-from datetime import datetime
from warchron.model.round import Round
@@ -9,8 +8,8 @@ class Campaign:
self.id: str = str(uuid4())
self.name: str = name
self.month: int = month
- self.participants = {}
- self.sectors = {}
+ self.participants: dict[str, CampaignParticipant] = {}
+ self.sectors: dict[str, Sector] = {}
self.rounds = []
self.is_over = False
@@ -46,6 +45,61 @@ class Campaign:
camp.set_state(data.get("is_over", False))
return camp
+# Campaign participant methods
+
+ def get_all_campaign_participants_ids(self) -> set[str]:
+ return set(self.participants.keys())
+
+ def has_participant(self, player_id: str) -> bool:
+ return player_id in self.participants
+
+ def add_campaign_participant(self, player_id: str, leader: str, theme: str) -> CampaignParticipant:
+ if player_id in self.participants:
+ raise ValueError("Player already registered in this campaign")
+ participant = CampaignParticipant(player_id, leader, theme)
+ self.participants[participant.id] = participant
+ return participant
+
+ def get_campaign_participant(self, id: str) -> CampaignParticipant:
+ return self.participants[id]
+
+ def get_all_campaign_participants(self) -> list[CampaignParticipant]:
+ return list(self.participants.values())
+
+ def update_campaign_participant(self, player_id: str, *, leader: str, theme: str):
+ part = self.get_campaign_participant(player_id)
+ part.set_leader(leader)
+ part.set_theme(theme)
+
+ def remove_campaign_participant(self, player_id: str):
+ del self.participants[player_id]
+
+# Sector methods
+
+ def add_sector(self, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str) -> Sector:
+ sect = Sector(name, round_id, major_id, minor_id, influence_id)
+ self.sectors[sect.id] = sect
+ return sect
+
+ def get_sector(self, id: str) -> Sector:
+ return self.sectors[id]
+
+ def get_all_sectors(self) -> list[Sector]:
+ return list(self.sectors.values())
+
+ def update_sector(self, sector_id: str, *, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str):
+ sect = self.get_sector(sector_id)
+ sect.set_name(name)
+ sect.set_round(round_id)
+ sect.set_major(major_id)
+ sect.set_minor(minor_id)
+ sect.set_influence(influence_id)
+
+ def remove_sector(self, sector_id: str):
+ del self.sectors[sector_id]
+
+# Round methods
+
def has_round(self, round_id: str) -> bool:
return any(r.id == round_id for r in self.rounds)
@@ -66,23 +120,59 @@ class Campaign:
self.rounds.remove(rnd)
def get_round_index(self, round_id: str) -> int:
+ if round_id is None:
+ return None
for index, rnd in enumerate(self.rounds, start=1):
if rnd.id == round_id:
return index
raise KeyError("Round not found in campaign")
+ def get_round_name(self, round_id: str | None) -> str:
+ if round_id is None:
+ return ""
+ for rnd in self.rounds:
+ if rnd.id == round_id:
+ return rnd.name
+ return ""
+
class CampaignParticipant:
- def __init__(self,war_participant_id: str, leader: str):
- self.id: str = war_participant_id # ref to War.participants
+ def __init__(self,player_id: str, leader: str, theme: str):
+ self.id: str = player_id # ref to War.participants
self.leader: str = leader
- self.victory_points = 0
- self.objective_points = {}
+ self.theme: str = theme
+
+ def set_id(self, new_id: str):
+ self.id = new_id
+
+ def set_leader(self, new_faction: str):
+ self.leader = new_faction
+
+ def set_theme(self, new_theme: str):
+ self.theme = new_theme
class Sector:
def __init__(self, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str):
self.id: str = str(uuid4())
self.name: str = name
+ self.round_id: str = round_id
self.major_objective_id: str = major_id
self.minor_objective_id: str = minor_id
self.influence_objective_id: str = influence_id
- self.round_id: str = round_id
+
+ def set_id(self, new_id: str):
+ self.id = new_id
+
+ def set_name(self, new_name: str):
+ self.name = new_name
+
+ def set_round(self, new_round_id: str):
+ self.round_id = new_round_id
+
+ def set_major(self, new_major_id: str):
+ self.major_objective_id = new_major_id
+
+ def set_minor(self, new_minor_id: str):
+ self.minor_objective_id = new_minor_id
+
+ def set_influence(self, new_influence_id: str):
+ self.influence_objective_id = new_influence_id
diff --git a/src/warchron/model/model.py b/src/warchron/model/model.py
index 6f8c222..c05b8d1 100644
--- a/src/warchron/model/model.py
+++ b/src/warchron/model/model.py
@@ -5,7 +5,7 @@ from datetime import datetime
from warchron.model.player import Player
from warchron.model.war import War, Objective, WarParticipant
-from warchron.model.campaign import Campaign
+from warchron.model.campaign import Campaign, Sector, CampaignParticipant
from warchron.model.round import Round
class Model:
@@ -156,7 +156,7 @@ class Model:
if not war.has_participant(player.id)
]
- def add_war_participant(self, war_id: str, player_id: str, faction: str) -> Objective:
+ def add_war_participant(self, war_id: str, player_id: str, faction: str) -> WarParticipant:
war = self.get_war(war_id)
return war.add_war_participant(player_id, faction)
@@ -198,7 +198,21 @@ class Model:
if camp is not None:
return camp
raise KeyError(f"Round {round_id} not found")
-
+
+ def get_campaign_by_campaign_participant(self, participant_id: str) -> Campaign:
+ for war in self.wars.values():
+ camp = war.get_campaign_by_campaign_participant(participant_id)
+ if camp is not None:
+ return camp
+ raise KeyError(f"Participant {participant_id} not found")
+
+ def get_campaign_by_sector(self, sector_id: str) -> Campaign:
+ for war in self.wars.values():
+ camp = war.get_campaign_by_sector(sector_id)
+ if camp is not None:
+ return camp
+ raise KeyError(f"Sector {sector_id} not found")
+
def update_campaign(self, campaign_id: str, *, name: str, month: int):
war = self.get_war_by_campaign(campaign_id)
war.update_campaign(campaign_id, name=name, month=month)
@@ -207,16 +221,64 @@ class Model:
war = self.get_war_by_campaign(campaign_id)
war.remove_campaign(campaign_id)
+# Sector methods
+
+ 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)
+ return camp.add_sector(name, round_id, major_id, minor_id, influence_id)
+
+ def get_sector(self, sector_id) -> Sector:
+ for war in self.wars.values():
+ for camp in war.campaigns:
+ for sect in camp.sectors.values():
+ if sect.id == sector_id:
+ return sect
+ 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):
+ camp = self.get_campaign_by_sector(sector_id)
+ camp.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):
+ camp = self.get_campaign_by_sector(sector_id)
+ camp.remove_sector(sector_id)
+
+# Campaign participant methods
+
+ def get_available_war_participants(self, campaign_id: str) -> list[WarParticipant]:
+ war = self.get_war_by_campaign(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:
+ camp = self.get_campaign(camp_id)
+ return camp.add_campaign_participant(player_id, leader, theme)
+
+ def get_campaign_participant(self, participant_id) -> CampaignParticipant:
+ for war in self.wars.values():
+ for camp in war.campaigns:
+ for part in camp.participants.values():
+ if part.id == participant_id:
+ return part
+ raise KeyError("Participant not found")
+
+ def update_campaign_participant(self, participant_id: str, *, leader: str, theme: str):
+ camp = self.get_campaign_by_campaign_participant(participant_id)
+ camp.update_campaign_participant(participant_id, leader=leader, theme=theme)
+
+ def remove_campaign_participant(self, participant_id: str):
+ camp = self.get_campaign_by_campaign_participant(participant_id)
+ camp.remove_campaign_participant(participant_id)
+
# Round methods
def add_round(self, campaign_id: str) -> Round:
- campaign = self.get_campaign(campaign_id)
- return campaign.add_round()
+ camp = self.get_campaign(campaign_id)
+ return camp.add_round()
def get_round(self, round_id: str) -> Round:
for war in self.wars.values():
- for campaign in war.campaigns:
- for rnd in campaign.rounds:
+ for camp in war.campaigns:
+ for rnd in camp.rounds:
if rnd.id == round_id:
return rnd
raise KeyError("Round not found")
diff --git a/src/warchron/model/war.py b/src/warchron/model/war.py
index 9e3b402..db14c78 100644
--- a/src/warchron/model/war.py
+++ b/src/warchron/model/war.py
@@ -2,7 +2,7 @@ from __future__ import annotations
from uuid import uuid4
from datetime import datetime
-from warchron.model.campaign import Campaign
+from warchron.model.campaign import Campaign, Sector, CampaignParticipant
class War:
@@ -50,9 +50,9 @@ class War:
# Objective methods
def add_objective(self, name: str, description: str) -> Objective:
- objective = Objective(name, description)
- self.objectives[objective.id] = objective
- return objective
+ obj = Objective(name, description)
+ self.objectives[obj.id] = obj
+ return obj
def get_objective(self, id: str) -> Objective:
return self.objectives[id]
@@ -60,6 +60,12 @@ class War:
def get_all_objectives(self) -> list[Objective]:
return list(self.objectives.values())
+ def get_objective_name(self, objective_id: str | None) -> str:
+ if objective_id is None:
+ return ""
+ obj = self.objectives.get(objective_id)
+ return obj.name if obj else ""
+
def update_objective(self, objective_id: str, *, name: str, description: str):
obj = self.get_objective(objective_id)
obj.set_name(name)
@@ -126,6 +132,20 @@ class War:
return camp
raise KeyError(f"Round {round_id} not found in any Campaign")
+ def get_campaign_by_sector(self, sector_id: str) -> Campaign:
+ for camp in self.campaigns:
+ for sect in camp.sectors.values():
+ if sect.id == sector_id:
+ return camp
+ raise KeyError(f"Sector {sector_id} not found in any Campaign")
+
+ def get_campaign_by_campaign_participant(self, participant_id: str) -> Campaign:
+ for camp in self.campaigns:
+ for part in camp.participants.values():
+ if part.id == participant_id:
+ return camp
+ raise KeyError(f"Participant {participant_id} not found in any Campaign")
+
def update_campaign(self, campaign_id: str, *, name: str, month: int):
camp = self.get_campaign(campaign_id)
camp.set_name(name)
@@ -138,6 +158,52 @@ class War:
camp = self.get_campaign(campaign_id)
self.campaigns.remove(camp)
+# Sector methods
+
+ def add_sector(self, campaign_id, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str) -> Sector:
+ camp = self.get_campaign(campaign_id)
+ return camp.add_sector(name, round_id, major_id, minor_id, influence_id)
+
+ def get_sector(self, id: str) -> Sector:
+ return self.sectors[id]
+
+ def update_sector(self, objective_id: str, *, name: str, round_id: str, major_id: str, minor_id: str, influence_id: str):
+ obj = self.get_objective(objective_id)
+ obj.set_name(name)
+
+ def remove_sector(self, sector_id: str):
+ camp = self.get_campaign_by_sector(sector_id)
+ camp.remove_sector(sector_id)
+
+# Campaign participant methods
+
+ def get_available_war_participants(self, campaign_id: str) -> list[WarParticipant]:
+ camp = self.get_campaign(campaign_id)
+ return [
+ part
+ for part in self.participants.values()
+ if not camp.has_participant(part.id)
+ ]
+
+ def add_campaign_participant(self, campaign_id: str, player_id: str, leader: str, theme: str) -> CampaignParticipant:
+ camp = self.get_campaign(campaign_id)
+ return camp.add_campaign_participant(player_id, leader, theme)
+
+ def get_campaign_participant(self, participant_id) -> CampaignParticipant:
+ for camp in self.campaigns.values():
+ for part in camp.participants.values():
+ if part.id == participant_id:
+ return part
+ raise KeyError("Participant not found")
+
+ def update_campaign_participant(self, participant_id: str, *, faction: str):
+ camp = self.get_campaign_by_campaign_participant(participant_id)
+ camp.update_campaign_participant(participant_id, faction=faction)
+
+ def remove_campaign_participant(self, participant_id: str):
+ camp = self.get_campaign_by_campaign_participant(participant_id)
+ camp.remove_campaign_participant(participant_id)
+
class Objective:
def __init__(self, name: str, description: str):
self.id: str = str(uuid4())
diff --git a/src/warchron/view/ui/ui_campaign_dialog.py b/src/warchron/view/ui/ui_campaign_dialog.py
index 8922ddf..1265947 100644
--- a/src/warchron/view/ui/ui_campaign_dialog.py
+++ b/src/warchron/view/ui/ui_campaign_dialog.py
@@ -17,25 +17,27 @@ class Ui_campaignDialog(object):
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(".\\src\\warchron\\view\\ui\\../resources/warchron_logo.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
campaignDialog.setWindowIcon(icon)
- self.buttonBox = QtWidgets.QDialogButtonBox(parent=campaignDialog)
- self.buttonBox.setGeometry(QtCore.QRect(10, 60, 341, 32))
- self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
- self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
- self.buttonBox.setObjectName("buttonBox")
+ self.formLayout = QtWidgets.QFormLayout(campaignDialog)
+ self.formLayout.setObjectName("formLayout")
self.label = QtWidgets.QLabel(parent=campaignDialog)
- self.label.setGeometry(QtCore.QRect(10, 20, 47, 14))
self.label.setObjectName("label")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label)
self.campaignName = QtWidgets.QLineEdit(parent=campaignDialog)
- self.campaignName.setGeometry(QtCore.QRect(60, 20, 113, 20))
self.campaignName.setObjectName("campaignName")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.campaignName)
self.label_2 = QtWidgets.QLabel(parent=campaignDialog)
- self.label_2.setGeometry(QtCore.QRect(10, 50, 47, 14))
self.label_2.setObjectName("label_2")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2)
self.campaignMonth = QtWidgets.QSpinBox(parent=campaignDialog)
- self.campaignMonth.setGeometry(QtCore.QRect(60, 50, 71, 22))
self.campaignMonth.setMinimum(1)
self.campaignMonth.setMaximum(12)
self.campaignMonth.setObjectName("campaignMonth")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.campaignMonth)
+ self.buttonBox = QtWidgets.QDialogButtonBox(parent=campaignDialog)
+ self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.buttonBox)
self.retranslateUi(campaignDialog)
self.buttonBox.accepted.connect(campaignDialog.accept) # type: ignore
diff --git a/src/warchron/view/ui/ui_campaign_dialog.ui b/src/warchron/view/ui/ui_campaign_dialog.ui
index cbccab3..03e9527 100644
--- a/src/warchron/view/ui/ui_campaign_dialog.ui
+++ b/src/warchron/view/ui/ui_campaign_dialog.ui
@@ -20,74 +20,45 @@
../resources/warchron_logo.png../resources/warchron_logo.png
-
-
-
- 10
- 60
- 341
- 32
-
-
-
- Qt::Horizontal
-
-
- QDialogButtonBox::Cancel|QDialogButtonBox::Ok
-
-
-
-
-
- 10
- 20
- 47
- 14
-
-
-
- Name:
-
-
-
-
-
- 60
- 20
- 113
- 20
-
-
-
-
-
-
- 10
- 50
- 47
- 14
-
-
-
- Month:
-
-
-
-
-
- 60
- 50
- 71
- 22
-
-
-
- 1
-
-
- 12
-
-
+
+ -
+
+
+ Name:
+
+
+
+ -
+
+
+ -
+
+
+ Month:
+
+
+
+ -
+
+
+ 1
+
+
+ 12
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
diff --git a/src/warchron/view/ui/ui_campaign_participant_dialog.py b/src/warchron/view/ui/ui_campaign_participant_dialog.py
new file mode 100644
index 0000000..3252da8
--- /dev/null
+++ b/src/warchron/view/ui/ui_campaign_participant_dialog.py
@@ -0,0 +1,72 @@
+# Form implementation generated from reading ui file '.\src\warchron\view\ui\ui_campaign_participant_dialog.ui'
+#
+# Created by: PyQt6 UI code generator 6.7.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_campaignParticipantDialog(object):
+ def setupUi(self, campaignParticipantDialog):
+ campaignParticipantDialog.setObjectName("campaignParticipantDialog")
+ campaignParticipantDialog.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
+ campaignParticipantDialog.resize(394, 124)
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(".\\src\\warchron\\view\\ui\\../resources/warchron_logo.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
+ campaignParticipantDialog.setWindowIcon(icon)
+ self.formLayout = QtWidgets.QFormLayout(campaignParticipantDialog)
+ self.formLayout.setObjectName("formLayout")
+ self.label = QtWidgets.QLabel(parent=campaignParticipantDialog)
+ self.label.setObjectName("label")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label)
+ self.playerComboBox = QtWidgets.QComboBox(parent=campaignParticipantDialog)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.playerComboBox.sizePolicy().hasHeightForWidth())
+ self.playerComboBox.setSizePolicy(sizePolicy)
+ self.playerComboBox.setObjectName("playerComboBox")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.playerComboBox)
+ self.label_2 = QtWidgets.QLabel(parent=campaignParticipantDialog)
+ self.label_2.setObjectName("label_2")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2)
+ self.leader = QtWidgets.QLineEdit(parent=campaignParticipantDialog)
+ self.leader.setObjectName("leader")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.leader)
+ self.label_3 = QtWidgets.QLabel(parent=campaignParticipantDialog)
+ self.label_3.setObjectName("label_3")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_3)
+ self.theme = QtWidgets.QLineEdit(parent=campaignParticipantDialog)
+ self.theme.setText("")
+ self.theme.setObjectName("theme")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.FieldRole, self.theme)
+ self.buttonBox = QtWidgets.QDialogButtonBox(parent=campaignParticipantDialog)
+ self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.formLayout.setWidget(3, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.buttonBox)
+
+ self.retranslateUi(campaignParticipantDialog)
+ self.buttonBox.accepted.connect(campaignParticipantDialog.accept) # type: ignore
+ self.buttonBox.rejected.connect(campaignParticipantDialog.reject) # type: ignore
+ QtCore.QMetaObject.connectSlotsByName(campaignParticipantDialog)
+
+ def retranslateUi(self, campaignParticipantDialog):
+ _translate = QtCore.QCoreApplication.translate
+ campaignParticipantDialog.setWindowTitle(_translate("campaignParticipantDialog", "Campaign participant"))
+ self.label.setText(_translate("campaignParticipantDialog", "Player"))
+ self.label_2.setText(_translate("campaignParticipantDialog", "Leader"))
+ self.label_3.setText(_translate("campaignParticipantDialog", "Theme"))
+
+
+if __name__ == "__main__":
+ import sys
+ app = QtWidgets.QApplication(sys.argv)
+ campaignParticipantDialog = QtWidgets.QDialog()
+ ui = Ui_campaignParticipantDialog()
+ ui.setupUi(campaignParticipantDialog)
+ campaignParticipantDialog.show()
+ sys.exit(app.exec())
diff --git a/src/warchron/view/ui/ui_campaign_participant_dialog.ui b/src/warchron/view/ui/ui_campaign_participant_dialog.ui
new file mode 100644
index 0000000..c17e80a
--- /dev/null
+++ b/src/warchron/view/ui/ui_campaign_participant_dialog.ui
@@ -0,0 +1,112 @@
+
+
+ campaignParticipantDialog
+
+
+ Qt::ApplicationModal
+
+
+
+ 0
+ 0
+ 394
+ 124
+
+
+
+ Campaign participant
+
+
+
+ ../resources/warchron_logo.png../resources/warchron_logo.png
+
+
+ -
+
+
+ Player
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Leader
+
+
+
+ -
+
+
+ -
+
+
+ Theme
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ campaignParticipantDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ campaignParticipantDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/warchron/view/ui/ui_main_window.py b/src/warchron/view/ui/ui_main_window.py
index 5bfbf54..8da8938 100644
--- a/src/warchron/view/ui/ui_main_window.py
+++ b/src/warchron/view/ui/ui_main_window.py
@@ -147,12 +147,12 @@ class Ui_MainWindow(object):
self.campaignMonth.setFont(font)
self.campaignMonth.setObjectName("campaignMonth")
self.labelParticipants_2 = QtWidgets.QLabel(parent=self.pageCampaign)
- self.labelParticipants_2.setGeometry(QtCore.QRect(10, 180, 47, 13))
+ self.labelParticipants_2.setGeometry(QtCore.QRect(10, 180, 61, 16))
self.labelParticipants_2.setObjectName("labelParticipants_2")
self.campaignParticipantsTable = QtWidgets.QTableWidget(parent=self.pageCampaign)
self.campaignParticipantsTable.setGeometry(QtCore.QRect(10, 200, 401, 181))
self.campaignParticipantsTable.setObjectName("campaignParticipantsTable")
- self.campaignParticipantsTable.setColumnCount(4)
+ self.campaignParticipantsTable.setColumnCount(5)
self.campaignParticipantsTable.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.campaignParticipantsTable.setHorizontalHeaderItem(0, item)
@@ -162,6 +162,8 @@ class Ui_MainWindow(object):
self.campaignParticipantsTable.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.campaignParticipantsTable.setHorizontalHeaderItem(3, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.campaignParticipantsTable.setHorizontalHeaderItem(4, item)
self.sectorsTable = QtWidgets.QTableWidget(parent=self.pageCampaign)
self.sectorsTable.setGeometry(QtCore.QRect(10, 60, 401, 101))
self.sectorsTable.setObjectName("sectorsTable")
@@ -315,7 +317,7 @@ class Ui_MainWindow(object):
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(1)
- self.selectedDetailsStack.setCurrentIndex(0)
+ self.selectedDetailsStack.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
@@ -366,8 +368,10 @@ class Ui_MainWindow(object):
item = self.campaignParticipantsTable.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Leader"))
item = self.campaignParticipantsTable.horizontalHeaderItem(2)
- item.setText(_translate("MainWindow", "Victory pts."))
+ item.setText(_translate("MainWindow", "Theme"))
item = self.campaignParticipantsTable.horizontalHeaderItem(3)
+ item.setText(_translate("MainWindow", "Victory pts."))
+ item = self.campaignParticipantsTable.horizontalHeaderItem(4)
item.setText(_translate("MainWindow", "Theme pts."))
item = self.sectorsTable.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "Name"))
diff --git a/src/warchron/view/ui/ui_main_window.ui b/src/warchron/view/ui/ui_main_window.ui
index 2cb8313..ab0cc4f 100644
--- a/src/warchron/view/ui/ui_main_window.ui
+++ b/src/warchron/view/ui/ui_main_window.ui
@@ -6,8 +6,8 @@
0
0
- 800
- 600
+ 914
+ 527
@@ -18,663 +18,671 @@
../resources/warchron_logo.png../resources/warchron_logo.png
-
-
-
- 16
- 9
- 771
- 531
-
-
-
- 1
-
-
-
-
- ../resources/users.png../resources/users.png
-
-
- Players
-
-
-
-
- 10
- 60
- 741
- 431
-
-
-
-
- Name
-
-
-
-
- Wars
-
-
-
-
- Wins
-
-
-
-
- Rewards
-
-
-
-
-
-
- 20
- 20
- 75
- 23
-
-
-
- Add player
-
-
-
-
-
-
- ../resources/swords-small.png../resources/swords-small.png
-
-
- Wars
-
-
-
-
- 10
- 60
- 211
- 431
-
-
-
-
-
-
-
-
-
-
-
- 20
- 20
- 75
- 23
-
-
-
- Add war
-
-
-
-
- false
-
-
-
- 110
- 20
- 91
- 23
-
-
-
- Add Campaign
-
-
-
-
- false
-
-
-
- 220
- 20
- 91
- 23
-
-
-
- Add Round
-
-
-
-
-
- 239
- 59
- 511
- 431
-
-
+
+ -
+
0
-
-
-
-
- 110
- 30
- 301
- 51
-
-
-
- Select an element within the tree to show/edit details.
-
-
+
+
+
+ ../resources/users.png../resources/users.png
+
+
+ Players
+
+
+
-
+
+
-
+
+
+ Add player
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+
+ Name
+
+
+
+
+ Wars
+
+
+
+
+ Wins
+
+
+
+
+ Rewards
+
+
+
+
+
-
-
-
-
- 10
- 10
- 241
- 16
-
-
-
-
- 12
-
-
-
- warName
-
-
-
-
-
- 280
- 10
- 71
- 16
-
-
-
-
- 12
-
-
-
- warYear
-
-
-
-
-
- 10
- 150
- 111
- 16
-
-
-
- Participants
-
-
-
-
-
- 420
- 270
- 81
- 23
-
-
-
- Add participant
-
-
-
-
-
- 10
- 170
- 401
- 211
-
-
-
-
- Name
-
-
-
-
- Faction
-
-
-
-
- Campaigns
-
-
-
-
- Victory pts.
-
-
-
-
- Theme pts
-
-
-
-
-
- true
-
-
-
- 230
- 400
- 61
- 23
-
-
-
- End war
-
-
-
+
+
+
+ ../resources/swords-small.png../resources/swords-small.png
+
+
+ Wars
+
+
10
60
- 401
- 71
+ 211
+ 431
- Name
-
-
-
-
- Description
+
-
+
- 10
- 40
- 111
- 20
-
-
-
- Objectives
-
-
-
-
- true
-
-
-
- 420
- 80
- 91
- 23
-
-
-
-
- 10
-
-
-
- Add objective
-
-
-
-
-
-
-
- 10
- 10
- 241
- 16
-
-
-
-
- 12
-
-
-
- campaignName
-
-
-
-
-
- 10
- 40
- 91
- 16
-
-
-
- Sectors
-
-
-
-
-
- 420
- 270
+ 20
+ 20
75
23
- Add participant
+ Add war
-
-
-
- 280
- 10
- 121
- 16
-
-
-
-
- 12
-
-
-
- campaignMonth
-
-
-
-
-
- 10
- 180
- 47
- 13
-
-
-
- Participants
-
-
-
-
-
- 10
- 200
- 401
- 181
-
-
-
-
- Name
-
-
-
-
- Leader
-
-
-
-
- Victory pts.
-
-
-
-
- Theme pts.
-
-
-
-
-
-
- 10
- 60
- 401
- 101
-
-
-
-
- Name
-
-
-
-
- Round
-
-
-
-
- Major obj.
-
-
-
-
- Minor opp.
-
-
-
-
- Influence imp.
-
-
-
-
+
- true
+ false
- 420
- 110
- 71
- 23
-
-
-
- Add Sector
-
-
-
-
- true
-
-
-
- 210
- 400
+ 110
+ 20
91
23
- End campaign
+ Add Campaign
-
-
-
-
-
- 10
- 40
- 91
- 16
-
-
-
- Choices
-
-
-
-
-
- 10
- 60
- 301
- 141
-
-
-
-
- Player
-
-
-
-
- Prioritary
-
-
-
-
- Secondary
-
-
-
-
-
-
- 10
- 10
- 241
- 16
-
-
-
-
- 12
-
-
-
- Round Nb
-
-
-
+
- true
-
-
-
- 320
- 110
- 91
- 23
-
-
-
- Resolve pairing
-
-
-
-
-
- 10
- 240
- 301
- 111
-
-
-
-
- Sector
-
-
-
-
- Player 1
-
-
-
-
- Player 2
-
-
-
-
-
- true
-
-
-
- 320
- 290
- 91
- 23
-
-
-
- Enter results
-
-
-
-
- true
+ false
220
- 400
- 71
+ 20
+ 91
23
- End round
+ Add Round
-
+
- 10
- 220
- 91
- 16
+ 239
+ 59
+ 511
+ 431
-
- Battles
+
+ 2
+
+
+
+
+ 110
+ 30
+ 301
+ 51
+
+
+
+ Select an element within the tree to show/edit details.
+
+
+
+
+
+
+
+ 10
+ 10
+ 241
+ 16
+
+
+
+
+ 12
+
+
+
+ warName
+
+
+
+
+
+ 280
+ 10
+ 71
+ 16
+
+
+
+
+ 12
+
+
+
+ warYear
+
+
+
+
+
+ 10
+ 150
+ 111
+ 16
+
+
+
+ Participants
+
+
+
+
+
+ 420
+ 270
+ 81
+ 23
+
+
+
+ Add participant
+
+
+
+
+
+ 10
+ 170
+ 401
+ 211
+
+
+
+
+ Name
+
+
+
+
+ Faction
+
+
+
+
+ Campaigns
+
+
+
+
+ Victory pts.
+
+
+
+
+ Theme pts
+
+
+
+
+
+ true
+
+
+
+ 230
+ 400
+ 61
+ 23
+
+
+
+ End war
+
+
+
+
+
+ 10
+ 60
+ 401
+ 71
+
+
+
+
+ Name
+
+
+
+
+ Description
+
+
+
+
+
+
+ 10
+ 40
+ 111
+ 20
+
+
+
+ Objectives
+
+
+
+
+ true
+
+
+
+ 420
+ 80
+ 91
+ 23
+
+
+
+
+ 10
+
+
+
+ Add objective
+
+
+
+
+
+
+
+ 10
+ 10
+ 241
+ 16
+
+
+
+
+ 12
+
+
+
+ campaignName
+
+
+
+
+
+ 10
+ 40
+ 91
+ 16
+
+
+
+ Sectors
+
+
+
+
+
+ 420
+ 270
+ 75
+ 23
+
+
+
+ Add participant
+
+
+
+
+
+ 280
+ 10
+ 121
+ 16
+
+
+
+
+ 12
+
+
+
+ campaignMonth
+
+
+
+
+
+ 10
+ 180
+ 61
+ 16
+
+
+
+ Participants
+
+
+
+
+
+ 10
+ 200
+ 401
+ 181
+
+
+
+
+ Name
+
+
+
+
+ Leader
+
+
+
+
+ Theme
+
+
+
+
+ Victory pts.
+
+
+
+
+ Theme pts.
+
+
+
+
+
+
+ 10
+ 60
+ 401
+ 101
+
+
+
+
+ Name
+
+
+
+
+ Round
+
+
+
+
+ Major obj.
+
+
+
+
+ Minor opp.
+
+
+
+
+ Influence imp.
+
+
+
+
+
+ true
+
+
+
+ 420
+ 110
+ 71
+ 23
+
+
+
+ Add Sector
+
+
+
+
+ true
+
+
+
+ 210
+ 400
+ 91
+ 23
+
+
+
+ End campaign
+
+
+
+
+
+
+
+ 10
+ 40
+ 91
+ 16
+
+
+
+ Choices
+
+
+
+
+
+ 10
+ 60
+ 301
+ 141
+
+
+
+
+ Player
+
+
+
+
+ Prioritary
+
+
+
+
+ Secondary
+
+
+
+
+
+
+ 10
+ 10
+ 241
+ 16
+
+
+
+
+ 12
+
+
+
+ Round Nb
+
+
+
+
+ true
+
+
+
+ 320
+ 110
+ 91
+ 23
+
+
+
+ Resolve pairing
+
+
+
+
+
+ 10
+ 240
+ 301
+ 111
+
+
+
+
+ Sector
+
+
+
+
+ Player 1
+
+
+
+
+ Player 2
+
+
+
+
+
+ true
+
+
+
+ 320
+ 290
+ 91
+ 23
+
+
+
+ Enter results
+
+
+
+
+ true
+
+
+
+ 220
+ 400
+ 71
+ 23
+
+
+
+ End round
+
+
+
+
+
+ 10
+ 220
+ 91
+ 16
+
+
+
+ Battles
+
+
+
-
-
+
+
diff --git a/src/warchron/view/ui/ui_war_participant_dialog.py b/src/warchron/view/ui/ui_war_participant_dialog.py
new file mode 100644
index 0000000..fe29eb4
--- /dev/null
+++ b/src/warchron/view/ui/ui_war_participant_dialog.py
@@ -0,0 +1,64 @@
+# Form implementation generated from reading ui file '.\src\warchron\view\ui\ui_war_participant_dialog.ui'
+#
+# Created by: PyQt6 UI code generator 6.7.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_warParticipantDialog(object):
+ def setupUi(self, warParticipantDialog):
+ warParticipantDialog.setObjectName("warParticipantDialog")
+ warParticipantDialog.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
+ warParticipantDialog.resize(394, 96)
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(".\\src\\warchron\\view\\ui\\../resources/warchron_logo.png"), QtGui.QIcon.Mode.Normal, QtGui.QIcon.State.Off)
+ warParticipantDialog.setWindowIcon(icon)
+ self.formLayout = QtWidgets.QFormLayout(warParticipantDialog)
+ self.formLayout.setObjectName("formLayout")
+ self.label = QtWidgets.QLabel(parent=warParticipantDialog)
+ self.label.setObjectName("label")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label)
+ self.playerComboBox = QtWidgets.QComboBox(parent=warParticipantDialog)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.playerComboBox.sizePolicy().hasHeightForWidth())
+ self.playerComboBox.setSizePolicy(sizePolicy)
+ self.playerComboBox.setObjectName("playerComboBox")
+ self.formLayout.setWidget(0, QtWidgets.QFormLayout.ItemRole.FieldRole, self.playerComboBox)
+ self.label_2 = QtWidgets.QLabel(parent=warParticipantDialog)
+ self.label_2.setObjectName("label_2")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.LabelRole, self.label_2)
+ self.faction = QtWidgets.QLineEdit(parent=warParticipantDialog)
+ self.faction.setObjectName("faction")
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.ItemRole.FieldRole, self.faction)
+ self.buttonBox = QtWidgets.QDialogButtonBox(parent=warParticipantDialog)
+ self.buttonBox.setOrientation(QtCore.Qt.Orientation.Horizontal)
+ self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.StandardButton.Cancel|QtWidgets.QDialogButtonBox.StandardButton.Ok)
+ self.buttonBox.setObjectName("buttonBox")
+ self.formLayout.setWidget(2, QtWidgets.QFormLayout.ItemRole.SpanningRole, self.buttonBox)
+
+ self.retranslateUi(warParticipantDialog)
+ self.buttonBox.accepted.connect(warParticipantDialog.accept) # type: ignore
+ self.buttonBox.rejected.connect(warParticipantDialog.reject) # type: ignore
+ QtCore.QMetaObject.connectSlotsByName(warParticipantDialog)
+
+ def retranslateUi(self, warParticipantDialog):
+ _translate = QtCore.QCoreApplication.translate
+ warParticipantDialog.setWindowTitle(_translate("warParticipantDialog", "War participant"))
+ self.label.setText(_translate("warParticipantDialog", "Player"))
+ self.label_2.setText(_translate("warParticipantDialog", "Faction"))
+
+
+if __name__ == "__main__":
+ import sys
+ app = QtWidgets.QApplication(sys.argv)
+ warParticipantDialog = QtWidgets.QDialog()
+ ui = Ui_warParticipantDialog()
+ ui.setupUi(warParticipantDialog)
+ warParticipantDialog.show()
+ sys.exit(app.exec())
diff --git a/src/warchron/view/ui/ui_participant_dialog.ui b/src/warchron/view/ui/ui_war_participant_dialog.ui
similarity index 88%
rename from src/warchron/view/ui/ui_participant_dialog.ui
rename to src/warchron/view/ui/ui_war_participant_dialog.ui
index 238ea5e..c5199af 100644
--- a/src/warchron/view/ui/ui_participant_dialog.ui
+++ b/src/warchron/view/ui/ui_war_participant_dialog.ui
@@ -1,7 +1,7 @@
- participantDialog
-
+ warParticipantDialog
+
Qt::ApplicationModal
@@ -10,17 +10,17 @@
0
0
394
- 148
+ 96
- Participant
+ War participant
../resources/warchron_logo.png../resources/warchron_logo.png
-
+
-
@@ -65,7 +65,7 @@
buttonBox
accepted()
- participantDialog
+ warParticipantDialog
accept()
@@ -81,7 +81,7 @@
buttonBox
rejected()
- participantDialog
+ warParticipantDialog
reject()
diff --git a/src/warchron/view/view.py b/src/warchron/view/view.py
index b5932e8..67b5708 100644
--- a/src/warchron/view/view.py
+++ b/src/warchron/view/view.py
@@ -12,7 +12,30 @@ from warchron.view.ui.ui_player_dialog import Ui_playerDialog
from warchron.view.ui.ui_war_dialog import Ui_warDialog
from warchron.view.ui.ui_campaign_dialog import Ui_campaignDialog
from warchron.view.ui.ui_objective_dialog import Ui_objectiveDialog
-from warchron.view.ui.ui_participant_dialog import Ui_participantDialog
+from warchron.view.ui.ui_war_participant_dialog import Ui_warParticipantDialog
+from warchron.view.ui.ui_campaign_participant_dialog import Ui_campaignParticipantDialog
+from warchron.view.ui.ui_sector_dialog import Ui_sectorDialog
+from warchron.controller.dtos import ParticipantOption
+
+# utils...
+
+def select_if_exists(combo, value):
+ if value is None:
+ return
+ idx = combo.findData(value)
+ if idx != -1:
+ combo.setCurrentIndex(idx)
+
+def format_war_label(war) -> str:
+ return f"{war.name} ({war.year})"
+
+def format_campaign_label(camp) -> str:
+ return f"{camp.name} ({calendar.month_name[camp.month]})"
+
+def format_round_label(round, index: int) -> str:
+ if index is None:
+ return ""
+ return f"Round {index}"
class View(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
@@ -31,6 +54,10 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
self.warParticipantsTable.customContextMenuRequested.connect(self._on_war_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.customContextMenuRequested.connect(self._on_sectors_table_context_menu)
self.warsTree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.warsTree.customContextMenuRequested.connect(self._on_wars_tree_context_menu)
self.addCampaignBtn.clicked.connect(self._on_add_campaign_clicked)
@@ -147,32 +174,23 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
if self.on_delete_item:
self.on_delete_item(item_type, item_id)
- def _format_war_label(self, war) -> str:
- return f"{war.name} ({war.year})"
-
- def _format_campaign_label(self, camp) -> str:
- return f"{camp.name} ({calendar.month_name[camp.month]})"
-
- def _format_round_label(self, round, index: int) -> str:
- return f"Round {index}"
-
def display_wars_tree(self, wars: list):
tree = self.warsTree
tree.clear()
tree.setColumnCount(1)
tree.setHeaderLabels(["Wars"])
for war in wars:
- war_item = QTreeWidgetItem([self._format_war_label(war)])
+ war_item = QTreeWidgetItem([format_war_label(war)])
war_item.setData(0, ROLE_TYPE, ItemType.WAR)
war_item.setData(0, ROLE_ID, war.id)
tree.addTopLevelItem(war_item)
for camp in war.get_all_campaigns():
- camp_item = QTreeWidgetItem([self._format_campaign_label(camp)])
+ camp_item = QTreeWidgetItem([format_campaign_label(camp)])
camp_item.setData(0, ROLE_TYPE, ItemType.CAMPAIGN)
camp_item.setData(0, ROLE_ID, camp.id)
war_item.addChild(camp_item)
for index, rnd in enumerate(camp.get_all_rounds(), start=1):
- rnd_item = QTreeWidgetItem([self._format_round_label(rnd, index)])
+ rnd_item = QTreeWidgetItem([format_round_label(rnd, index)])
rnd_item.setData(0, ROLE_TYPE, ItemType.ROUND)
rnd_item.setData(0, ROLE_ID, rnd.id)
camp_item.addChild(rnd_item)
@@ -282,10 +300,78 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
# Campaign page
+ def _on_sectors_table_context_menu(self, pos):
+ item = self.sectorsTable.itemAt(pos)
+ if not item:
+ return
+ row = item.row()
+ name_item = self.sectorsTable.item(row, 0)
+ if not name_item:
+ return
+ sector_id = name_item.data(Qt.ItemDataRole.UserRole)
+ menu = QMenu(self)
+ edit_action = menu.addAction("Edit")
+ delete_action = menu.addAction("Delete")
+ action = menu.exec(self.sectorsTable.viewport().mapToGlobal(pos))
+ if action == edit_action and self.on_edit_item:
+ self.on_edit_item(ItemType.SECTOR, sector_id)
+ elif action == delete_action and self.on_delete_item:
+ self.on_delete_item(ItemType.SECTOR, sector_id)
+
+ def _on_campaign_participants_table_context_menu(self, pos):
+ item = self.campaignParticipantsTable.itemAt(pos)
+ if not item:
+ return
+ row = item.row()
+ name_item = self.campaignParticipantsTable.item(row, 0)
+ if not name_item:
+ return
+ participant_id = name_item.data(Qt.ItemDataRole.UserRole)
+ menu = QMenu(self)
+ edit_action = menu.addAction("Edit")
+ delete_action = menu.addAction("Delete")
+ action = menu.exec(self.campaignParticipantsTable.viewport().mapToGlobal(pos))
+ if action == edit_action and self.on_edit_item:
+ self.on_edit_item(ItemType.CAMPAIGN_PARTICIPANT, participant_id)
+ elif action == delete_action and self.on_delete_item:
+ self.on_delete_item(ItemType.CAMPAIGN_PARTICIPANT, participant_id)
+
def show_campaign_details(self, *, name: str, month: int):
self.campaignName.setText(name)
self.campaignMonth.setText(calendar.month_name[month])
+ def display_campaign_sectors(self, sectors: list[tuple[str, str, str, str, str, str]]):
+ table = self.sectorsTable
+ table.clearContents()
+ table.setRowCount(len(sectors))
+ for row, (name, round_index, major, minor, influence, pid) in enumerate(sectors):
+ name_item = QtWidgets.QTableWidgetItem(name)
+ round_item = QtWidgets.QTableWidgetItem(format_round_label(None, round_index))
+ major_item = QtWidgets.QTableWidgetItem(major)
+ minor_item = QtWidgets.QTableWidgetItem(minor)
+ influence_item = QtWidgets.QTableWidgetItem(influence)
+ name_item.setData(Qt.ItemDataRole.UserRole, pid)
+ table.setItem(row, 0, name_item)
+ table.setItem(row, 1, round_item)
+ table.setItem(row, 2, major_item)
+ table.setItem(row, 3, minor_item)
+ table.setItem(row, 4, influence_item)
+ table.resizeColumnsToContents()
+
+ def display_campaign_participants(self, participants: list[tuple[str, str, str, str]]):
+ table = self.campaignParticipantsTable
+ table.clearContents()
+ table.setRowCount(len(participants))
+ for row, (name, leader, theme, pid) in enumerate(participants):
+ name_item = QtWidgets.QTableWidgetItem(name)
+ lead_item = QtWidgets.QTableWidgetItem(leader)
+ theme_item = QtWidgets.QTableWidgetItem(theme)
+ name_item.setData(Qt.ItemDataRole.UserRole, pid)
+ table.setItem(row, 0, name_item)
+ table.setItem(row, 1, lead_item)
+ table.setItem(row, 2, theme_item)
+ table.resizeColumnsToContents()
+
# Round page
def show_round_details(self, *, index: int):
@@ -346,17 +432,14 @@ class ObjectiveDialog(QDialog):
def get_objective_description(self) -> str:
return self.ui.objectiveDescription.toPlainText().strip()
-class ParticipantDialog(QDialog):
+class WarParticipantDialog(QDialog):
def __init__(self, parent=None, *, players: list, default_player_id=None, default_faction="", editable_player=True):
super().__init__(parent)
- self.ui = Ui_participantDialog()
+ self.ui = Ui_warParticipantDialog()
self.ui.setupUi(self)
for player in players:
self.ui.playerComboBox.addItem(player.name, player.id)
- if default_player_id:
- index = self.ui.playerComboBox.findData(default_player_id)
- if index != -1:
- self.ui.playerComboBox.setCurrentIndex(index)
+ select_if_exists(self.ui.playerComboBox, default_player_id)
self.ui.playerComboBox.setEnabled(editable_player)
self.ui.faction.setText(default_faction)
@@ -364,4 +447,60 @@ class ParticipantDialog(QDialog):
return self.ui.playerComboBox.currentData()
def get_participant_faction(self) -> str:
- return self.ui.faction.text().strip()
\ No newline at end of file
+ return self.ui.faction.text().strip()
+
+class CampaignParticipantDialog(QDialog):
+ def __init__(self, parent=None, *, participants: list[ParticipantOption], default_participant_id=None, default_leader="", default_theme="", editable_player=True):
+ super().__init__(parent)
+ self.ui = Ui_campaignParticipantDialog()
+ self.ui.setupUi(self)
+ for part in participants:
+ self.ui.playerComboBox.addItem(part.name, part.id)
+ select_if_exists(self.ui.playerComboBox, default_participant_id)
+ self.ui.playerComboBox.setEnabled(editable_player)
+ self.ui.leader.setText(default_leader)
+ self.ui.theme.setText(default_theme)
+
+ def get_player_id(self) -> str:
+ return self.ui.playerComboBox.currentData()
+
+ def get_participant_leader(self) -> str:
+ return self.ui.leader.text().strip()
+
+ def get_participant_theme(self) -> str:
+ return self.ui.theme.text().strip()
+
+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):
+ super().__init__(parent)
+ self.ui = Ui_sectorDialog()
+ self.ui.setupUi(self)
+ self.ui.majorComboBox.addItem("(none)", None)
+ self.ui.minorComboBox.addItem("(none)", None)
+ self.ui.influenceComboBox.addItem("(none)", None)
+ self.ui.sectorName.setText(default_name)
+ for index, rnd in enumerate(rounds, start=1):
+ self.ui.roundComboBox.addItem(format_round_label(rnd, index), rnd.id)
+ select_if_exists(self.ui.roundComboBox, default_round_id)
+ for obj in objectives:
+ self.ui.majorComboBox.addItem(obj.name, obj.id)
+ self.ui.minorComboBox.addItem(obj.name, obj.id)
+ self.ui.influenceComboBox.addItem(obj.name, obj.id)
+ select_if_exists(self.ui.majorComboBox, default_major_id)
+ select_if_exists(self.ui.minorComboBox, default_minor_id)
+ select_if_exists(self.ui.influenceComboBox, default_influence_id)
+
+ def get_sector_name(self) -> str:
+ return self.ui.sectorName.text().strip()
+
+ def get_round_id(self) -> str:
+ return self.ui.roundComboBox.currentData()
+
+ def get_major_id(self) -> str:
+ return self.ui.majorComboBox.currentData()
+
+ def get_minor_id(self) -> str:
+ return self.ui.minorComboBox.currentData()
+
+ def get_influence_id(self) -> str:
+ return self.ui.influenceComboBox.currentData()