def test_time_pair(self): json_time = { "start": "12:20", "end": "14:00" } t = TimePair() t.load(json_time) self.assertEqual(str(t.save()), str(json_time), "Time save/Load test failed")
def combo_box_start_changed(self, index) -> None: """ Slot to change the end time of the pair. """ old_index = self.combo_box_end.currentIndex() self.combo_box_end.clear() self.combo_box_end.addItems(TimePair.time_ends()[index:])
def set_pair(self, pair: StudentPair) -> None: """ Method to set the pair to edit. :param pair: Pair """ self._edit_pair = pair self.line_edit_title.setText(str(self._edit_pair["title"])) self.line_edit_lecturer.setText(str(self._edit_pair["lecturer"])) self.combo_box_type.setCurrentText(str(self._edit_pair["type"])) self.line_edit_classes.setText(str(self._edit_pair["classroom"])) self.combo_box_subgroup.setCurrentText(str( self._edit_pair["subgroup"])) time: TimePair = self._edit_pair["time"] if time is not None: number = time.get_number() self.combo_box_start.setCurrentIndex(number) self.combo_box_end.clear() self.combo_box_end.addItems(TimePair.time_ends()[number:]) self.combo_box_end.setCurrentIndex(time.duration() - 1) self._dates = self._edit_pair["dates"] self.update_list_widget_date()
def __init__(self, number, parent: QWidget = None): super().__init__(parent) self._number: int = number self._edit_pair: StudentPair = None self._dates: DatePair = DatePair() # window settings self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.setWindowTitle(self.tr("Creator")) self.setMinimumSize(640, 350) self.resize(800, 400) # general settings window self.group_box_general = QGroupBox(self.tr("General")) self.layout_general = QFormLayout(self.group_box_general) # title self.label_title = QLabel(self.tr("Title")) self.layout_general.setWidget(0, QFormLayout.LabelRole, self.label_title) self.line_edit_title = QLineEdit("") self.layout_general.setWidget(0, QFormLayout.FieldRole, self.line_edit_title) # lecturer self.label_lecturer = QLabel(self.tr("Lecturer")) self.layout_general.setWidget(1, QFormLayout.LabelRole, self.label_lecturer) self.line_edit_lecturer = QLineEdit("") self.layout_general.setWidget(1, QFormLayout.FieldRole, self.line_edit_lecturer) self.completer = QCompleter(LecturerPair.get_lecturers()) self.completer.setModelSorting(QCompleter.CaseSensitivelySortedModel) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setFilterMode(Qt.MatchContains) self.line_edit_lecturer.setCompleter(self.completer) # type self.label_type = QLabel(self.tr("Type")) self.layout_general.setWidget(2, QFormLayout.LabelRole, self.label_type) self.combo_box_type = QComboBox() self.layout_general.setWidget(2, QFormLayout.FieldRole, self.combo_box_type) for name, attrib in TypePairAttrib.items(): self.combo_box_type.addItem(name, attrib) # classes self.label_classes = QLabel(self.tr("Classes")) self.layout_general.setWidget(3, QFormLayout.LabelRole, self.label_classes) self.line_edit_classes = QLineEdit("") self.layout_general.setWidget(3, QFormLayout.FieldRole, self.line_edit_classes) # subgroup self.label_subgroup = QLabel(self.tr("Subgroup")) self.layout_general.setWidget(4, QFormLayout.LabelRole, self.label_subgroup) self.combo_box_subgroup = QComboBox() self.layout_general.setWidget(4, QFormLayout.FieldRole, self.combo_box_subgroup) for name, attrib in SubgroupPairAttrib.items(): self.combo_box_subgroup.addItem(name, attrib) # time setting self.group_box_time = QGroupBox(self.tr("Time")) self.layout_time = QFormLayout(self.group_box_time) self.label_start = QLabel(self.tr("Start")) self.layout_time.setWidget(0, QFormLayout.LabelRole, self.label_start) self.combo_box_start = QComboBox() self.layout_time.setWidget(0, QFormLayout.FieldRole, self.combo_box_start) self.label_end = QLabel(self.tr("End")) self.layout_time.setWidget(1, QFormLayout.LabelRole, self.label_end) self.combo_box_end = QComboBox() self.layout_time.setWidget(1, QFormLayout.FieldRole, self.combo_box_end) self.combo_box_start.addItems(TimePair.time_starts()) self.combo_box_start.setCurrentIndex(self._number) self.combo_box_end.addItems(TimePair.time_ends()) self.combo_box_end.setCurrentIndex(self._number) # date setting self.group_box_date = QGroupBox(self.tr("Date")) self.layout_date_edit = QHBoxLayout(self.group_box_date) self.list_widget_date = QListWidget(self.group_box_date) self.layout_date_edit.addWidget(self.list_widget_date) self.layout_date_edit_navigate = QVBoxLayout() self.layout_date_edit.addLayout(self.layout_date_edit_navigate) self.push_button_add_date = QPushButton(self.tr("Add")) self.layout_date_edit_navigate.addWidget(self.push_button_add_date) self.push_button_edit_date = QPushButton(self.tr("Edit")) self.layout_date_edit_navigate.addWidget(self.push_button_edit_date) self.push_button_remove_date = QPushButton(self.tr("Remove")) self.layout_date_edit_navigate.addWidget(self.push_button_remove_date) self.layout_date_edit_navigate.addStretch(1) # navigate self.layout_navigate = QHBoxLayout() self.layout_navigate.addStretch(1) self.push_button_ok = QPushButton(self.tr("OK")) self.layout_navigate.addWidget(self.push_button_ok) self.push_button_cancel = QPushButton(self.tr("Cancel")) self.layout_navigate.addWidget(self.push_button_cancel) # layout settings self.layout_general_time = QVBoxLayout() self.layout_general_time.addWidget(self.group_box_general) self.layout_general_time.addWidget(self.group_box_time) self.layout_center = QHBoxLayout() self.layout_center.addLayout(self.layout_general_time) self.layout_center.addWidget(self.group_box_date) self.layout_main = QVBoxLayout() self.layout_main.addLayout(self.layout_center) self.layout_main.addLayout(self.layout_navigate) self.setLayout(self.layout_main) # connection self.combo_box_start.currentIndexChanged.connect( self.combo_box_start_changed) self.list_widget_date.itemDoubleClicked.connect( self.push_button_edit_date_clicked) self.push_button_add_date.clicked.connect( self.push_button_add_date_clicked) self.push_button_edit_date.clicked.connect( self.push_button_edit_date_clicked) self.push_button_remove_date.clicked.connect( self.push_button_remove_date_clicked) self.push_button_ok.clicked.connect(self.push_button_ok_clicked) self.push_button_cancel.clicked.connect( self.push_button_cancel_clicked)
def export_full_to_pdf(schedule_ref: Schedule, title_text: str, file_path: str, font_name: str, font_path: str, encoding: str, progress=None) -> None: """ Method for exports to PDF file """ file = QFileInfo(file_path) # pdf pdf = FPDF(orientation="L") # encoding if encoding == "UTF-8": pdf.add_font(font_name, "", font_path, uni=True) else: pdf.add_font(font_name, "", font_path) pdf.set_doc_option("core_fonts_encoding", encoding) pdf.set_font(font_name) pdf.add_page() x, y = float(pdf.get_x()), float(pdf.get_y()) w = float(pdf.w) - 2 * float(pdf.get_x()) h = float(pdf.h) - 2 * float(pdf.get_y()) - 6 pdf.set_auto_page_break(True, margin=y) title = 10 pdf.set_font_size(14) pdf.cell(w, title, txt=title_text, align="C", border=0) h -= title first_column, first_row = 4, 4 step_column = (w - first_row) / 8 step_row = (h - first_column) / 6 indexes = schedule_ref.indexes() table_widget = schedule_editor_window.ScheduleTableWidget() table_widget.set_schedule(schedule_ref) # processing week_step = 100 / 7 count = 0 i = 0 while i < 7: j = 0 while j < 9: if i == 0 and j == 0: # upper-left cell pdf.set_xy(x, y + title) pdf.cell(first_column, first_row, border=1) j += 1 elif i == 0: # top cells with time pdf.set_xy(x + first_row + step_column * (j - 1), y + title) pdf.set_font_size(8) pdf.cell(step_column, first_row, txt=TimePair.time_start_end(j - 1), align="C", border=1) j += 1 elif j == 0: # left cells with days of the week pdf.set_xy( x, y + title + first_column + step_row * (i - 1) + step_row) pdf.rotate(90) pdf.set_font_size(8) pdf.cell(step_row, first_row, txt=str(DaysOfWeek.value_of(i - 1)), align="C", border=1) pdf.rotate(0) j += 1 else: # cells inside the table pdf.set_xy(x + first_row + step_column * (j - 1), y + title + first_column + step_row * (i - 1)) simple_row = (step_row / indexes[i - 1]) prev_x, prev_y = pdf.get_x(), pdf.get_y() start_index = sum(indexes[r] for r in range(i - 1)) number_row = 0 for m in range(start_index, start_index + indexes[i - 1]): item = table_widget.item(m, j - 1) if item is not None: x_span_count = table_widget.columnSpan(m, j - 1) y_span_count = table_widget.rowSpan(m, j - 1) pdf.set_xy(prev_x, prev_y + number_row * simple_row) pdf.cell(step_column * x_span_count, simple_row * y_span_count, border=1) text = item.text() if text != "": draw_text( pdf, x + first_row + step_column * (j - 1), y + title + first_column + step_row * (i - 1) + simple_row * number_row, step_column * x_span_count, simple_row * y_span_count, text) number_row += 1 pdf.set_xy(prev_x, prev_y) j += 1 i += 1 if progress is not None: count += 1 progress.setValue(week_step * count) if progress.wasCanceled(): break pdf.output(file.absoluteFilePath())
def export_weeks_to_pdf(schedule_ref: Schedule, title_text: str, add_date: bool, file_path: str, font_name: str, font_path: str, encoding: str, start: datetime.date, end: datetime.date, color_a: QColor, color_b: QColor, progress=None) -> None: """ Method for exports to PDF file """ file = QFileInfo(file_path) # pdf pdf = FPDF(orientation="L") # encoding if encoding == "UTF-8": pdf.add_font(font_name, "", font_path, uni=True) else: pdf.add_font(font_name, "", font_path) pdf.set_doc_option("core_fonts_encoding", encoding) # processing week_step = 100 / (end - start).days / 7 count = 0 pdf.set_font(font_name) while True: pdf.add_page() schedule = schedule_ref.create_week_schedule( start, start + datetime.timedelta(days=6)) indexes = schedule.indexes() table_widget = schedule_editor_window.ScheduleTableWidget() table_widget.set_schedule(schedule) start += datetime.timedelta(days=6) x, y = float(pdf.get_x()), float(pdf.get_y()) w = float(pdf.w) - 2 * float(pdf.get_x()) h = float(pdf.h) - 2 * float(pdf.get_y()) - 6 pdf.set_auto_page_break(True, margin=y) title = 10 title_page = title_text if add_date: start_week = (start + datetime.timedelta(days=-6)).strftime("%d.%m.%Y") end_week = start.strftime("%d.%m.%Y") title_page += f". {start_week} - {end_week}" pdf.set_font_size(14) pdf.cell(w, title, txt=title_page, align="C", border=0) h -= title first_column, first_row = 4, 4 step_column = (w - first_row) / 8 step_row = (h - first_column) / 6 i = 0 while i < 7: j = 0 while j < 9: if i == 0 and j == 0: # upper-left cell pdf.set_xy(x, y + title) pdf.cell(first_column, first_row, border=1) j += 1 elif i == 0: # top cells with time pdf.set_xy(x + first_row + step_column * (j - 1), y + title) pdf.set_font_size(8) pdf.cell(step_column, first_row, txt=TimePair.time_start_end(j - 1), align="C", border=1) j += 1 elif j == 0: # left cells with days of the week pdf.set_xy( x, y + title + first_column + step_row * (i - 1) + step_row) pdf.rotate(90) pdf.set_font_size(8) pdf.cell(step_row, first_row, txt=str(DaysOfWeek.value_of(i - 1)), align="C", border=1) pdf.rotate(0) j += 1 else: # cells inside the table pdf.set_xy(x + first_row + step_column * (j - 1), y + title + first_column + step_row * (i - 1)) simple_row = (step_row / indexes[i - 1]) prev_x, prev_y = pdf.get_x(), pdf.get_y() start_index = sum(indexes[r] for r in range(i - 1)) number_row = 0 for m in range(start_index, start_index + indexes[i - 1]): item = table_widget.item(m, j - 1) if item is not None: x_span_count = table_widget.columnSpan(m, j - 1) y_span_count = table_widget.rowSpan(m, j - 1) pdf.set_xy(prev_x, prev_y + number_row * simple_row) # pdf.cell(step_column * x_span_count, # simple_row * y_span_count, # border=1) day, number, duration = i - 1, j - 1, x_span_count pairs = schedule.pairs_by_index( day, number, duration, number_row) # select color for cell if all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.Common for pair in pairs): # common pdf.cell(step_column * x_span_count, simple_row * y_span_count, border=1) elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.A for pair in pairs): # A subgroup pdf.set_fill_color(color_a.red(), color_a.green(), color_a.blue()) pdf.cell(step_column * x_span_count, simple_row * y_span_count, border=1, fill=1) elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.B for pair in pairs): # B subgroup pdf.set_fill_color(color_b.red(), color_b.green(), color_b.blue()) pdf.cell(step_column * x_span_count, simple_row * y_span_count, border=1, fill=1) else: # A and B subgroup prev_x = pdf.get_x() prev_y = pdf.get_y() toggle = True row = 5 column = math.ceil(step_column * x_span_count / step_row * row) for t in range(column): for n in range(row): pdf.set_xy( prev_x + t * step_column * x_span_count / column, prev_y + n * step_row / row) if toggle: color = color_a toggle = False else: color = color_b toggle = True pdf.set_fill_color( color.red(), color.green(), color.blue()) pdf.cell(step_column * x_span_count / column, simple_row * y_span_count / row, border=0) pdf.set_xy(prev_x, prev_y) pdf.cell(step_column * x_span_count, simple_row * y_span_count, border=1) if len(pairs) != 0: text = "\n".join(str(pair) for pair in pairs) draw_text( pdf, x + first_row + step_column * (j - 1), y + title + first_column + step_row * (i - 1) + simple_row * number_row, step_column * x_span_count, simple_row * y_span_count, text) number_row += 1 pdf.set_xy(prev_x, prev_y) j += 1 # old # pairs = schedule.pairs_by_index(i - 1, j - 1, 1) \ # + schedule.pairs_by_index(i - 1, j - 1, 2) # # max_duration = max([1, *[pair["time"].duration() for pair in pairs]]) # # # select color for cell # if all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.Common # for pair in pairs): # # common # pdf.cell(step_column * max_duration, # step_row, # border=1) # elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.A # for pair in pairs): # # A subgroup # pdf.set_fill_color(color_a.red(), color_a.green(), color_a.blue()) # pdf.cell(step_column * max_duration, # step_row, # border=1, # fill=1) # elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.B # for pair in pairs): # # B subgroup # pdf.set_fill_color(color_b.red(), color_b.green(), color_b.blue()) # pdf.cell(step_column * max_duration, # step_row, # border=1, # fill=1) # else: # # A and B subgroup # prev_x = pdf.get_x() # prev_y = pdf.get_y() # # toggle = True # # row = 5 # column = math.ceil(step_column * max_duration / step_row * row) # # for m in range(column): # for n in range(row): # pdf.set_xy(prev_x + m * step_column * max_duration / column, # prev_y + n * step_row / row) # # if toggle: # color = color_a # toggle = False # else: # color = color_b # toggle = True # # pdf.set_fill_color(color.red(), color.green(), color.blue()) # pdf.cell(step_column * max_duration / column, # step_row / row, # border=0, # fill=1) # pdf.set_xy(prev_x, prev_y) # pdf.cell(step_column * max_duration, # step_row, # border=1) # text = "" # for pair in pairs: # text += str(pair) + "\n" # # if text != "": # draw_text(pdf, # x + first_row + step_column * (j - 1), # y + title + first_column + step_row # * (i - 1), # step_column * max_duration, # step_row, # text) # j += max_duration i += 1 if progress is not None: count += 1 progress.setValue(week_step * count) if progress.wasCanceled(): break start += datetime.timedelta(days=1) if end <= start: break pdf.output(file.absoluteFilePath())
def __init__(self): super().__init__() self._schedule = Schedule() self._indexes_ref = self._schedule.indexes() self._file = None # window settings self.setWindowTitle(self.tr("Schedule Editor")) self.setMinimumSize(800, 600) # central widget settings self.table_widget = ScheduleTableWidget() self.table_widget.set_schedule(self._schedule) self.table_widget.setVerticalHeader( CustomHeaderView(Qt.Vertical, self._indexes_ref)) self.table_widget.setHorizontalHeader(CustomHeaderView(Qt.Horizontal)) self.table_widget.setWordWrap(True) self.table_widget.setContextMenuPolicy(Qt.CustomContextMenu) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.table_widget.horizontalHeader().setMaximumHeight(25) self.table_widget.horizontalHeader().setStretchLastSection(True) self.table_widget.verticalHeader().setSectionResizeMode( QHeaderView.Fixed) self.table_widget.verticalHeader().setMaximumWidth(25) self.table_widget.verticalHeader().setStretchLastSection(True) self.table_widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self.table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.table_widget.setColumnCount(self._schedule.columns()) for i in range(8): item = QTableWidgetItem(TimePair.time_start_end(i)) self.table_widget.setHorizontalHeaderItem(i, item) self.table_widget.setRowCount(self._schedule.rows()) for i, day in enumerate(DaysOfWeek.to_list()): item = QTableWidgetItem(day) self.table_widget.setVerticalHeaderItem(i, item) self.setCentralWidget(self.table_widget) # menu bar settings self.menu_bar = self.menuBar() self.menu_file = self.menu_bar.addMenu(self.tr("&File")) self.action_new_file = QAction(QIcon.fromTheme("document-new"), self.tr("&New file"), self) self.action_new_file.setShortcut("Ctrl+N") self.menu_file.addAction(self.action_new_file) self.action_open = QAction(QIcon.fromTheme("document-open"), self.tr("&Open"), self) self.action_open.setShortcut("Ctrl+O") self.menu_file.addAction(self.action_open) self.action_save = QAction(QIcon.fromTheme("document-save"), self.tr("&Save"), self) self.action_save.setShortcut("Ctrl+S") self.menu_file.addAction(self.action_save) self.action_save_as = QAction(QIcon.fromTheme("document-save-as"), self.tr("Save as..."), self) self.action_save_as.setShortcut("Ctrl+S+A") self.menu_file.addAction(self.action_save_as) self.action_export = QAction(self.tr("Export"), self) self.action_export.setShortcut("Ctrl+E") self.menu_file.addAction(self.action_export) self.action_import = QAction(self.tr("Import"), self) self.action_import.setShortcut("Ctrl+I") self.menu_file.addAction(self.action_import) self.menu_file.addSeparator() self.action_settings = QAction(self.tr("Settings"), self) self.menu_file.addAction(self.action_settings) self.action_about = QAction(self.tr("About"), self) self.menu_file.addAction(self.action_about) self.action_exit = QAction(self.tr("&Quit"), self) self.action_exit.setShortcut("Ctrl+Q") self.menu_file.addAction(self.action_exit) # status bar settings self.statusBar().showMessage(self.tr("Ready!")) # connection self.action_new_file.triggered.connect(self.action_new_file_clicked) self.action_open.triggered.connect(self.action_open_clicked) self.action_save.triggered.connect(self.action_save_clicked) self.action_save_as.triggered.connect(self.action_save_as_clicked) self.action_export.triggered.connect(self.action_export_clicked) self.action_import.triggered.connect(self.action_import_clicked) self.action_settings.triggered.connect(self.action_settings_clicked) self.action_about.triggered.connect(self.action_about_clicked) self.action_exit.triggered.connect(self.close) # self.table_widget.clicked.connect(self.test) self.table_widget.doubleClicked.connect(self.cell_clicked) self.table_widget.customContextMenuRequested.connect( self.context_menu_requested)
def import_from_pdf(process_id, manager: ImportManager) -> None: tesseract = TesseractWrapper(tesseract_path=manager.tesseract_path) while not manager.queue.empty(): try: file_path = manager.queue.get(True, 1) file = QFileInfo(file_path) # convert from pdf to PIL image img_pdf = pdf2image.convert_from_path( file.absoluteFilePath(), dpi=manager.dpi, poppler_path=manager.poppler_path) img_pdf = img_pdf[0].convert('RGB') # convert to NumPy array img = np.array(img_pdf) img = img[:, :, ::-1].copy() # set mask grey = cv.cvtColor(img, cv.COLOR_BGR2GRAY) thresh = cv.threshold(grey, 127, 255, 0)[1] if manager.flags["stop"]: break # found contours contours = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)[0] height, width = img.shape[:2] # max and min area of rect max_area = height * width / 20 min_area = max_area / 40 cells = [] time_cells = dict() contours_number = len(contours) number = 0 for k, contour in enumerate(contours, 1): rect = cv.minAreaRect(contour) area = int(rect[1][0] * rect[1][1]) if min_area < area < max_area: if manager.flags["stop"]: break x, y, w, h = cv.boundingRect(contour) crop_img = img[int(y):int(y + h), int(x):int(x + w)] txt = tesseract.to_string(crop_img) found = False for i in range(8): if TimePair.time_starts( )[i] in txt and TimePair.time_ends()[i]: time_cells[i] = (x, x + w) found = True break if not found: cells.append((x, x + w, " ".join(txt.split()))) # draw debug rect with number if manager.debug_image: box = cv.boxPoints(rect) box = np.int0(box) blue_color = (255, 0, 0) center = (int(rect[0][0]), int(rect[0][1])) cv.drawContours(img, [box], 0, blue_color, 2) cv.putText(img, str(number), (center[0] - 100, center[1] - 40), cv.FONT_HERSHEY_SIMPLEX, 3, blue_color, 12) number += 1 process = int(k / contours_number * 70) manager.progress_value_list[process_id] = process manager.progress_text_list[process_id] = "{} {}%".format( file.baseName(), process) if manager.debug_image: cv.imwrite(file_path[0:-4] + "-debug.jpg", img) if manager.flags["stop"]: break schedule = Schedule() cells_number = len(cells) for k, cell in enumerate(cells): if manager.flags["stop"]: break start_x, end_x, text = cell first_start_time, first_end_time = time_cells[0] if not abs(end_x - first_start_time) < abs(start_x - first_start_time): text = "\n".join(re.findall(r".*?\]", text)) while True: try: pairs = parse_pair(manager, text) break except InvalidDatePair as ex: text = confuse_loop( process_id, manager, ConfuseSituationException( file.absoluteFilePath(), text, confuse=str(ex))) except ConfuseSituationException as ex: ex.filename = file.absoluteFilePath( )[0:-4] + "-debug.jpg" ex.cell = k ex.context = text if ex.maybe_answer == "": ex.maybe_answer = text text = confuse_loop(process_id, manager, ex) if len(pairs) != 0: diff_start = abs(start_x - first_start_time) diff_end = abs(end_x - first_end_time) start, end = 0, 0 for number, (start_time, end_time) in time_cells.items(): diff = abs(start_x - start_time) if diff < diff_start: diff_start = diff start = number diff = abs(end_x - end_time) if diff < diff_end: diff_end = diff end = number for pair in pairs: pair["time"].set_time( TimePair.time_starts()[start], TimePair.time_ends()[end]) schedule.add_pair(pair) process = int(70 + k / cells_number * 30) manager.progress_value_list[process_id] = process manager.progress_text_list[process_id] = "{} {}%".format( file.baseName(), process) schedule.save(file.absoluteFilePath()[0:-4] + ".json") print(file.absoluteFilePath()[0:-4] + ".json") if manager.flags["stop"]: break if manager.weekly: export_weeks_to_pdf( schedule, file.baseName(), True, file.absoluteFilePath()[0:-4] + "-weekly.pdf", manager.font_name, manager.font_path, manager.encoding, manager.start, manager.end, manager.color_a, manager.color_b) if manager.full: export_full_to_pdf(schedule, file.baseName(), file.absoluteFilePath()[0:-4] + "-full.pdf", manager.font_name, manager.font_path, manager.encoding) except Exception as ex: print("Exception, process:", process_id, "is:", ex) traceback.print_exc() manager.progress_value_list[process_id] = 100 manager.progress_text_list[process_id] = "Work complete"