示例#1
0
    def openFiles(self):
        '''Prompts the user for the location of the dictionary and document to be checked, via a
        the system's file explorer dialog.'''

        self.fileOptions = {'parent': self.root, 'initialdir': self.directory}
        try:
            with askopenfile(message="Location of dictionary file:", **self.fileOptions) as dictionaryFile:
                self.dictionary = LanguageHelper(dictionaryFile)
            with askopenfile(message="Location of document file:", **self.fileOptions) as documentFile:
                self.document = map(str.strip, documentFile.read().split(' '))
        except AttributeError:
            sys.exit()
示例#2
0
class SpellChecker:
    '''A spell-checking and editing toolkit with a GUI interface.'''
    def __init__(self):
        '''Constructs the Tkinter window and configures all the necessary options and bindings.
        Declares all necessary class-level attributes, constructs the widgets to be bound to the
        Tkinter window, and starts the spell checking process automatically after creation.'''

        self.directory = os.path.dirname(os.path.realpath(__file__))
        self.root = Tk()
        self.root.geometry("1000x600+%d+%d" % (self.root.winfo_screenwidth()/2 - 500,
                                               self.root.winfo_screenheight()/2 - 300))
        self.root.protocol('WM_DELETE_WINDOW', sys.exit) 
        self.openFiles()
        self.documentIndex = int()
        self.documentIndexHistory = list()
        self.ignoreList = list()
        self.punctuation = ['.', '?', '!', ',', ';', ':']
        self.createButtons()
        self.createDocumentBox()
        self.createSuggestionBox()
        self.startSpellChecker()
        mainloop()

    def openFiles(self):
        '''Prompts the user for the location of the dictionary and document to be checked, via a
        the system's file explorer dialog.'''

        self.fileOptions = {'parent': self.root, 'initialdir': self.directory}
        try:
            with askopenfile(message="Location of dictionary file:", **self.fileOptions) as dictionaryFile:
                self.dictionary = LanguageHelper(dictionaryFile)
            with askopenfile(message="Location of document file:", **self.fileOptions) as documentFile:
                self.document = map(str.strip, documentFile.read().split(' '))
        except AttributeError:
            sys.exit()

    def createButtons(self):
        '''Creates all necessary buttons and binds them to the relevant methods. Places them in the
        main window via the grid geometry manager.'''

        labels = [["New",    {0: self.newFile         }], ["Exit",     {0: self.exitProgram     }],
                  ["Save",   {0: self.saveToFile      }], ["Clear",    {0: self.clearText       }],
                  ["Add",    {0: self.addToDictionary }], ["Edit",     {0: self.editSuggestion  }],
                  ["Ignore", {0: self.ignoreWord      }], ["Previous", {0: self.previousWord    }]]
        buttonList = dict()
        for each in range(len(labels)):
            buttonList[labels[each][0]] = Button(self.root, height=2, width=9, text=labels[each][0], command=labels[each][1][0])
            buttonList[labels[each][0]].grid(row=0, column=each, padx = 8, pady=2)

    def createDocumentBox(self):
        '''Creates the Text widget that will be used to display the document and all edits to the
        user. Placed in the main window via the place geometry manager. Uses relative, scalable
        coordinates.'''

        self.documentBox = Text(self.root, yscrollcommand=Scrollbar(Frame(self.root), orient=VERTICAL).set)
        self.documentBox.insert(INSERT, ' '.join(self.document))
        self.documentBox.place(relx=0.02, y=50, relwidth=0.46, relheight=0.88)

    def createSuggestionBox(self):
        '''Creates the Listbox widget that will be used to display the edit suggestions as choices
        to the user. Placed in the main window via the place geometry manager. Uses relative,
        scalable coordinates.'''

        self.suggestionBox = Listbox(self.root, yscrollcommand=Scrollbar(Frame(self.root), orient=VERTICAL).set)
        self.suggestionBox.bind("<<ListboxSelect>>", lambda x: self.updateSuggestionBox(True))
        self.suggestionBox.place(relx=0.52, y=50, relwidth=0.46, relheight=0.88)

    def updateDocumentBox(self, wordFix):
        '''Updates the Text widget with the edit selected by the user. Takes a string as an argument
        and clears the widget when the program runs out of words to edit.'''

        try:
            if self.document[self.documentIndex][-1] in self.punctuation:
                self.document[self.documentIndex] = wordFix + self.document[self.documentIndex][-1]
            else:
                self.document[self.documentIndex] = wordFix
            self.documentBox.delete('1.0', END)
            self.documentBox.insert(INSERT, ' '.join(self.document))
        except IndexError:
            self.documentBox.delete('1.0', END)

    def updateSuggestionBox(self, trigger=False):
        '''Checks if the function was triggered by the user's Listbox selection. If so, it updates
        the document box with the desired edit. If not, cycles forward until it finds an incorrectly
        spelled word and it updates the document index and displays the new edit suggestions to the
        user accordingly. Records every misspelled word found in a list, storing the original word
        and the index where it was found. Takes a boolean as an argument, whose default value is
        False.'''

        try:
            if trigger:
                self.updateDocumentBox(self.suggestionBox.get(self.suggestionBox.curselection()))
            cycleForward = True
            while cycleForward:
                if self.document[self.documentIndex] in self.ignoreList:
                    choiceList = [None]
                elif self.document[self.documentIndex][-1] in self.punctuation:
                    choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex][:-1])
                else:
                    choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex])
                if choiceList not in [[None], []]:
                    self.documentIndexHistory.append([self.documentIndex, self.document[self.documentIndex]])
                    self.suggestionBox.delete(0, END)
                    for choice in choiceList:
                        self.suggestionBox.insert(END, choice)
                    cycleForward = False
                else:
                    self.documentIndex += 1
        except (IndexError, TclError):
            self.suggestionBox.delete(0, END)

    def startSpellChecker(self):
        '''Starts the program by cycling through the words in the document until it finds an
        incorrectly spelled word. Displays edit suggestions to the user accordingly.'''

        if self.document[self.documentIndex][-1] in self.punctuation:
            choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex][:-1])
        else:
            choiceList = self.dictionary.getSuggestions(self.document[self.documentIndex])
        if choiceList not in [[None], []]:
            self.documentIndexHistory.append([self.documentIndex, self.document[self.documentIndex]])
            for choice in choiceList:
                self.suggestionBox.insert(END, choice)
        else:
            self.documentIndex += 1
            self.startSpellChecker()

    def newFile(self):
        '''Destroys the Tk object, prompting the outside loop to construct a new SpellChecker
        instance.'''

        self.root.destroy()

    def exitProgram(self):
        '''Prompts the user to choose a filename and location to save the document progress, and
        then hard-exits the program.'''

        self.saveToFile()
        sys.exit()

    def saveToFile(self):
        '''Prompts the user to choose a filename and location to save the document progress.'''

        try:
            with asksaveasfile(message="Location to save file:", **self.fileOptions) as output:
                output.write(' '.join(self.document))
        except AttributeError:
            pass

    def clearText(self):
        '''Clears the document and document box widget.'''

        self.document = list()
        self.documentBox.delete('1.0', END)

    def addToDictionary(self):
        '''Adds the mispelled word to a list of acceptable words and calls previousWord(), which
        cycles the document index forward and moves onto the next mispelled word.'''

        self.ignoreList.append(self.document[self.documentIndex])
        self.ignoreWord()

    def editSuggestion(self):
        '''Promps the user for a custom edit to the mispelled word, via a system dialog. Applies
        the edit to the document and updates the document box accordingly. Calls updateSuggestionBox
        at the end to cycle the program forward to the next mispelled word.'''

        try:
            editedWord = askstring("Edit Word", "Enter word to use:")
            self.updateDocumentBox(editedWord)
            self.documentIndex += 1
            self.updateSuggestionBox()
        except TypeError:
            pass

    def ignoreWord(self):
        '''Increments the document index by one and calls updateSuggestionBox() to cycle forward to
        the next misspelled word.'''

        self.documentIndex += 1
        self.updateSuggestionBox()

    def previousWord(self):
        '''Sets the currect document index to the index of the previous mispelled word and pops the
        two most recent edits off the edit history. Updates the document with the original
        misspelled word and calls updateSuggestionBox() to cycle the program forward.'''

        try:
            self.documentIndex = self.documentIndexHistory[-2][0]
            self.updateDocumentBox(self.documentIndexHistory[-2][1])
            self.documentIndexHistory = self.documentIndexHistory[:-2]
            self.updateSuggestionBox()
        except IndexError:
            pass