from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtWidgets import QMessageBox, QMenu, QWidget from utils.widgets.members_table import MembersTable from controllers.base_controller import BaseController from model.distribution import Distribution from model.member import Member from utils.database import IntegrityError from utils.globals import Global from utils.qtmodels.distributions_tree_model import DistributionTreeModel from utils.widgets.editable_title_widget import EditableTitle from windows import groupedit class GroupEdit(BaseController, QWidget, groupedit.Ui_Form): def __init__(self, main_window, group, parent=None): """ Cotnroller of group edit window :param main_window: main application window :param group: (Group) group to be displayed :param parent: parent widget for qt """ super(GroupEdit, self).__init__(parent) self.setupUi(self) self.main_window = main_window self.group = group self.membersTable = MembersTable( num_of_buttons=2, button_definitions=({'text':"", 'tooltip':self.tr("Přehled"), 'icon':":/icons/eye.svg"}, {'text':"", 'tooltip':self.tr("Smazat člena"), 'icon':":/icons/minus.svg"},), data=group.members) self.updateMemberCount() self.layoutMembers.insertWidget(0, self.membersTable) self.treeDistributions.setModel(DistributionTreeModel(group.distributions)) title = EditableTitle(group.name, self) self.layoutName.replaceWidget(self.widgetTitle, title) self.widgetTitle = title self.btnExpandAll.clicked.connect(self.onExpandAllClicked) self.expanded = False # signals self.btnDelete.clicked.connect(self.deleteGroup) self.btnAddNew.clicked.connect(self.addNewMember) self.editNewMemberName.returnPressed.connect(self.addNewMember) self.btnDistribute.clicked.connect(self.distribute) self.membersTable.btnClicked.connect(self.onTableMembersBtnClicked) self.membersTable.itemDoubleClicked.connect(self.goToMemberOverview) self.widgetTitle.textConfirmed.connect(self.changeGroupName) self.treeDistributions.expanded.connect(self.expandChildren) self.treeDistributions.customContextMenuRequested.connect(self.onContextMenuRequested) def reloadData(self): """ reload data from database """ self.group = Global.db.getGroupById(self.group.id_) self.membersTable.changeData(self.group.members) self.updateMemberCount() self.treeDistributions.setModel(DistributionTreeModel(self.group.distributions)) @pyqtSlot(str) def changeGroupName(self, name): """ change name of group, if it's not unique, show error message :param name: new group name """ try: self.group.rename(name) except IntegrityError as e: msg = QMessageBox(self) msg.setIcon(QMessageBox.Critical) msg.setText("Skupina s tímto jménem již existuje") msg.setWindowTitle(self.tr("Nelze přejmenovat skupinu")) msg.setStandardButtons(QMessageBox.Ok) msg.exec() self.widgetTitle.editMode() @pyqtSlot() def deleteGroup(self): """ Show confirmation prompt and delete group + go back after """ msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setWindowTitle(self.tr("Opravdu?")) msg.setText(self.tr("Opravdu chcete smazat skupinu " + self.group.name + "?")) msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) if msg.exec() == QMessageBox.Ok: self.group.delete() self.main_window.dataChanged() self.main_window.goBack() @pyqtSlot() def addNewMember(self): """ Add member specified in self.editNewMemberName, if not unique, show error message """ name = self.editNewMemberName.text().strip() if len(name) == 0: return try: self.group.addMember(name) self.main_window.dataChanged() except IntegrityError as e: msg = QMessageBox(self) msg.setIcon(QMessageBox.Critical) msg.setText(self.tr("Tento člen již v této skupině existuje.")) msg.setWindowTitle(self.tr("Nelze přidat člena")) msg.setStandardButtons(QMessageBox.Ok) msg.exec() finally: # prepare for inserting another one self.editNewMemberName.clear() self.editNewMemberName.setFocus() self.membersTable.changeData(self.group.members) self.updateMemberCount() def updateMemberCount(self): """ update member count label """ self.lblMemberCount.setText(str(self.group.member_count)) @pyqtSlot() def distribute(self): """ go to distribution setup for this group """ self.main_window.goToDistributionSetup(self.group) @pyqtSlot(Member, int) def onTableMembersBtnClicked(self, member, btn_nr): """ Slot for buttons from tableMembers :param member: :param btn_nr: """ if btn_nr == 0: self.goToMemberOverview(member) elif btn_nr == 1: self.deleteMember(member) def goToMemberOverview(self, member): """ go to member overview :param member: """ self.main_window.goToMemberOverview(member) def deleteMember(self, member): """ delete member :param member: """ msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setWindowTitle(self.tr("Opravdu?")) msg.setText(self.tr("Opravdu chcete smazat člena " + member.name + "?")) msg.setInformativeText(self.tr("Člen bude zároveň smazán i ze všech rozdělení, ve kterých byl.")) msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) if msg.exec() == QMessageBox.Ok: member.delete() self.main_window.dataChanged() self.reloadData() def onExpandAllClicked(self): """ expand everything in treeHistory and change button to 'hide all' or if the button already is 'hide all' do the opposite """ if self.expanded: self.treeDistributions.collapseAll() self.btnExpandAll.setText(self.tr("Rozbalit vše")) else: self.treeDistributions.expandAll() self.btnExpandAll.setText(self.tr("Sbalit vše")) self.expanded = not self.expanded def expandChildren(self, index): """ expand all children of given index in self.treeDistribution :param index: """ for i in range(index.model().rowCount(index)): child = index.model().index(i, 0, index) self.treeDistributions.expand(child) def onContextMenuRequested(self, point): """ construct context menu (only if clicked on distribution) :param point: """ element = self.treeDistributions.model().data(self.treeDistributions.indexAt(point), Qt.UserRole) if not isinstance(element, Distribution): return menu = QMenu(self.treeDistributions) menu.addAction(self.tr("Upravit"), lambda: self.goToDistributionEdit(element)) menu.addAction(self.tr("Duplikovat"), lambda: self.duplicate(element)) menu.exec_(self.treeDistributions.mapToGlobal(point)) def goToDistributionEdit(self, distribution): """ go to distribution edit window :param distribution: """ self.main_window.goToDistributionEdit(distribution, self.group) def duplicate(self, distribution): """ duplicate distribution and go to it's overview :param distribution: """ self.main_window.goToDistributionOverview( {team.name: team.members for team in distribution.teams}, self.group, distribution.name )