def load(self, filename): if not os.path.isfile(filename): QtGui.QMessageBox.critical(self, "File Not Found", "Couldn't find \"" + filename + "\"") self.reject() return self.anagram = AnagramFile(filename) self.setWindowTitle("Anagram Editor - " + os.path.basename(filename)) self.ui.txtSolutionTrans.setText(self.anagram.solution.translated) self.ui.txtSolutionOrig.setText(self.anagram.solution.original) self.ui.txtExtraTrans.setText(self.anagram.extra.translated) self.ui.txtExtraOrig.setText(self.anagram.extra.original) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Easy, self.anagram.easy) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Norm, self.anagram.normal) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Hard, self.anagram.hard) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Easy, self.anagram.easy_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Norm, self.anagram.normal_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Hard, self.anagram.hard_orig) # The translation side is updated automatically because the text box changes. self.update_checks(CHK_TYPE.Orig) self.update_preview()
def load(self, filename): if not os.path.isfile(filename): QtGui.QMessageBox.critical(self, "File Not Found", "Couldn't find \"" + filename + "\"") self.reject() return self.anagram = AnagramFile(filename) self.setWindowTitle("Anagram Editor - " + os.path.basename(filename)) self.ui.txtSolutionTrans.setText(self.anagram.solution[common.editor_config.lang_trans]) self.ui.txtSolutionOrig.setText(self.anagram.solution[common.editor_config.lang_orig]) self.ui.txtExtraTrans.setText(self.anagram.extra[common.editor_config.lang_trans]) self.ui.txtExtraOrig.setText(self.anagram.extra[common.editor_config.lang_orig]) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Easy, self.anagram.easy) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Norm, self.anagram.normal) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Hard, self.anagram.hard) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Easy, self.anagram.easy_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Norm, self.anagram.normal_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Hard, self.anagram.hard_orig) # The translation side is updated automatically because the text box changes. self.update_checks(CHK_TYPE.Orig) self.update_preview()
class AnagramEditor(QtGui.QDialog): def __init__(self, parent=None): super(AnagramEditor, self).__init__(parent) self.ui = Ui_Anagram() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.anagram = None # Better than doing it manually in Qt Designer. for diff in CHK_DIFF: for i in range(15): self.connect(self.get_check(CHK_TYPE.Trans, diff, i + 1), QtCore.SIGNAL("clicked(bool)"), self.check_clicked) # They don't need to be editable. for diff in CHK_DIFF: for i in range(15): self.get_check(CHK_TYPE.Orig, diff, i + 1).setEnabled(False) self.update_checks() ############################################################################## ### @fn load() ### @desc Load an anagram dat file. ############################################################################## def load(self, filename): if not os.path.isfile(filename): QtGui.QMessageBox.critical(self, "File Not Found", "Couldn't find \"" + filename + "\"") self.reject() return self.anagram = AnagramFile(filename) self.setWindowTitle("Anagram Editor - " + os.path.basename(filename)) self.ui.txtSolutionTrans.setText(self.anagram.solution.translated) self.ui.txtSolutionOrig.setText(self.anagram.solution.original) self.ui.txtExtraTrans.setText(self.anagram.extra.translated) self.ui.txtExtraOrig.setText(self.anagram.extra.original) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Easy, self.anagram.easy) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Norm, self.anagram.normal) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Hard, self.anagram.hard) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Easy, self.anagram.easy_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Norm, self.anagram.normal_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Hard, self.anagram.hard_orig) # The translation side is updated automatically because the text box changes. self.update_checks(CHK_TYPE.Orig) self.update_preview() ############################################################################## ### @fn save() ### @desc Save the anagram dat file, with backups/changes. ############################################################################## def save(self): source = self.anagram.filename filename = os.path.basename(self.anagram.filename) # First, make the backup. self.anagram.backup() # Then save a copy of our changes for easy access. change_file = os.path.join(common.editor_config.changes_dir, filename) self.anagram.save(change_file) # Then save for real. self.anagram.save() ############################################################################## ### @fn get_check() ### @desc Returns the checkbox object for a type, difficulty, and value. ############################################################################## def get_check(self, type, difficulty, value): if not type == CHK_TYPE.Orig and not type == CHK_TYPE.Trans: return None if not difficulty == CHK_DIFF.Easy and not difficulty == CHK_DIFF.Norm and not difficulty == CHK_DIFF.Hard: return None if not value in CHK_VAL: return None return vars(self.ui)["chk%s%s%d" % (str(type), str(difficulty), value)] ############################################################################## ### @fn update_preview() ### @desc Updates the preview image. ############################################################################## def update_preview(self): image = draw_anagram(self.anagram) pixmap = QtGui.QPixmap.fromImage(image) self.ui.lblPreview.setPixmap(pixmap) ############################################################################## ### @fn check_clicked() ### @desc What happens when a check is clicked. ############################################################################## def check_clicked(self): self.store_checks() self.update_preview() ############################################################################## ### @fn store_checks() ### @desc Take the check boxes and store their values in our anagram. ############################################################################## def store_checks(self): if not self.anagram == None: self.anagram.easy = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Easy) self.anagram.normal = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Norm) self.anagram.hard = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Hard) ############################################################################## ### @fn set_checks() ### @desc Checks/unchecks the checkboxes based on a list of shown letters. ############################################################################## def set_checks(self, type, difficulty, shown): for i in range(1, 16): checked = False if not shown == None and i in shown: checked = True self.get_check(type, difficulty, i).setChecked(checked) ############################################################################## ### @fn checks_to_list(type, difficulty) ### @desc Converts the check boxes into a list of shown letters. ############################################################################## def checks_to_list(self, type, difficulty): text = "" if type == CHK_TYPE.Trans: text = common.qt_to_unicode(self.ui.txtSolutionTrans.text()) else: text = common.qt_to_unicode(self.ui.txtSolutionOrig.text()) letters = len(text) shown = [] for i in range(1, letters + 1): if self.get_check(type, difficulty, i).isChecked(): shown.append(i) return shown ############################################################################## ### @fn update_checks(type) ### @desc Enables/disables check boxes as necessary. ############################################################################## def update_checks(self, type=CHK_TYPE.Trans): text = "" if type == CHK_TYPE.Trans: text = common.qt_to_unicode(self.ui.txtSolutionTrans.text()) else: text = common.qt_to_unicode(self.ui.txtSolutionOrig.text()) letters = len(text) for diff in CHK_DIFF: for i in range(1, letters + 1): # Only enable the check boxes for translation mode, since they can't # edit the originals. if type == CHK_TYPE.Trans: self.get_check(type, diff, i).setEnabled(True) self.get_check(type, diff, i).setVisible(True) for i in range(letters + 1, 16): self.get_check(type, diff, i).setEnabled(False) self.get_check(type, diff, i).setChecked(False) self.get_check(type, diff, i).setVisible(False) ############################################################################## ### @fn changedSolution(text) ### @desc Triggered when the solution box is changed, either manually or ### programatically. ############################################################################## def changed_solution(self, text): self.update_checks(CHK_TYPE.Trans) self.update_preview() ############################################################################## ### @fn editedSolution(text) ### @desc Triggered when the solution box is edited manually-- ### NOT programatically. ############################################################################## def edited_solution(self, text): text = sanitize_text(text) cursor = self.ui.txtSolutionTrans.cursorPosition() self.ui.txtSolutionTrans.setText(text) self.ui.txtSolutionTrans.setCursorPosition(cursor) self.anagram.solution.translated = text self.store_checks() ############################################################################## ### @fn editedExtra(text) ### @desc Triggered when the extra box is edited manually-- ### NOT programatically. ############################################################################## def edited_extra(self, text): text = sanitize_text(text) cursor = self.ui.txtExtraTrans.cursorPosition() self.ui.txtExtraTrans.setText(text) self.ui.txtExtraTrans.setCursorPosition(cursor) self.anagram.extra.translated = text ############################################################################## ### @fn accept() ### @desc Overrides the Save button. ############################################################################## def accept(self): if self.anagram.solution.translated == "" or self.anagram.extra.translated == "": QtGui.QMessageBox.critical( self, "No Translation", "Please fill in the translation boxes.") return self.save() super(AnagramEditor, self).accept() ############################################################################## ### @fn reject() ### @desc Overrides the Cancel button. ############################################################################## def reject(self): super(AnagramEditor, self).reject() #if __name__ == '__main__': #import sys #app = QtGui.QApplication(sys.argv) #app.connect(app, QtCore.SIGNAL("lastWindowClosed()"), #app, #QtCore.SLOT("quit()") #) #form = AnagramEditor() #form.load("umdimage/anagram_11.dat") #form.show() #sys.exit(app.exec_()) ### EOF ###
def pack_dir(self, dir, handler, file_list=None, align_toc=16, align_files=16, eof=False): table_of_contents = {} if file_list == None: file_list = sorted(os.listdir(dir)) num_files = len(file_list) toc_length = (num_files + 1) * 4 if eof: toc_length += 1 if toc_length % align_toc > 0: toc_length += align_toc - (toc_length % align_toc) handler.seek(0) handler.write(struct.pack("<I", num_files)) handler.write(bytearray(toc_length - 4)) for file_num, item in enumerate(file_list): full_path = os.path.join(dir, item) if os.path.isfile(full_path): basename = os.path.basename(item) basename, ext = os.path.splitext(basename) # Special handling for certain data types. if ext == ".txt": data = self.pack_txt(full_path) # anagram_81.dat is not a valid anagram file. <_> elif basename[: 8] == "anagram_" and ext == ".dat" and not basename == "anagram_81": anagram = AnagramFile(full_path) data = anagram.pack(for_game=True).bytes else: with open(full_path, "rb") as f: data = f.read() else: temp_align_toc = 16 temp_align_files = 4 if item in SPECIAL_ALIGN: temp_align_toc = SPECIAL_ALIGN[item][0] temp_align_files = SPECIAL_ALIGN[item][1] elif os.path.basename(dir) in SPECIAL_ALIGN and len( SPECIAL_ALIGN[os.path.basename(dir)]) == 4: temp_align_toc = SPECIAL_ALIGN[os.path.basename(dir)][2] temp_align_files = SPECIAL_ALIGN[os.path.basename(dir)][3] if os.path.splitext(full_path)[1].lower() == ".lin": data = self.pack_lin(full_path) else: data = io.BytesIO() with io.BufferedWriter(data) as fh: self.pack_dir(full_path, fh, align_toc=temp_align_toc, align_files=temp_align_files, eof=eof) fh.flush() data = data.getvalue() data = bytearray(data) file_size = len(data) padding = 0 if file_size % align_files > 0: padding = align_files - (file_size % align_files) data.extend(bytearray(padding)) handler.seek(0, io.SEEK_END) file_pos = handler.tell() handler.write(data) handler.seek((file_num + 1) * 4) handler.write(struct.pack("<I", file_pos)) del data self.file_count += 1 if self.file_count % 25 == 0: self.progress.setLabelText("Reading...\n" + full_path) self.progress.setValue(self.file_count) # Re-center the dialog. progress_w = self.progress.geometry().width() progress_h = self.progress.geometry().height() new_x = self.x + ((self.width - progress_w) / 2) new_y = self.y + ((self.height - progress_h) / 2) self.progress.move(new_x, new_y) table_of_contents[item] = {} table_of_contents[item]["size"] = file_size table_of_contents[item]["pos"] = file_pos if eof: handler.seek(0, io.SEEK_END) archive_len = handler.tell() handler.seek((num_files + 1) * 4) handler.write(struct.pack("<I", archive_len)) return table_of_contents
class AnagramEditor(QtGui.QDialog): def __init__(self, parent = None): super(AnagramEditor, self).__init__(parent) self.ui = Ui_Anagram() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.anagram = None # Better than doing it manually in Qt Designer. for diff in CHK_DIFF: for i in range(15): self.connect(self.get_check(CHK_TYPE.Trans, diff, i + 1), QtCore.SIGNAL("clicked(bool)"), self.check_clicked) # They don't need to be editable. for diff in CHK_DIFF: for i in range(15): self.get_check(CHK_TYPE.Orig, diff, i + 1).setEnabled(False) self.update_checks() ############################################################################## ### @fn load() ### @desc Load an anagram dat file. ############################################################################## def load(self, filename): if not os.path.isfile(filename): QtGui.QMessageBox.critical(self, "File Not Found", "Couldn't find \"" + filename + "\"") self.reject() return self.anagram = AnagramFile(filename) self.setWindowTitle("Anagram Editor - " + os.path.basename(filename)) self.ui.txtSolutionTrans.setText(self.anagram.solution[common.editor_config.lang_trans]) self.ui.txtSolutionOrig.setText(self.anagram.solution[common.editor_config.lang_orig]) self.ui.txtExtraTrans.setText(self.anagram.extra[common.editor_config.lang_trans]) self.ui.txtExtraOrig.setText(self.anagram.extra[common.editor_config.lang_orig]) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Easy, self.anagram.easy) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Norm, self.anagram.normal) self.set_checks(CHK_TYPE.Trans, CHK_DIFF.Hard, self.anagram.hard) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Easy, self.anagram.easy_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Norm, self.anagram.normal_orig) self.set_checks(CHK_TYPE.Orig, CHK_DIFF.Hard, self.anagram.hard_orig) # The translation side is updated automatically because the text box changes. self.update_checks(CHK_TYPE.Orig) self.update_preview() ############################################################################## ### @fn save() ### @desc Save the anagram dat file, with backups/changes. ############################################################################## def save(self): source = self.anagram.filename filename = os.path.basename(self.anagram.filename) # First, make the backup. self.anagram.backup() # Then save a copy of our changes for easy access. change_file = os.path.join(common.editor_config.changes_dir, filename) self.anagram.save(change_file) # Then save for real. self.anagram.save() ############################################################################## ### @fn get_check() ### @desc Returns the checkbox object for a type, difficulty, and value. ############################################################################## def get_check(self, type, difficulty, value): if not type == CHK_TYPE.Orig and not type == CHK_TYPE.Trans: return None if not difficulty == CHK_DIFF.Easy and not difficulty == CHK_DIFF.Norm and not difficulty == CHK_DIFF.Hard: return None if not value in CHK_VAL: return None return vars(self.ui)["chk%s%s%d" % (str(type), str(difficulty), value)] ############################################################################## ### @fn update_preview() ### @desc Updates the preview image. ############################################################################## def update_preview(self): image = draw_anagram(self.anagram) pixmap = QtGui.QPixmap.fromImage(image) self.ui.lblPreview.setPixmap(pixmap) ############################################################################## ### @fn check_clicked() ### @desc What happens when a check is clicked. ############################################################################## def check_clicked(self): self.store_checks() self.update_preview() ############################################################################## ### @fn store_checks() ### @desc Take the check boxes and store their values in our anagram. ############################################################################## def store_checks(self): if not self.anagram == None: self.anagram.easy = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Easy) self.anagram.normal = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Norm) self.anagram.hard = self.checks_to_list(CHK_TYPE.Trans, CHK_DIFF.Hard) ############################################################################## ### @fn set_checks() ### @desc Checks/unchecks the checkboxes based on a list of shown letters. ############################################################################## def set_checks(self, type, difficulty, shown): for i in range(1, 16): checked = False if not shown == None and i in shown: checked = True self.get_check(type, difficulty, i).setChecked(checked) ############################################################################## ### @fn checks_to_list(type, difficulty) ### @desc Converts the check boxes into a list of shown letters. ############################################################################## def checks_to_list(self, type, difficulty): text = "" if type == CHK_TYPE.Trans: text = common.qt_to_unicode(self.ui.txtSolutionTrans.text()) else: text = common.qt_to_unicode(self.ui.txtSolutionOrig.text()) letters = len(text) shown = [] for i in range(1, letters + 1): if self.get_check(type, difficulty, i).isChecked(): shown.append(i) return shown ############################################################################## ### @fn update_checks(type) ### @desc Enables/disables check boxes as necessary. ############################################################################## def update_checks(self, type = CHK_TYPE.Trans): text = "" if type == CHK_TYPE.Trans: text = common.qt_to_unicode(self.ui.txtSolutionTrans.text()) else: text = common.qt_to_unicode(self.ui.txtSolutionOrig.text()) letters = len(text) for diff in CHK_DIFF: for i in range(1, letters + 1): # Only enable the check boxes for translation mode, since they can't # edit the originals. if type == CHK_TYPE.Trans: self.get_check(type, diff, i).setEnabled(True) self.get_check(type, diff, i).setVisible(True) for i in range(letters + 1, 16): self.get_check(type, diff, i).setEnabled(False) self.get_check(type, diff, i).setChecked(False) self.get_check(type, diff, i).setVisible(False) ############################################################################## ### @fn changedSolution(text) ### @desc Triggered when the solution box is changed, either manually or ### programatically. ############################################################################## def changed_solution(self, text): self.update_checks(CHK_TYPE.Trans) self.update_preview() ############################################################################## ### @fn editedSolution(text) ### @desc Triggered when the solution box is edited manually-- ### NOT programatically. ############################################################################## def edited_solution(self, text): text = sanitize_text(text) cursor = self.ui.txtSolutionTrans.cursorPosition() self.ui.txtSolutionTrans.setText(text) self.ui.txtSolutionTrans.setCursorPosition(cursor) self.anagram.solution[common.editor_config.lang_trans] = text self.store_checks() ############################################################################## ### @fn editedExtra(text) ### @desc Triggered when the extra box is edited manually-- ### NOT programatically. ############################################################################## def edited_extra(self, text): text = sanitize_text(text) cursor = self.ui.txtExtraTrans.cursorPosition() self.ui.txtExtraTrans.setText(text) self.ui.txtExtraTrans.setCursorPosition(cursor) self.anagram.extra[common.editor_config.lang_trans] = text ############################################################################## ### @fn accept() ### @desc Overrides the Save button. ############################################################################## def accept(self): if self.anagram.solution[common.editor_config.lang_trans] == "" or self.anagram.extra[common.editor_config.lang_trans] == "": QtGui.QMessageBox.critical(self, "No Translation", "Please fill in the translation boxes.") return self.save() super(AnagramEditor, self).accept() ############################################################################## ### @fn reject() ### @desc Overrides the Cancel button. ############################################################################## def reject(self): super(AnagramEditor, self).reject() #if __name__ == '__main__': #import sys #app = QtGui.QApplication(sys.argv) #app.connect(app, QtCore.SIGNAL("lastWindowClosed()"), #app, #QtCore.SLOT("quit()") #) #form = AnagramEditor() #form.load("umdimage/anagram_11.dat") #form.show() #sys.exit(app.exec_()) ### EOF ###