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()
 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()
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 ###
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 ###