Skip to content
Snippets Groups Projects
distribution_overview_controller.py 7.36 KiB
Newer Older
  • Learn to ignore specific revisions
  • from timeit import default_timer as timer
    
    from PyQt5 import QtWidgets as Qtw
    from PyQt5.QtCore import pyqtSlot, Qt
    
    from PyQt5.QtGui import QPainter, QPicture
    from PyQt5.QtPrintSupport import QPrintDialog
    from PyQt5.QtWidgets import QDialog, QMenu, QFileDialog
    
    from model.distribution import Distribution
    from model.team import Team
    
    from utils.drag_drop_table_unassigned import DragDropTableUnassigned
    
    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)
    
                table.contextMenuRequested.connect(self.onContextMenuRequested)
    
                self.teamTables.append(table)
                self.gridTeams.addWidget(table, i // 2, i % 2)
    
                -1,
                self.getUnassigned(teams),
    
                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):
    
            dialog = QPrintDialog()
            if dialog.exec_() != QDialog.Accepted:
                return
    
    Jakub Štercl's avatar
    Jakub Štercl committed
            widget = PrintWidget(self.distribution_name, self.teamTables)
    
    
            # first we print into QPicture, that way we can rescale without a big resolution loss
            pic = QPicture()
            print(pic.size())
            pic_painter = QPainter(pic)
            widget.render(pic_painter, flags=widget.DrawChildren)
            pic_painter.end()
            pic.setBoundingRect(widget.rect())
    
            printer = dialog.printer()
            painter = QPainter()
    
            painter.begin(printer)
    
    
            # rescale the picture to page and print
            x_scale = printer.pageRect().width() / pic.width()
            y_scale = printer.pageRect().height() / pic.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(-pic.width() / 2, -pic.height() / 2)
            painter.drawPicture(0, 0, pic)
    
            painter.end()
    
    
        @pyqtSlot()
        def exportToFile(self):
            file, options = QFileDialog.getSaveFileName(self, self.tr("Exportovat do"))
            if file == '':
                return
            with open(file, 'w') as f:
                f.write(self.distribution_name + '\n')
                for table in self.teamTables:
                    team = table.getAllData()
                    f.write(table.name + ': ')
                    for member in team:
                        f.write(member.name + ', ')
                    f.write('\n')
    
    
        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)