Skip to content
Snippets Groups Projects
distribution_overview_controller.py 6.52 KiB
Newer Older
from timeit import default_timer as timer
from PyQt5 import QtWidgets as Qtw
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtGui import QPainter
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog
from PyQt5.QtWidgets import QDialog, QMenu
from model.distribution import Distribution
from model.team import Team
Jakub Štercl's avatar
Jakub Štercl committed
from utils.editable_title_widget import EditableTitle
from utils.members_drag_drop_table import MembersDragDropTable
from utils.print_widget import PrintWidget
from windows import distribution_overview


class DistributionOverview(Qtw.QWidget, distribution_overview.Ui_Form):
    def __init__(self, main_window, teams, group, parent=None):
        super(DistributionOverview, self).__init__(parent)
        self.setupUi(self)
        self.main_window = main_window
        self.group = group
        self.teamTables = []
        for i, team_name in enumerate(teams):
            table = MembersDragDropTable(i, teams[team_name], team_name, self)
            table.model.sourceModel().droppedMemberFrom.connect(self.removeMember)
            table.deleteClicked.connect(self.removeTeam)
            # connecting the signal of the actual table, not the whole widget (I don't think it's worth it to wrap this)
            table.contextMenuRequested.connect(self.onContextMenuRequested)
            self.teamTables.append(table)
            self.gridTeams.addWidget(table, i // 2, i % 2)

        self.tableOthers = MembersDragDropTable(
            -1,
            self.getUnassigned(teams),
            self.tr("nezařazeni"),
            self
        )
        self.tableOthers.model.sourceModel().droppedMemberFrom.connect(self.removeMember)
        self.tableOthers.contextMenuRequested.connect(self.onContextMenuRequested)
        self.gridTeams.addWidget(self.tableOthers, len(self.teamTables) // 2, len(self.teamTables) % 2)

Jakub Štercl's avatar
Jakub Štercl committed
        self.distribution_name = self.tr("Nepojmenované rozdělení")
Jakub Štercl's avatar
Jakub Štercl committed
        title = EditableTitle(self.distribution_name)
        self.layoutName.replaceWidget(self.titleWidget, title)
        self.titleWidget = title
    
        # signals
        self.btnAddTeam.clicked.connect(self.addTeam)
        self.btnSave.clicked.connect(self.save)
        self.btnPrint.clicked.connect(self.printDistribution)
Jakub Štercl's avatar
Jakub Štercl committed
        self.titleWidget.textConfirmed.connect(self.changeDistName)

    def getUnassigned(self, teams):
        """
        :param teams: teams in distribution (dict) 
        :return: list of unassigned members from group
        """
        res = []
        for member in self.group.members:
            for team in teams.values():
                if member in team:
                    break
            else:
                res.append(member)
        return res

Jakub Štercl's avatar
Jakub Štercl committed
    @pyqtSlot(str)
    def changeDistName(self, name):
        self.distribution_name = name
        
    @pyqtSlot()
    def addTeam(self):
        table_id = len(self.teamTables)
        table = MembersDragDropTable(table_id, [], "Tým " + str(table_id + 1), self)
        table.model.sourceModel().droppedMemberFrom.connect(self.removeMember)
        table.deleteClicked.connect(self.removeTeam)
        self.teamTables.append(table)
        self.gridTeams.replaceWidget(self.tableOthers, table)
        self.gridTeams.addWidget(self.tableOthers, len(self.teamTables) // 2, len(self.teamTables) % 2 )

    @pyqtSlot(int, int)
    def removeMember(self, member_id, table_id):
        if table_id == -1:
            self.tableOthers.removeMember(member_id)
        else:
            self.teamTables[table_id].removeMember(member_id)

    @pyqtSlot(int)
    def removeTeam(self, table_id):
        if self.teamTables[table_id].isEmpty():
            self.teamTables[table_id].hide()
            self.gridTeams.replaceWidget(self.teamTables[len(self.teamTables) - 1],self.tableOthers)
            for i in range(len(self.teamTables) - 1, table_id, -1):
                self.gridTeams.replaceWidget(self.teamTables[i-1], self.teamTables[i])
                self.teamTables[i].id_ -= 1
            self.teamTables.pop(table_id)
        else:
            msg = Qt.QMessageBox(self)
            msg.setIcon(Qt.QMessageBox.Critical)
            msg.setWindowTitle("Chyba")
            msg.setText("Nelze smazat neprázdný tým!")
            msg.setStandardButtons(Qt.QMessageBox.Ok)
            msg.exec_()

    @pyqtSlot()
    def save(self):
        teams = []
        for table in self.teamTables:
            team = Team(table.id_, table.name, table.getAllData())
            teams.append(team)
Jakub Štercl's avatar
Jakub Štercl committed
        distribution = Distribution(self.distribution_name, teams, self.group.id_)
        start = timer()
        distribution.saveToDb()
        print('total time:', timer() - start)
        self.main_window.reset()

    @pyqtSlot()
    def printDistribution(self):
        printer = QPrinter(QPrinter.HighResolution)
        dialog = QPrintDialog()
        if dialog.exec_() != QDialog.Accepted:
            return
        painter = QPainter()
Jakub Štercl's avatar
Jakub Štercl committed
        widget = PrintWidget(self.distribution_name, self.teamTables)
        widget_height =  widget.sizeHint().height()
        widget_width = widget.width()
        painter.begin(printer)
        x_scale = printer.pageRect().width() / widget_width
        y_scale = printer.pageRect().height() / widget_height
        scale = min([x_scale, y_scale])
        painter.translate(printer.paperRect().x() + printer.pageRect().width() / 2,
                          printer.paperRect().y() + printer.pageRect().height() / 2)
        painter.scale(scale, scale)
        painter.translate(-widget_width / 2, -widget_height / 2)

        widget.render(painter)
        painter.end()

    def onContextMenuRequested(self, member, from_table_id, point):
        """
        construct and display context menu allowing to move members from a team to different one
        :param member:
        :param from_table_id:
        :param point:
        """
        menu = QMenu(self.sender())
        submenu = menu.addMenu(self.tr("Přesunout do týmu:"))
        for table in self.teamTables:
            if table.id_ != from_table_id:
                submenu.addAction(table.name, lambda i=table.id_: self.moveMember(member, from_table_id, i))

        if from_table_id != -1:
            menu.addSeparator()
            menu.addAction(self.tr("Vyřadit z rozdělení"), lambda: self.moveMember(member, from_table_id, -1))
        menu.exec_(point)

    def moveMember(self, member, from_table_id, to_table_id):
        self.removeMember(member.id_, from_table_id)
        if to_table_id == -1:
            self.tableOthers.insertMember(member)
        else:
            self.teamTables[to_table_id].insertMember(member)