def on_edit_config(self) -> None: """ Displays the edition dialog for application settings """ dlg = SettingsEditionDialog() if dlg.exec_(): if dlg.restore_default(): AssetManager.getInstance().restore_default_settings() else: AssetManager.getInstance().save_config(dlg.new_config()) self.status_bar.showMessage(tr("acknowledge_changes"), 3000) self.repaint() if dlg.need_restart(): restart_confirm = VConfirmDialog(self, "need_restart") restart_confirm.ok_btn.setText(tr("restart_now")) restart_confirm.ok_btn.setFixedSize(QSize(105, 33)) restart_confirm.cancel_btn.setText(tr("restart_later")) restart_confirm.cancel_btn.setFixedSize(QSize(105, 33)) if restart_confirm.exec_(): self.reboot_requested = True self.close() self.restart()
def do_shuffle(self): if not VConfirmDialog(self.parent(), "confirm_message_shuffle").exec_(): return self.sig_enable_animation_btns.emit(False) self.sig_shuffle.emit()
def lot_change(self): list_id_attr = self.gui.sidewidget.attributes().selected_attributes() if len(list_id_attr) == 1: # Only one attribute is selected, we change it id_topic = self.mod_bdd.get_topic_id_by_course_id( self.main_ctrl.id_course) students_in_course = self.mod_bdd.get_students_in_course_by_id( self.main_ctrl.id_course) if self.main_ctrl.filter_selection: # get desk selection desks_id = self.v_canvas.get_selected_tiles() id_students_selected = [ self.mod_bdd.get_desk_by_id(d).id_student for d in desks_id ] students = [(s.id, f"{s.lastname} {s.firstname}") for s in students_in_course if s.id in id_students_selected] else: students = [(s.id, f"{s.lastname} {s.firstname}") for s in students_in_course] attr_id = list_id_attr[0] attr_type = self.mod_bdd.get_attribute_type_from_id(attr_id) dlg = None # QDialog if attr_type == EAttributesTypes.TEXT.value: dlg = VDlgEditText(self.gui, "") elif attr_type == EAttributesTypes.MARK.value: dlg = VDlgEditMark(self.gui, "") elif attr_type == EAttributesTypes.COLOR.value: dlg = VDlgEditColor(self.gui, "") elif attr_type == EAttributesTypes.COUNTER.value: dlg = VDlgEditCounter(self.gui, "1") if dlg and dlg.exec_(): if attr_type == EAttributesTypes.COUNTER.value: if dlg.new_value() == 0 and not VConfirmDialog( self.gui, "confirm_message_RAZ").exec_(): return for s in students: if dlg.new_value() == 0: val = "0" else: val = self.mod_bdd.get_attribute_value( s[0], attr_id, id_topic) val = str(int(val) + dlg.new_value()) if val else str( dlg.new_value()) self.mod_bdd.update_attr_with_ids( s[0], attr_id, id_topic, val) else: for s in students: val = dlg.new_value() self.mod_bdd.update_attr_with_ids( s[0], attr_id, id_topic, val) self.__bdd.commit() self.on_attribute_selection_changed()
def on_delete_course(self) -> None: """ Deletes the selected course """ if not VConfirmDialog(self.gui, "confirm_message_delete").exec_(): return self.mod_bdd.delete_course_with_id(self.main_ctrl.id_course) self.main_ctrl.id_course = 0 self.__bdd.commit() self.show_all_courses()
def on_delete_group(self) -> None: """ Deletes the selected group """ if not VConfirmDialog(self.gui, "confirm_message_delete").exec_(): return self.mod_bdd.delete_group_by_id(self.main_ctrl.id_group) self.main_ctrl.id_group = 0 self.__bdd.commit() self.show_all_groups()
def on_delete_attributes(self) -> None: """ Deletes all the selected attribtues """ if not VConfirmDialog(self.gui, "confirm_message_delete").exec_(): return for id_a in self.gui.sidewidget.attributes().selected_attributes(): self.mod_bdd.delete_attribute_with_id(id_a) self.__bdd.commit() self.show_all_attributes()
def killstudent(self): if not VConfirmDialog(self.gui, "confirm_message_delete").exec_(): return self.gui.status_bar.showMessage(tr("grp_action_del_student"), 3000) list_id_students = self.gui.sidewidget.students().selected_students() for id_std in list_id_students: self.mod_bdd.remove_student_from_group(id_std, self.main_ctrl.id_group) self.course_ctrl.show_course() self.show_all_groups(current=self.main_ctrl.id_group) self.__bdd.commit()
def on_create_grp_std(self, new_grp_std: str): """ Creates a new group or a new student with the specified name. It is a group if the received string starts with 'grp '. It is a student if it starts with 'std '. """ prefix = new_grp_std[:4] name = new_grp_std[4:] if prefix == 'grp ': # Group creation self.gui.status_bar.showMessage(f"Creation du groupe {name}", 3000) id_group = self.mod_bdd.create_group(name) list_id_students = self.gui.sidewidget.students( ).selected_students() for id_std in list_id_students: self.mod_bdd.insert_isin(id_std, id_group) if name[-1] in ["1", "A", "a"] and VConfirmDialog( self.gui, "confirm_create_complementary_group").exec_(): namec = name[:-1] namec += chr(ord(name[-1]) + 1) # create complementary group id_group = self.mod_bdd.create_group(namec) # Students are unselected at this point list_all_students = self.mod_bdd.get_students_in_group( self.mod_bdd.get_group_name_by_id(self.main_ctrl.id_group)) for std in list_all_students: if std.id not in list_id_students: self.mod_bdd.insert_isin(std.id, id_group) self.show_all_groups() elif prefix == 'std ': # Student creation self.gui.status_bar.showMessage(f"Creation de l'élève {name}", 3000) lastname, firstname = process_line(name, ";") self.mod_bdd.insert_student_in_group_id(firstname, lastname, 0, self.main_ctrl.id_group) self.course_ctrl.show_course() self.show_all_groups(current=self.main_ctrl.id_group) else: # Student edition id_std = int(prefix) lastname, firstname = process_line(name, ";") self.gui.status_bar.showMessage( f"Renommage de l'élève {firstname} {lastname}", 3000) self.mod_bdd.rename_student_by_id(id_std, firstname, lastname) self.course_ctrl.show_course() self.show_all_groups(current=self.main_ctrl.id_group) self.__bdd.commit()
def delete(self) -> None: if not VConfirmDialog(self.gui, "confirm_message_delete").exec_(): return desks_id = self.v_canvas.get_selected_tiles() for d in desks_id: id_student = self.mod_bdd.get_desk_by_id(d).id_student if id_student == 0: self.remove_desk_by_id(d) else: # We free the desk self.v_canvas.set_student(d, "", "") self.mod_bdd.set_student_in_desk_by_id(0, d) self.__bdd.commit() self.synchronize_canvas_selection_with_side_list() self.v_canvas.repaint()
def __init__(self): """ Application main controller. """ QObject.__init__(self) # Create the Views self.gui = ViewMainFrame(self.sig_quit, self.sig_config_mode_changed, self.sig_export_csv) self.v_canvas = self.gui.central_widget.classroom_tab.v_canvas # BDD connection bdd_path, bdd_exists = AssetManager.getInstance().bdd_path() if not bdd_exists: bp = QFileDialog.getExistingDirectory(self.gui, tr("select_db")) if bp == "" or not path.isdir(bp): self.mod_bdd = None return bdd_path = path.normpath(bp + "/sdc_db") if path.isfile(bdd_path): self.__bdd = sqlite3.connect(bdd_path) else: # we initialize a new BDD if not VConfirmDialog(self.gui, "confirm_db_creation").exec_(): self.mod_bdd = None return self.__bdd = self.initialize_bdd(bdd_path) config = AssetManager.getInstance().get_config_parser() config.set('main', 'bdd_path', bdd_path) AssetManager.getInstance().save_config(config) else: self.__bdd = sqlite3.connect(bdd_path) self.mod_bdd = ModBdd(self.__bdd) self.gui.set_bdd_version(self.mod_bdd.get_version()) # Create secondary controllers self.attr_ctrl = AttrController(self, self.__bdd) self.course_ctrl = CourseController(self, self.__bdd) self.group_ctrl = GroupController(self, self.__bdd) # Plugs the signals into the views self.v_canvas.sig_select_tile = self.sig_select_tile self.gui.central_widget.sig_shuffle = self.sig_shuffle self.gui.sig_quit = self.sig_quit self.v_canvas.sig_canvas_click = self.sig_canvas_click self.v_canvas.sig_desk_selected = self.sig_desk_selected self.v_canvas.sig_canvas_drag = self.sig_canvas_drag self.v_canvas.sig_tile_info = self.sig_canvas_right_click self.gui.sidewidget.courses( ).sig_course_changed = self.sig_course_changed self.gui.sidewidget.courses( ).courses_toolbar.add_widget.sig_new_element = self.sig_create_course self.gui.sidewidget.courses( ).sig_topic_changed = self.sig_topic_changed self.gui.sidewidget.students( ).students_toolbar.sig_combo_changed = self.sig_student_group_changed ViewMenuButton.sig_action = self.sig_action_triggered self.gui.maintoolbar.sig_TBbutton = self.sig_TBbutton self.gui.sidewidget.students( ).students_toolbar.create_field.sig_create = self.sig_create_grp_std self.gui.sidewidget.attributes( ).attributes_toolbar.add_widget.sig_new_element = self.sig_create_attribute self.gui.sidewidget.attributes( ).attributes_toolbar.add_widget.sig_delete = self.sig_delete_attributes self.gui.sidewidget.courses( ).courses_toolbar.sig_delete = self.sig_delete_course self.gui.sidewidget.attributes( ).sig_selection_changed = self.sig_attr_selection_changed self.gui.central_widget.attributes_tab.sig_cell_clicked = self.sig_attribute_cell_selected # Signals connection self.sig_select_tile.connect( self.attr_ctrl.on_attribute_selection_changed) self.sig_quit.connect(self.do_quit) self.sig_canvas_click.connect(self.course_ctrl.add_desk) self.sig_desk_selected.connect( self.course_ctrl.on_desk_selection_changed_on_app) self.sig_canvas_drag.connect(self.course_ctrl.move_desk) self.sig_canvas_right_click.connect( self.attr_ctrl.show_student_attributes) self.sig_shuffle.connect(self.course_ctrl.desk_shuffle) self.sig_course_changed.connect(self.course_ctrl.on_course_changed) self.sig_create_course.connect(self.course_ctrl.on_create_course) self.sig_topic_changed.connect(self.course_ctrl.on_topic_changed) self.sig_student_group_changed.connect( self.group_ctrl.on_student_group_changed) self.sig_action_triggered.connect(self.action_triggered) self.sig_TBbutton.connect(self.action_triggered) self.sig_create_grp_std.connect(self.group_ctrl.on_create_grp_std) self.sig_create_attribute.connect(self.attr_ctrl.on_create_attr) self.sig_delete_attributes.connect(self.attr_ctrl.on_delete_attributes) self.sig_delete_course.connect(self.course_ctrl.on_delete_course) self.sig_attr_selection_changed.connect( self.attr_ctrl.on_attribute_selection_changed) self.sig_attribute_cell_selected.connect( self.attr_ctrl.on_attribute_cell_selected) self.sig_flask_desk_selection_changed.connect( self.course_ctrl.on_desk_selection_changed_on_web) self.sig_close_qr.connect(self.close_qr) self.sig_config_mode_changed.connect(self.on_config_changed) self.sig_export_csv.connect(self.attr_ctrl.export_csv) self.actions_table = { # Action buttons "import_csv": self.group_ctrl.import_pronote, "auto_place": self.group_ctrl.auto_place, "sort_asc": lambda: self.group_ctrl.sort_alpha(False), "sort_desc": lambda: self.group_ctrl.sort_alpha(True), "sort_desks_Z": lambda: self.course_ctrl.sort_desks(sort_type="Z"), "sort_desks_2": lambda: self.course_ctrl.sort_desks(sort_type="2"), "sort_desks_U": lambda: self.course_ctrl.sort_desks(sort_type="U"), "killstudent": self.group_ctrl.killstudent, "delete_group": self.group_ctrl.on_delete_group, # Toolbar buttons "filter_select": self.attr_ctrl.change_filter_selection, "select": self.course_ctrl.auto_select_desks, "choice": self.course_ctrl.student_random_pick, "choice_attr": self.course_ctrl.student_attr_pick, "delete": self.course_ctrl.delete, "lot_change": self.attr_ctrl.lot_change, "print": self.course_ctrl.export_pdf, "show_qr": self.show_qr } # properties self.id_course = 0 self.id_group = 0 self.selection_mode = self.SEL_ALL self.filter_selection = False self.std_dialog_info: VStdAttributesDialog = None self.qr_dialog: VQRCode = None # initialize the views self.course_ctrl.show_all_courses() self.group_ctrl.show_all_groups() self.attr_ctrl.show_all_attributes() self.gui.on_config_mode(False) self.gui.update() # initialize connection to flask server self.flask_client = socketio.Client() self.flask_client.connect( 'http://localhost:' + AssetManager.getInstance().config('webapp', 'port')) self.flask_server = None # search for new version latest_version = AssetManager.getInstance().get_latest_version() if latest_version > AssetManager.getInstance().config( 'main', 'version'): self.gui.status_bar.showMessage(tr("new_version") + latest_version)