Beispiel #1
0
class DlgSpellingReplace:
    """Main class for this dialog."""

    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        self.msgbox = MessageBox(unoObjs)
        self.dlgCtrls = None
        self.evtHandler = None
        self.buttonPressed = ""
        self.changeTo = None
        self.doExecute = None
        self.doEndExecute = None
        self.doDispose = None

    def makeDlg(self):
        """This method will neither show nor destroy the dialog.
        That is left up to the calling code, via
        doExecute() and doDispose().
        """
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(
            self.unoObjs, ctrl_getter, self.evtHandler)
        self.evtHandler.setCtrls(self.dlgCtrls)

        ## Methods to display and close the dialog

        self.doExecute = dlg.execute
        # hides the dialog and cause the execute() method to return
        self.doEndExecute = dlg.endExecute
        # destroys the dialog
        self.doDispose = dlg.dispose

    def setContents(self, textFound, suggestions, context):
        self.buttonPressed = ""
        self.changeTo = textFound
        self.dlgCtrls.lblFoundText.setText(textFound)
        self.dlgCtrls.lblContext.setText(context)
        self.dlgCtrls.txtChangeTo.setText(textFound)
        logger.debug(repr(suggestions))
        dutil.fill_list_ctrl(self.dlgCtrls.listSuggestions, suggestions)
        logger.debug(util.funcName('end'))

    def finish(self, buttonPressed):
        if buttonPressed in ['Change', 'ChangeAll']:
            if (self.dlgCtrls.txtChangeTo.getText() ==
                    self.dlgCtrls.lblFoundText.getText()):
                self.msgbox.display(
                    "You did not make any changes to the word.")
                return
        self.buttonPressed = buttonPressed
        self.changeTo = self.dlgCtrls.txtChangeTo.getText()
        self.doEndExecute()   # return from the execute() loop

    def getResults(self):
        return self.buttonPressed, self.changeTo
class ChangerMaker:
    """Save a CC table or XSLT file from data in the spreadsheet."""
    def __init__(self, calcUnoObjs, userVars):
        self.unoObjs = calcUnoObjs
        self.userVars = userVars
        self.msgbox = MessageBox(self.unoObjs)
        self.filepath = ""
        self.matchPartial = False
        self.exportType = ""
        self.xpathExprs = ""
        self.sfMarkers = ""

    def setFilepath(self, newVal):
        self.filepath = newVal

    def setExportType(self, newVal):
        self.exportType = newVal

    def setSFM(self, newVal):
        self.sfMarkers = newVal

    def setMatchPartial(self, newVal):
        self.matchPartial = newVal

    def setXpathExprs(self, newVal):
        """Value should be an iterable containing strings."""
        self.xpathExprs = newVal

    def make(self):
        logger.debug(util.funcName('begin'))
        progressBar = ProgressBar(self.unoObjs, "Getting data...")
        progressBar.show()
        progressBar.updateBeginning()
        try:
            columnOrder = ColumnOrder(self.userVars)
            columnOrder.loadUserVars()
            changeList = getChangeList(self.unoObjs, columnOrder)
            progressBar.updateFinishing()
        except exceptions.DocAccessError:
            self.msgbox.display("Error reading spreadsheet.")
        progressBar.close()
        progressBar = ProgressBar(self.unoObjs, "Saving file...")
        progressBar.show()
        progressBar.updatePercent(50)
        if self.exportType == "ReplacementCCT":
            outputter = CCT_Writer(self.filepath)
            outputter.writeSimpleReplacements(changeList)
        elif self.exportType == "SFM_CCT":
            outputter = CCT_Writer(self.filepath)
            outputter.writeComplete(changeList, self.sfMarkers)
        elif self.exportType == "XSLT":
            outputter = XSLT_Writer(self.filepath)
            outputter.write(changeList, self.xpathExprs, self.matchPartial)
        progressBar.updateFinishing()
        progressBar.close()
        logger.debug(util.funcName('end'))
class AbbrevManager:
    """Sends output to the Writer doc."""
    def __init__(self, unoObjs, styles):
        self.unoObjs = unoObjs
        self.msgbox = MessageBox(unoObjs)
        self.styleNames = styles.styleNames
        self.styles = styles
        logger.debug("AbbrevManager init() finished")

    def outputList(self, abbrevList):
        logger.debug(util.funcName('begin'))

        ## Start with default formatting at the beginning

        oVC = self.unoObjs.viewcursor
        if oVC.TextTable or oVC.TextFrame:
            self.msgbox.display(
                "The cursor cannot be inside a table or frame.")
            return
        elif oVC.getText().getImplementationName() == "SwXHeadFootText":
            self.msgbox.display("The cursor cannot be in a header or footer.")
            return
        textcursor = self.unoObjs.text.createTextCursorByRange(
            self.unoObjs.viewcursor.getStart())
        logger.debug("Created a text cursor.")
        textcursor.setPropertyValue('ParaStyleName', 'Standard')
        textcursor.setPropertyToDefault('CharStyleName')

        didOutput = False
        for abbr in abbrevList:
            if not abbr.shouldOutput():
                logger.debug("Skipping abbrev %s.", abbr.abbrevText)
                continue
            logger.debug("Outputting abbrev %s.", abbr.abbrevText)
            didOutput = True
            self.styles.requireParaStyle('abbr')
            textcursor.setPropertyValue("ParaStyleName",
                                        self.styleNames['abbr'])
            abbr_str = abbr.abbrevText + "\t" + abbr.fullName
            self.unoObjs.text.insertString(textcursor, abbr_str, 0)
            self.unoObjs.text.insertControlCharacter(textcursor,
                                                     PARAGRAPH_BREAK, 0)

        if didOutput:
            self.unoObjs.text.insertControlCharacter(textcursor,
                                                     PARAGRAPH_BREAK, 0)
            textcursor.setPropertyValue("ParaStyleName", "Standard")
        else:
            self.unoObjs.text.insertString(textcursor,
                                           "No abbreviations found.", 0)
            self.unoObjs.text.insertControlCharacter(textcursor,
                                                     PARAGRAPH_BREAK, 0)
        logger.debug(util.funcName('end'))
Beispiel #4
0
def requireInputFile(exType, unoObjs, userVars):
    """Make sure the user has specified an input file.
    If no file is specified, displays an error message and returns false.
    """
    varname = "XML_filePath"
    if exType == EXTYPE_GRAMMAR:
        varname = "XML_filePath00"
    filepath = userVars.get(varname)
    if filepath == "":
        msgbox = MessageBox(unoObjs)
        if exType == EXTYPE_GRAMMAR:
            msgbox.display(
                "Please go to Grammar Settings and specify a file.")
        else:
            msgbox.display(
                "Please go to Phonology Settings and specify a file.")
        return False
    return True
Beispiel #5
0
class SpellingStepper:
    """Step through each row in a word list to check for spelling."""

    def __init__(self, calcUnoObjs, userVars):
        self.unoObjs = calcUnoObjs
        self.userVars = userVars
        self.msgbox = MessageBox(self.unoObjs)
        self.suggestions = SpellingSuggestions(self.msgbox)
        self.suggListSet = False
        self.wantSuggestions = True
        self.currentRow = -1
        self.datalist = []  # List of wordlist_structs.WordInList items.
        self.columnOrder = None

    def loadData(self):
        self.columnOrder = ColumnOrder(self.userVars)
        self.columnOrder.loadUserVars()

        wordlistIO = WordlistIO(self.unoObjs, self.columnOrder)
        self.datalist = wordlistIO.readList()
        self.setSuggestionList()
        return len(self.datalist)

    def gotoRow(self, rowNum):
        """Return copy of WordInList item of that row."""
        self.currentRow = rowNum
        return copy.deepcopy(self.currentRowData())

    def setSuggestionList(self):
        if not self.wantSuggestions:
            self.suggListSet = False
            return
        wordStrings = []
        for wordData in self.datalist:
            if (wordData.isCorrect is not Tribool('False')
                    and not wordData.correction):
                wordStrings.append(wordData.text)
        self.suggestions.setList(wordStrings)
        self.suggListSet = True

    def getSuggestions(self, listToIgnore):
        if not self.suggListSet:
            self.setSuggestionList()
        wordData = self.currentRowData()
        suggList = self.suggestions.getSuggestions(wordData.text)

        ## Remove duplicate words
        wordData = self.currentRowData()
        for wordText in listToIgnore + [wordData.text]:
            if wordText in suggList:
                suggList.remove(wordText)
        return suggList

    def setIsCorrect(self, newVal):
        """:param newVal: type Tribool"""
        logger.debug("%s %r %s", util.funcName('begin'), newVal, type(newVal))
        outputter = SpreadsheetOutput(self.unoObjs)
        wordData = self.currentRowData()
        wordData.isCorrect = newVal
        try:
            outputter.outputString(
                self.columnOrder.getColLetter('colOk'), self.currentRow,
                wordData.isCorrect_str())
        except exceptions.DocAccessError:
            self.msgbox.display("Error writing to spreadsheet.")
        self.setSuggestionList()
        logger.debug(util.funcName('end'))

    def setCorrection(self, newText):
        outputter = SpreadsheetOutput(self.unoObjs)
        wordData = self.currentRowData()
        wordData.correction = newText
        try:
            outputter.outputString(
                self.columnOrder.getColLetter('colChange'), self.currentRow,
                newText)
        except exceptions.DocAccessError:
            self.msgbox.display("Error writing to spreadsheet.")

    def currentRowData(self):
        """Data starts on the second row of the Calc spreadsheet."""
        return self.datalist[self.currentRow - 2]
Beispiel #6
0
class DlgAbbreviations:
    """Main class for this dialog."""
    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        self.userVars = UserVars(Prefix.ABBREVIATIONS, unoObjs.document,
                                 logger)
        self.msgbox = MessageBox(unoObjs)
        self.abbrevList = abbreviations.AbbrevList(self.unoObjs, self.userVars)
        self.selectedIndex = -1  # position in abbrevList and listboxAbbrevs
        self.selectedAbbrev = None
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.dlgClose = dlg.endExecute
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(self.unoObjs, ctrl_getter, self.evtHandler)
        logger.debug("Got controls.")

        self.dlgCtrls.loadValues(self.userVars, self.abbrevList)
        self.viewAbbrev(False)

        ## Display the dialog and then close it

        dlg.execute()
        self.storeResults()
        dlg.dispose()

    def viewAbbrev(self, checkForUpdates):
        """
        Fill the form with values of the selected abbreviation.
        :param checkForUpdates: set to true to update current item if needed
        """
        logger.debug(util.funcName('begin'))
        if checkForUpdates:
            newSelectedItem = self.dlgCtrls.listboxAbbrevs.getSelectedItem()
            logger.debug("newSelectedItem '%s'", newSelectedItem)
            self.updateAbbrev(False)
            if newSelectedItem:
                # Select the new item again,
                # since it may have been deselected while refreshing the list.
                self.dlgCtrls.listboxAbbrevs.selectItem(newSelectedItem, True)
        try:
            self.selectedIndex = dutil.get_selected_index(
                self.dlgCtrls.listboxAbbrevs)
            logger.debug("self.selectedIndex %d", self.selectedIndex)
        except exceptions.ChoiceProblem:
            return
        abbr = self.abbrevList[self.selectedIndex]
        logger.debug("Abbrev %s", abbr.abbrevText)

        self.dlgCtrls.txtAbbrev.setText(abbr.abbrevText)
        self.dlgCtrls.txtFullName.setText(abbr.fullName)
        if abbr.forceOutput:
            self.dlgCtrls.chkForceOutput.setState(True)
        else:
            self.dlgCtrls.chkForceOutput.setState(False)
        self.dlgCtrls.txtOccurrences.setText(abbr.occurrences)
        logger.debug(util.funcName('end'))

    def updateAbbrev(self, selectNewItem):
        """
        Update abbrev attributes from dialog fields if changed.
        :param selectNewItem: set to True to select item when refreshing list
        """
        logger.debug(util.funcName('begin'))
        if not 0 <= self.selectedIndex < len(self.abbrevList):
            if selectNewItem:
                self.msgbox.displayExc(self.abbrevList.noItemSelected())
            return
        newAbbrev = abbreviations.Abbrev()
        newAbbrev.abbrevText = self.dlgCtrls.txtAbbrev.getText()
        if not newAbbrev.abbrevText:
            return
        newAbbrev.fullName = self.dlgCtrls.txtFullName.getText()
        if self.dlgCtrls.chkForceOutput.getState() == 1:  # checked
            newAbbrev.forceOutput = True
        oldAbbrev = self.abbrevList[self.selectedIndex]
        if oldAbbrev:
            if newAbbrev.sameAs(oldAbbrev):
                return
            logger.debug("%r not sameAs %r", newAbbrev, oldAbbrev)
            if newAbbrev.abbrevText == oldAbbrev.abbrevText:
                newAbbrev.occurrences = oldAbbrev.occurrences
            try:
                self.abbrevList.updateItem(self.selectedIndex, newAbbrev)
            except exceptions.ChoiceProblem as exc:
                self.msgbox.displayExc(exc)
                return
        if selectNewItem:
            self.refreshListAndSelectItem(newAbbrev)
        else:
            self.refreshList()
        logger.debug(util.funcName('end'))

    def refreshList(self):
        dutil.fill_list_ctrl(self.dlgCtrls.listboxAbbrevs,
                             self.abbrevList.getItemTextList())

    def refreshListAndSelectItem(self, selItem):
        logger.debug(util.funcName('begin'))
        dutil.fill_list_ctrl(self.dlgCtrls.listboxAbbrevs,
                             self.abbrevList.getItemTextList(), str(selItem))
        try:
            self.selectedIndex = dutil.get_selected_index(
                self.dlgCtrls.listboxAbbrevs)
            logger.debug("self.selectedIndex %d", self.selectedIndex)
            self.viewAbbrev(False)
        except exceptions.ChoiceProblem:
            return
        logger.debug(util.funcName('end'))

    def addAbbrev(self):
        logger.debug(util.funcName('begin'))
        newAbbrev = abbreviations.Abbrev()
        newAbbrev.abbrevText = "---"
        newAbbrev.fullName = ""
        self.abbrevList.addItem(newAbbrev, allowDuplicates=True)
        self.refreshListAndSelectItem(newAbbrev)
        logger.debug(util.funcName('end'))

    def deleteAbbrev(self):
        logger.debug(util.funcName('begin'))
        try:
            self.abbrevList.deleteItem(self.selectedIndex)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        self.refreshList()

        ## Select the next item

        if self.dlgCtrls.listboxAbbrevs.getItemCount() > 0:
            dutil.select_index(self.dlgCtrls.listboxAbbrevs,
                               self.selectedIndex)
            self.viewAbbrev(False)
        else:
            ## The list is empty.  Clear the fields.
            logger.debug("Clearing fields.")
            self.dlgCtrls.txtAbbrev.setText("")
            self.dlgCtrls.txtFullName.setText("")
            self.dlgCtrls.chkForceOutput.setState(False)
            self.dlgCtrls.txtOccurrences.setText(0)
            self.selectedIndex = -1
        logger.debug(util.funcName('end'))

    def changeAllCaps(self):
        logger.debug(util.funcName('begin'))
        self.abbrevList.changeAllCaps()
        self.refreshList()
        dutil.select_index(self.dlgCtrls.listboxAbbrevs, self.selectedIndex)
        self.viewAbbrev(False)
        logger.debug(util.funcName('end'))

    def rescan(self):
        logger.debug(util.funcName('begin'))
        abbrevSearch = search.AbbrevSearch(self.unoObjs)
        abbrevSearch.findOccurrences(self.abbrevList)
        self.refreshList()
        dutil.select_index(self.dlgCtrls.listboxAbbrevs, self.selectedIndex)
        self.viewAbbrev(False)
        logger.debug(util.funcName('end'))

    def insertList(self):
        logger.debug(util.funcName('begin'))

        ## Rescan and prepare for output

        abbrevSearch = search.AbbrevSearch(self.unoObjs)
        abbrevSearch.findOccurrences(self.abbrevList)
        self.refreshList()
        self.abbrevList.storeUserVars()
        abbrevStyles = styles.AbbrevStyles(self.unoObjs, self.userVars)
        abbrevStyles.createStyles()

        ## Output the list and close

        writerOutput = outputmanager.AbbrevManager(self.unoObjs, abbrevStyles)
        try:
            writerOutput.outputList(self.abbrevList)
        except exceptions.MessageError as exc:
            self.msgbox.displayExc(exc)
        self.dlgClose()
        logger.debug(util.funcName('end'))

    def findNext(self):
        logger.debug(util.funcName('begin'))

        ## Get search form results

        displayName = self.dlgCtrls.cmbxSearchParaStyle.getText()
        if not displayName:
            self.msgbox.display("Please select a paragraph style.")
            return
        searchConfig = search.AbbrevSearchSettings()
        searchConfig.searchParaStyle = displayName
        self.userVars.store("SearchParaStyle", displayName)

        searchConfig.searchAffix = "any"
        if self.dlgCtrls.optSearchSuffix.getState() == 1:  # checked
            searchConfig.searchAffix = "suffix"
        elif self.dlgCtrls.optSearchPrefix.getState() == 1:  # checked
            searchConfig.searchAffix = "prefix"
        self.userVars.store("SearchAffix", searchConfig.searchAffix)

        try:
            searchConfig.maxSearchLength = int(
                self.dlgCtrls.txtMaxSearchLength.getText())
        except ValueError:
            self.msgbox.display("Please enter a number for max length.")
            return
        self.userVars.store("MaxSearchLength", searchConfig.maxSearchLength)

        searchConfig.searchUpperCase = False
        chkValue = self.dlgCtrls.chkSearchUpperCase.getState()
        if chkValue == 1:
            searchConfig.searchUpperCase = True
        self.userVars.store("SearchUpperCase", str(chkValue))

        searchConfig.startFromBeginning = False
        if self.dlgCtrls.chkStartFromBeginning.getState() == 1:
            searchConfig.startFromBeginning = True
            self.dlgCtrls.chkStartFromBeginning.setState(False)

        searchConfig.searchDelimiters = self.userVars.get("SearchDelimiters")

        ## Search

        abbrevSearch = search.AbbrevSearch(self.unoObjs)
        while True:
            possibleAbbrevs = abbrevSearch.findNext(
                searchConfig, self.abbrevList.getUniqueList())
            if len(possibleAbbrevs) == 0:
                self.msgbox.display("No more possible abbreviations found.")
                return
            for possibleAbbrevText in possibleAbbrevs:
                if possibleAbbrevText.strip() == "":
                    continue
                result = self.msgbox.displayYesNoCancel(
                    "Add '%s' as a new abbreviation?", possibleAbbrevText)
                if result == "yes":
                    logger.debug("Adding abbreviation from search.")
                    newAbbrev = abbreviations.Abbrev()
                    newAbbrev.abbrevText = possibleAbbrevText
                    newAbbrev.occurrences = 1
                    try:
                        self.abbrevList.addItem(newAbbrev)
                        self.refreshListAndSelectItem(newAbbrev)
                    except exceptions.ChoiceProblem as exc:
                        self.msgbox.displayExc(exc)
                elif result == "cancel":
                    return
                elif result == "no":
                    ## continue
                    pass
        logger.debug(util.funcName('end'))

    def storeResults(self):
        logger.debug(util.funcName('begin'))
        self.updateAbbrev(False)
        self.abbrevList.storeUserVars()
        logger.debug(util.funcName('end'))
Beispiel #7
0
class SpellingCharClasses:
    """Suggest spelling changes based on character classes."""
    def __init__(self, calcUnoObjs, userVars):
        self.unoObjs = calcUnoObjs
        self.userVars = userVars
        self.msgbox = MessageBox(self.unoObjs)
        self.script = ""
        self.charsComp = []  # lines of chars to compare
        self.datalist = None
        self.displayResults = True

    def setScript(self, newName):
        self.script = newName

    def getAvailableScriptKeys(self):
        if self.script not in unicode_data.SIMILAR_CHARS:
            return []
        charsDict = unicode_data.SIMILAR_CHARS[self.script]
        keys = list(charsDict.keys())
        if 'AnyConsonants' in unicode_data.SCRIPT_LETTERS[self.script]:
            keys.append('GEMIN')
        return keys

    def setCharCompFromScript(self, charCompOpts):
        """Sets self.charsComp"""
        logger.debug(util.funcName('begin', args=(charCompOpts, )))
        self.charsComp = []
        if self.script not in unicode_data.SIMILAR_CHARS:
            logger.debug("Did not find script '%s'", self.script)
            return
        charsDict = unicode_data.SIMILAR_CHARS[self.script]
        for key in charCompOpts:
            if key in charsDict:
                setList = charsDict[key]
                if len(setList) > 0:
                    setList.sort(key=itemgetter(0))
                    self.charsComp.extend(setList)
            elif key == 'GEMIN':
                if self.script in unicode_data.SCRIPT_LETTERS:
                    consList = unicode_data.SCRIPT_LETTERS[
                        self.script]['AnyConsonants']
                    gemList = []
                    for cons in consList:
                        if self.script in letters.VIRAMA:
                            virama = letters.VIRAMA[self.script]
                            gemChars = "".join([cons, virama, cons])
                        else:
                            gemChars = cons * 2
                        gemList.append([cons, gemChars])
                    self.charsComp.extend(gemList)

    def setCharCompFromInput(self, inputString):
        """Sets self.charsComp from input from user."""
        self.charsComp = []
        for line in inputString.splitlines():
            charlist = []
            for char in line:
                if not char.isspace():
                    charlist.append(char)
            self.charsComp.append(charlist)

    def getCharCompString(self):
        lines = list()
        for charlist in self.charsComp:
            lines.append("  ".join(charlist))
        return os.linesep.join(lines) + os.linesep

    def doChecks(self):
        """Check all words to see if they match by taking character classes
        into account.
        """
        logger.debug(util.funcName('begin'))
        columnOrder = ColumnOrder(self.userVars)
        columnOrder.loadUserVars()
        colLetter = columnOrder.getColLetter('colWord')

        reader = SpreadsheetReader(self.unoObjs)
        try:
            wordStrings = reader.getColumnStringList(colLetter,
                                                     skipFirstRow=True)
        except exceptions.DocAccessError:
            self.msgbox.display("Error reading spreadsheet.")
            return
        words = wordsFromStrings(wordStrings)

        charSetList = []
        for charlist in self.charsComp:
            if len(charlist) < 2:
                # only useful to have at least two characters to compare
                continue
            charset = CharSet(charlist)
            # treat each similarity set as if it were an individual character
            wordChar = WordChar(charset, isCharset=True)
            charSetList.append(wordChar)

        numSimilarWords = compareAllWords(words, charSetList)

        similarWordsStrings = [word.similarWords_str() for word in words]
        colLetter = columnOrder.getColLetter('colSimilar')
        outputter = SpreadsheetOutput(self.unoObjs)
        try:
            outputter.outputToColumn(colLetter, similarWordsStrings)
        except exceptions.DocAccessError:
            self.msgbox.display("Error writing to spreadsheet.")

        if self.displayResults:
            if numSimilarWords == 0:
                self.msgbox.display("Did not find any similar words.")
            else:
                self.msgbox.display("Found %d similar words.", numSimilarWords)
        logger.debug(util.funcName('end'))
Beispiel #8
0
class SpellingChecker:
    """Traverse words in a Writer document to check and make spelling
    corrections.  This is similar in concept to a traditional spell checker.
    Calls DlgSpellingReplace from the UI layer.
    """
    def __init__(self, writerUnoObjs, userVars):
        self.unoObjs = writerUnoObjs
        self.msgbox = MessageBox(self.unoObjs)
        self.userVars = userVars
        self.goodList = GoodList(self.msgbox)
        self.wordAsker = WordAsker(self.unoObjs, self.goodList)
        self.config = None
        self.numChanges = 0

    def setConfig(self, newConfig):
        """Param should be of type CheckerSettings."""
        self.config = newConfig
        self.wordAsker.setConfig(newConfig)

    def doSearch(self):
        """Get text ranges and then check those ranges for words.
        Navigate to each word (perhaps using punctuation list) and
        verify each word against the word list.
        """
        logger.debug(util.funcName('begin'))
        try:
            self.readWordList()
        except (exceptions.FileAccessError, exceptions.DocAccessError) as exc:
            self.msgbox.display(
                "Error reading file %s", self.config.filepath)
            return
        rangesFound = self.getRanges()
        self.numChanges = 0
        try:
            for txtRange in rangesFound:
                self.changeTextRange(txtRange)
            if self.config.whichTask == 'ApplyCorrections':
                plural = "" if self.numChanges == 1 else "s"
                self.msgbox.display(
                    "Made %d correction%s.", self.numChanges, plural)
            else:
                self.msgbox.display("Spell check finished.")
        except exceptions.UserInterrupt:
            pass
        except exceptions.DocAccessError:
            self.msgbox.display("Error writing to spreadsheet.")
        except exceptions.RangeError as exc:
            self.msgbox.displayExc(exc)
        finally:
            self.wordAsker.cleanup()

    def changeTextRange(self, txtRange):
        rangeJumper = RangeJumper(self.unoObjs)
        rangeJumper.setTextRange(txtRange)
        rangeTokens = getTokens(rangeJumper.getString())
        tokenNum = -2   # because the loop starts by += 2
        while True:
            tokenNum += 2   # tokens are in pairs: word, delim
            logger.debug("Token '%d' of %d", tokenNum, len(rangeTokens))
            if tokenNum >= len(rangeTokens):
                break
            word = rangeTokens[tokenNum].strip(self.config.punctuation)
            #word = re.sub(self.config.punct_expr, "", rangeTokens[tokenNum])
            wordLower = self.goodList.firstLower(word)
            wordNoAffix = self.wordAsker.removeAffixes(wordLower)
            suspect = True
            if not word:
                suspect = False
            elif word.isdigit() or word.isspace():
                suspect = False
            elif wordLower in self.goodList or wordNoAffix in self.goodList:
                suspect = False
            elif wordLower in self.wordAsker.wordsToIgnore:
                suspect = False
            if self.config.whichTask == 'ApplyCorrections':
                suspect = wordLower in self.goodList.changeDict
            if suspect:
                logger.debug("Word '%s' is suspect", word)
                try:
                    rangeJumper.selectWord(
                        "".join(rangeTokens[:tokenNum]),
                        rangeTokens[tokenNum])
                except exceptions.RangeError:
                    if self.msgbox.displayOkCancel(
                            "Missed word '%s'.  Keep going?", word):
                        continue
                    else:
                        raise exceptions.UserInterrupt()
                if self.wordAsker.handleWord(
                        word, rangeTokens, tokenNum, rangeJumper):
                    self.numChanges += 1
                    rangeTokens = getTokens(rangeJumper.getString())
                    tokensBefore = getTokens(rangeJumper.getStringBefore())
                    tokenNum = len(tokensBefore)
                    tokenNum -= tokenNum % 2  # make sure it's even

    def readWordList(self):
        """Read word list from Calc.
        Sets self.changeDict if applying corrections.
        """
        fileReader = spreadsheet_reader.CalcFileReader(self.unoObjs)
        fileReader.loadDoc(self.config.filepath)
        self.goodList.setCalcUnoObjs(fileReader.calcUnoObjs)
        columnOrder = ColumnOrder(self.userVars)
        columnOrder.loadUserVars()
        if self.config.whichTask == 'SpellCheck':
            logger.debug("Reading good list.")
            columnLetter = columnOrder.getColLetter('colWord')
            wordListReader = fileReader.getSpreadsheetReader()
            wordList = wordListReader.getColumnStringList(
                columnLetter, skipFirstRow=True)
            self.goodList.setGoodList(
                wordList, self.config.matchCase, self.config.normForm,
                columnLetter)
        else:
            logger.debug("Reading change list.")
            changeList = spellingchanges.getChangeList(
                fileReader.calcUnoObjs, columnOrder)
            for oldVal, newVal in changeList:
                self.goodList.changeDict[
                    self.goodList.firstLower(oldVal)] = newVal

    def getRanges(self):
        progressBar = ProgressBar(self.unoObjs, "Finding text...")
        progressBar.show()
        progressBar.updateBeginning()
        textSearch = TextSearch(self.unoObjs, progressBar)
        textSearch.setConfig(self.config.searchConfig)
        try:
            if self.config.whichScope == 'WholeDoc':
                textSearch.scopeWholeDocTraverse()
            elif self.config.whichScope == 'Selection':
                textSearch.scopeSelection()
            elif self.config.whichScope == 'Language':
                textSearch.scopeLocale()
            elif self.config.whichScope == 'ParaStyle':
                textSearch.scopeParaStyle()
            elif self.config.whichScope == 'CharStyle':
                textSearch.scopeCharStyle()
            elif self.config.whichScope == 'Font':
                textSearch.scopeFont()
            elif self.config.whichScope == 'SFMs':
                textSearch.scopeSFMs()
            else:
                raise exceptions.LogicError(
                    "Unexpected value %s", self.config.whichScope)
            progressBar.updateFinishing()
        except exceptions.MessageError as exc:
            raise exc
        finally:
            progressBar.close()
        return textSearch.getRanges()
class DlgPhonSettings:
    """Main class for this dialog."""

    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        self.userVars = UserVars(Prefix.PHONOLOGY, unoObjs.document, logger)
        self.msgbox = MessageBox(unoObjs)
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(
            self.unoObjs, ctrl_getter, self.evtHandler)
        self.dlgCtrls.loadValues(self.userVars)

        self.dlgClose = dlg.endExecute
        dlg.execute()
        dlg.dispose()

    def selectWritingSys(self):
        logger.debug(util.funcName('begin'))
        logger.debug("Selecting Writing System...")

        filepath = self.dlgCtrls.fileControl.getText()
        if not re.search(r"\.lift$", filepath):
            self.msgbox.display(
                "If you want to use LIFT data, then first specify a "
                "LIFT file exported from FieldWorks.")
            return
        defaultCode = self.dlgCtrls.txtWritingSys.getText()
        dlgWS = DlgWritingSystem(defaultCode, self.unoObjs)
        dlgWS.readFile(filepath)
        if len(dlgWS.writingSystems) == 0:
            self.msgbox.display("No writing systems found.")
            return
        dlgWS.showDlg()
        writingSystem = dlgWS.getResult()
        dlgWS.call_dispose()
        self.dlgCtrls.txtWritingSys.setText(writingSystem.internalCode)

    def storeAndClose(self):
        logger.debug(util.funcName('begin'))
        outSettings = lingex_structs.PhonOutputSettings(self.userVars)
        outSettings.showBrackets = bool(
            self.dlgCtrls.checkboxBrackets.getState())
        outSettings.phonemicLeftmost = bool(
            self.dlgCtrls.optionPhonemicFirst.getState())
        outSettings.storeUserVars()

        inSettings = lingex_structs.PhonInputSettings(self.userVars)
        inSettings.filepath = self.dlgCtrls.fileControl.getText()
        inSettings.phoneticWS = self.dlgCtrls.txtWritingSys.getText()
        inSettings.isLexemePhonetic = bool(
            self.dlgCtrls.optionLexemePht.getState())
        inSettings.storeUserVars()

        PhonologyStyles(self.unoObjs, self.userVars).createStyles()
        PhonologyTags(self.userVars).loadUserVars()
        self.dlgClose()
        logger.debug(util.funcName('end'))
class ExampleSearch:
    """Search for example ref number."""
    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        self.msgbox = MessageBox(unoObjs)
        self.foundSomething = False
        self.search = None
        self.foundString = None
        logger.debug("ExampleSearch init() finished")

    def getFoundString(self):
        return self.foundString

    def findRefNumber(self, startFromBeginning, findingAll=False):
        """Find a #abc123 tag in the document that should be replaced."""
        logger.debug(util.funcName('begin'))

        ## Set up the search

        if self.search is None:
            self.search = self.unoObjs.document.createSearchDescriptor()
            self.search.SearchRegularExpression = True
            self.search.SearchString = \
                r"#[a-zA-Z0-9][a-zA-Z0-9\._\-]*[a-zA-Z0-9][:space:]*"

        ## Do the search

        found = None
        if startFromBeginning:
            found = self.unoObjs.document.findFirst(self.search)
        else:
            found = self.unoObjs.document.findNext(
                self.unoObjs.viewcursor.getEnd(), self.search)

        ## Results

        if found:
            logger.debug("Found %s.", found.String)
            self.unoObjs.controller.select(found)
            self.foundSomething = True
            self.foundString = found.String
        else:
            if self.foundSomething:
                message = "No more reference numbers found."
                self.foundSomething = False
            else:
                message = "Did not find a reference number."
                if findingAll:
                    self.msgbox.display(message)
                if not startFromBeginning:
                    message += (
                        "\n Try checking the box to search from beginning.")
                else:
                    message += "\n Make sure to type # in front."
            if not findingAll:
                self.msgbox.display(message)
            self.foundString = None

    def findRefCharStyle(self,
                         charStyleName,
                         startFromBeginning,
                         findingAll=False):
        """Find text set to reference character style.  Probably it is there
        because an example was inserted.
        """
        logger.debug(util.funcName('begin'))
        charStyleSearch = CharStyleSearch(self.unoObjs, charStyleName,
                                          startFromBeginning)
        foundText = charStyleSearch.doSearch()
        if foundText:
            logger.debug("Found %s.", foundText)
            self.foundSomething = True
            self.foundString = foundText
        else:
            if self.foundSomething:
                message = "No more existing examples found."
                self.foundSomething = False
            else:
                message = "Did not find an existing example."
                if findingAll:
                    self.msgbox.display(message)
                if not startFromBeginning:
                    message += (
                        "\n Try checking the box to search from beginning.")
                else:
                    message += (
                        "\n Verify the example reference number's style.")
            if not findingAll:
                self.msgbox.display(message)
            self.foundString = None

    def refInTable(self):
        """Returns True if the selected ref is in a TextTable.
        Otherwise deselects the ref and returns False.
        """
        if not self.unoObjs.viewcursor.TextTable:
            self.unoObjs.viewcursor.collapseToEnd()
            self.unoObjs.viewcursor.goRight(0, False)
            return False
        return True
class DlgWordList:
    """Main class for this dialog."""

    def __init__(self, unoObjs, newUserVarPrefix=None):
        self.unoObjs = unoObjs
        self.msgbox = MessageBox(unoObjs)  # calls theLocale.loadUnoObjs()
        userVarPrefix = uservars.Prefix.WORD_LIST
        if newUserVarPrefix:
            userVarPrefix = newUserVarPrefix
        uservars.SettingsDocPreparer(userVarPrefix, unoObjs).prepare()
        self.userVars = uservars.UserVars(
            userVarPrefix, unoObjs.document, logger)
        self.fileItems = FileItemList(WordListFileItem, self.userVars)
        self.punctToRemove = ""
        self.normForm = DEFAULT_NORM_FORM
        self.columnOrder = ColumnOrder(self.userVars)
        self.app = WordList(
            unoObjs, self.fileItems, self.columnOrder, self.userVars)
        self.generateOnClose = False
        self.disposeWhenFinished = True
        self.ok = False
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None
        self.dlgDispose = None

    def dontDisposeWhenFinished(self):
        """If you do this, then call .dlgDispose() when finished."""
        self.disposeWhenFinished = False

    def getResult(self):
        """The dialog result for calling code."""
        return self.ok

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self, self.app)
        self.dlgCtrls = DlgControls(
            self.unoObjs, ctrl_getter, self.evtHandler)
        self.evtHandler.setCtrls(self.dlgCtrls)
        self.columnOrder.loadUserVars()
        self.dlgCtrls.loadValues(
            self.userVars, self.fileItems, self.disposeWhenFinished)
        self.set_listboxColOrder_values()

        self.dlgClose = dlg.endExecute
        self.dlgDispose = dlg.dispose
        dlg.execute()

        if self.generateOnClose:
            self.app.generateList(self.punctToRemove, self.normForm)
        if self.disposeWhenFinished:
            dlg.dispose()

    def fileAdd(self):
        logger.debug(util.funcName('begin'))
        newItem = WordListFileItem(self.userVars)
        dlgFile = DlgWordListFile(newItem, self.unoObjs, self.userVars)
        dlgFile.showDlg()
        ok = dlgFile.getResult()
        dlgFile.dlgDispose()
        if ok:
            logger.debug("Adding item text %s", newItem)
            try:
                self.fileItems.addItem(newItem)
            except exceptions.ChoiceProblem as exc:
                self.msgbox.displayExc(exc)
                return
            self.fileItems.storeUserVars()
            logger.debug("Successfully added.")
            dutil.fill_list_ctrl(
                self.dlgCtrls.listboxFiles, self.fileItems.getItemTextList(),
                str(newItem))
            if self.disposeWhenFinished:
                self.dlgCtrls.btnMakeList.Label = theLocale.getText(
                    "Make List")
        logger.debug("FileAdd end")

    def fileChange(self):
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(
                self.dlgCtrls.listboxFiles, "a file")
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        fileItem = self.fileItems[itemPos]
        logger.debug("Copying item.")
        newItem = fileItem.getDeepCopy()
        dlgFile = DlgWordListFile(newItem, self.unoObjs, self.userVars)
        dlgFile.showDlg()
        ok = dlgFile.getResult()
        dlgFile.dlgDispose()
        if ok:
            logger.debug("Updating item.")
            try:
                self.fileItems.updateItem(itemPos, newItem)
            except exceptions.ChoiceProblem as exc:
                self.msgbox.displayExc(exc)
            self.fileItems.storeUserVars()
            logger.debug("Successfully updated.")

            logger.debug("Removing item at %d", itemPos)
            self.dlgCtrls.listboxFiles.removeItems(itemPos, 1)
            add_at_index = itemPos
            logger.debug("Adding item at %d", add_at_index)
            self.dlgCtrls.listboxFiles.addItem(
                str(newItem), add_at_index)
            self.dlgCtrls.listboxFiles.selectItemPos(add_at_index, True)
        logger.debug("FileUpdate end")

    def fileRemove(self):
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(
                self.dlgCtrls.listboxFiles, "a file")
            self.fileItems.deleteItem(itemPos)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        self.fileItems.storeUserVars()
        self.dlgCtrls.listboxFiles.removeItems(itemPos, 1)
        if len(self.fileItems) == 0 and self.disposeWhenFinished:
            self.dlgCtrls.btnMakeList.Label = theLocale.getText(
                "Make Empty List")
        # Select the next item
        dutil.select_index(self.dlgCtrls.listboxFiles, itemPos)
        logger.debug(util.funcName('end'))

    def moveUp(self):
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(self.dlgCtrls.listboxColOrder)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        changed = self.columnOrder.moveUp(itemPos)
        if changed:
            self.set_listboxColOrder_values(itemPos - 1)

    def moveDown(self):
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(self.dlgCtrls.listboxColOrder)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        changed = self.columnOrder.moveDown(itemPos)
        if changed:
            self.set_listboxColOrder_values(itemPos + 1)

    def makeList(self):
        logger.debug(util.funcName('begin'))
        if len(self.fileItems) == 0 and not self.disposeWhenFinished:
            self.msgbox.display("Please add a file to get words.")
            return
        self.storeUserVars()
        if self.disposeWhenFinished:
            self.generateOnClose = True
        else:
            self.ok = True
        self.dlgClose()

    def set_listboxColOrder_values(self, selItemPos=-1):
        listbox = self.dlgCtrls.listboxColOrder
        selectedValue = ""
        if selItemPos >= 0 and selItemPos < listbox.getItemCount():
            selectedValue = self.columnOrder.getTitle(selItemPos)
        dutil.fill_list_ctrl(
            listbox, self.columnOrder.getTitles(), selectedValue)

    def storeUserVars(self):
        self.punctToRemove = self.dlgCtrls.txtRemovePunct.getText()
        self.userVars.store("Punctuation", self.punctToRemove)
        self.normForm = self.userVars.get('NormForm')
        self.columnOrder.storeUserVars()
        for fileItem in self.fileItems:
            if fileItem.filetype in PhonReader.supportedNames():
                uservars.InterlinTags(self.userVars).loadUserVars()
                break
        for fileItem in self.fileItems:
            if fileItem.filetype in InterlinReader.supportedNames():
                uservars.PhonologyTags(self.userVars).loadUserVars()
                break
Beispiel #12
0
class DlgScriptPractice:
    """Main class for this dialog."""

    # which dialog step (which view)
    STEP_SETTINGS = 1
    STEP_PRACTICE = 2

    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        uservars.SettingsDocPreparer(uservars.Prefix.SCRIPT_PRACTICE,
                                     unoObjs).prepare()
        self.userVars = uservars.UserVars(uservars.Prefix.SCRIPT_PRACTICE,
                                          unoObjs.document, logger)
        self.msgbox = MessageBox(unoObjs)
        self.script = scriptpractice.Script(self.unoObjs)
        self.questions = scriptpractice.PracticeQuestions(
            self.unoObjs, self.script)
        self.stats = scriptpractice.Stats()
        self.wordList = []
        self.whichSource = ""
        self.step = self.STEP_SETTINGS
        self.dlg = None
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        self.dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not self.dlg:
            return
        ctrl_getter = dutil.ControlGetter(self.dlg)
        self.evtHandler = DlgEventHandler(self.userVars, self, self.script,
                                          self.questions)
        self.dlgClose = self.dlg.endExecute
        self.dlgCtrls = DlgControls(ctrl_getter, self.evtHandler, self.script,
                                    self.dlgClose, self.msgbox)
        self.dlg.getModel().Step = self.step
        self.evtHandler.setCtrls(self.dlgCtrls)
        self.dlgCtrls.loadValues(self.userVars, self.questions)

        ## Display the dialog

        self.dlg.execute()
        if self.step == self.STEP_SETTINGS:
            self.getFormResults()
        self.dlg.dispose()

    def resetChars(self):
        logger.debug(util.funcName('begin'))
        self.script.setCharsetFromScript()
        self.dlgCtrls.txtCharset.setText(self.script.getCharsetString())

    def chooseFiles(self):
        logger.debug(util.funcName('begin'))
        dlgFileList = DlgWordList(self.unoObjs, self.userVars.VAR_PREFIX)
        dlgFileList.dontDisposeWhenFinished()
        dlgFileList.showDlg()
        if not dlgFileList.getResult():
            dlgFileList.dlgDispose()
            return
        fileItems = dlgFileList.fileItems
        listApp = dlgFileList.app
        punctToRemove = dlgFileList.punctToRemove
        dlgFileList.dlgDispose()
        if len(fileItems) > 0:
            listApp.generateList(punctToRemove,
                                 dlgFileList.normForm,
                                 outputToCalc=False)
            self.wordList = listApp.words[:]

    def switch(self):
        logger.debug(util.funcName('begin'))
        if self.step == self.STEP_SETTINGS:
            self.getFormResults()
            if self.whichSource == "Generate":
                if not self.script.scriptNameIsSet():
                    self.msgbox.display("Please select a script.")
                    return
            elif self.whichSource == "Wordlist":
                if len(self.wordList) == 0:
                    self.msgbox.display(
                        "Please load a word list by clicking on the "
                        "Files... button.  When file settings are "
                        "finished, click Get words.")
                    return
            self.step = self.STEP_PRACTICE
            self.dlg.getModel().Step = self.step  # change the dialog
            self.dlgCtrls.btnSwitch.Label = theLocale.getText(
                "Back to Settings")
            self.dlg.setTitle(theLocale.getText("Script Practice"))
            self.dlgCtrls.btnNextWord.setFocus()
            self.showNextQuestion()
        elif self.step == self.STEP_PRACTICE:
            self.step = self.STEP_SETTINGS
            self.dlg.getModel().Step = self.step  # change the dialog
            self.dlgCtrls.btnSwitch.Label = theLocale.getText("Go to Practice")
            self.dlg.setTitle(theLocale.getText("Script Practice - Settings"))
            self.resetStats()

    def resetStats(self):
        self.stats.resetStats()
        self.dlgCtrls.dispCorrect.setText("0")
        self.dlgCtrls.dispIncorrect.setText("0")
        self.dlgCtrls.dispNumWords.setText("0")
        self.dlgCtrls.dispAvgTime.setText("0")

    def getFormResults(self):
        """Reads form fields and sets app configuration."""
        logger.debug(util.funcName('begin'))
        config = scriptpractice.PracticeSettings()
        charsetString = self.dlgCtrls.txtCharset.getText()
        self.script.setCharsetFromInput(charsetString)
        self.userVars.store("CharSet", charsetString)
        self.questions.setConfig(config, self.wordList)

        ## Radio buttons and the corresponding combo box selection

        self.whichSource = ""
        if self.dlgCtrls.optGenerate.getState():
            self.whichSource = "Generate"
        elif self.dlgCtrls.optWordlist.getState():
            self.whichSource = "Wordlist"
        self.userVars.store("WhichSource", config.whichSource)
        config.whichSource = self.whichSource

        ## Font name and size

        fontName = self.dlgCtrls.comboFont.getText()
        if fontName == "(None)":
            fontName = None
        fontSize = FontSize(default=30.0)
        fontSize.loadCtrl(self.dlgCtrls.txtFontSize)
        self.userVars.store('Font', fontName)
        self.userVars.store('FontSize', fontSize.getString())
        self.userVars.store("Script", self.dlgCtrls.comboScript.getText())
        self.userVars.store("OnlyKnownFonts",
                            str(self.dlgCtrls.chkKnownFonts.getState()))

        ## Syllable and Word size

        strval = self.dlgCtrls.listSyllableSize.getSelectedItem()
        try:
            val = int(strval)
        except ValueError:
            val = 2
        if val < 1 or val > 3:
            val = 2
        config.syllableSize = val
        self.userVars.store("SyllableSize", str(val))

        strval = self.dlgCtrls.txtNumSyllables.getText()
        try:
            val = int(strval)
        except ValueError:
            val = 1
            self.dlgCtrls.txtNumSyllables.setText(str(val))
        if val < 1 or val > 9:
            val = 1
            self.dlgCtrls.txtNumSyllables.setText(str(val))
        config.numSyllables = val
        self.userVars.store("NumSyllables", str(val))

        strval = self.dlgCtrls.txtNumWords.getText()
        try:
            val = int(strval)
        except ValueError:
            val = 1
            self.dlgCtrls.txtNumWords.setText(str(val))
        if val < 1 or val > 50:
            val = 1
            self.dlgCtrls.txtNumWords.setText(str(val))
        config.numWords = val
        self.userVars.store("NumWords", str(val))
        logger.debug(util.funcName('end'))

    def showNextQuestion(self):
        logger.debug(util.funcName('begin'))
        nextQuestion = self.questions.getNextQuestion()
        self.dlgCtrls.txtQuestion.setText(nextQuestion)
        self.stats.newQuestion()
        self.prepareAnswerBox()
        logger.debug(util.funcName('end'))

    def prepareAnswerBox(self):
        self.dlgCtrls.txtAnswer.setText("")
        self.dlgCtrls.txtAnswer.getModel().BackgroundColor = \
            int("FFFFFF", 16)  # White
        self.dlgCtrls.txtAnswer.setEditable(True)
        self.dlgCtrls.txtAnswer.setFocus()

    def answerChanged(self):
        if self.questions.answerIsReady(self.dlgCtrls.txtAnswer.getText()):
            self.checkAnswer()

    def checkAnswer(self):
        """Determine if the answer is correct."""
        if self.questions.waitForSpace:
            given = self.dlgCtrls.txtAnswer.getText().rstrip()
            if given != self.dlgCtrls.txtAnswer.getText():
                # Reset the text without the newline so it doesn't look funny.
                # Warning: This line can cause a crash, but hopefully we avoid
                # it by the "if" statement.
                self.dlgCtrls.txtAnswer.setText(given)
        else:
            given = self.dlgCtrls.txtAnswer.getText()
        if self.questions.questionMatches(given):
            self.dlgCtrls.dispCorrect.setText(self.stats.answerCorrect())
            self.dlgCtrls.txtAnswer.getModel().BackgroundColor = \
                int("00CC00", 16)  # Green
            self.dlgCtrls.btnNextWord.setFocus()
        else:
            self.dlgCtrls.dispIncorrect.setText(self.stats.answerIncorrect())
            self.dlgCtrls.txtAnswer.getModel().BackgroundColor = \
                int("FF0000", 16)  # Red
            self.dlgCtrls.btnRetry.setFocus()
        self.dlgCtrls.dispNumWords.setText(self.stats.getTotalQuestions())
        self.dlgCtrls.dispAvgTime.setText(self.stats.getAvgTime())
        self.dlgCtrls.txtAnswer.setEditable(False)
Beispiel #13
0
class WordlistIO:
    def __init__(self, calcUnoObjs, colOrder):
        self.unoObjs = calcUnoObjs
        self.colOrder = colOrder
        self.msgbox = MessageBox(self.unoObjs)
        self.progressRanges = None
        self.sheet = None
        self.listDoc = None

    def getMsgbox(self):
        """After outputList(), self.msgbox will be for the spreadsheet."""
        return self.msgbox

    def outputList(self, wordList, progressBarWriter):
        """Sends output to the Calc spreadsheet.
        Takes a list of app.wordlist.WordInList.
        """
        logger.debug(util.funcName('begin'))
        outputter = SpreadsheetOutput(self.unoObjs)
        self.listDoc = outputter.createSpreadsheet()
        self.msgbox = MessageBox(self.listDoc)
        self.sheet = self.listDoc.sheets.getByIndex(0)

        progressBarCalc = ProgressBar(self.listDoc, "Generating List...")
        progressBarCalc.show()
        self.progressRanges = ProgressRanges(
            [progressBarWriter, progressBarCalc])
        self.progressRanges.initRanges(progressBarWriter.getPercent() + 20, 95,
                                       len(wordList))
        self.progressRanges.updateStart()
        try:
            self._outputList(wordList)
            self.progressRanges.updateFinishing()
        finally:
            self.progressRanges.closeBars()
        logger.debug(util.funcName('end'))

    def _outputList(self, wordList):
        headingRow = 0  # first row
        numberFormat = 0  # General format
        for colNum, heading in enumerate(self.colOrder.getTitles()):
            cell = self.sheet.getCellByPosition(colNum, headingRow)
            cell.setFormula("")
            cell.setPropertyValue("NumberFormat", numberFormat)
            cell.setString(theLocale.getText(heading))

        cellFreeze = self.sheet.getCellByPosition(0, 1)
        self.listDoc.controller.select(cellFreeze)
        self.unoObjs.dispatcher.executeDispatch(self.listDoc.frame,
                                                ".uno:FreezePanes", "", 0, ())

        CHUNK_SIZE = 25  # make this value bigger or smaller for optimization
        #CHUNK_SIZE = 1  # useful for debugging
        for word_i1 in range(0, len(wordList), CHUNK_SIZE):
            word_i2 = word_i1 + CHUNK_SIZE - 1
            if word_i2 >= len(wordList):
                word_i2 = len(wordList) - 1
            self._fillInData(wordList, word_i1, word_i2)

    def _fillInData(self, wordList, word_i1, word_i2):
        data = []
        for word_i in range(word_i1, word_i2 + 1):
            word = wordList[word_i]
            colOrd = self.colOrder  # shorthand variable name
            colOrd.resetRowData()
            colOrd.setRowVal('colWord', word.text)
            colOrd.setRowVal('colOccur', word.occurrences)
            colOrd.setRowVal('colOk', word.isCorrect_str())
            colOrd.setRowVal('colChange', word.correction)
            colOrd.setRowVal('colSrc', word.sources_str())
            data.append(colOrd.getRowTuple())

        row1 = word_i1 + 2  # start at second row, so index 0 is row 2
        row2 = word_i2 + 2
        col2 = chr(ord('A') + len(self.colOrder.COLUMNS) - 1)
        rangeName = "A%d:%s%d" % (row1, col2, row2)
        logger.debug("Adding %d rows to range %s", len(data), rangeName)
        #logger.debug(repr(data))
        oRange = self.sheet.getCellRangeByName(rangeName)
        try:
            oRange.setDataArray(tuple(data))
        except RuntimeException as exc:
            raise exceptions.FileAccessError(
                "There was a problem while writing the list.\n\n%s", exc)
        self.progressRanges.update(word_i1)

    def readList(self):
        """Expects input spreadsheet to have columns generated by
        word list app,
        including word, similar words, source, isCorrect, et cetera.
        Returns a list of app.wordlist.WordInList.
        """
        logger.debug(util.funcName('begin'))

        colOrd = self.colOrder  # shorthand variable name
        colLetterWord = colOrd.getColLetter('colWord')
        reader = SpreadsheetReader(self.unoObjs)
        stringList = reader.getColumnStringList(colLetterWord, True)
        if len(stringList) == 0:
            logger.debug("No data found.")
            return []
        row1 = 2  # first row is heading, second row is beginning of data
        row2 = row1 + len(stringList) - 1
        rangeName = "%s%d:%s%d" % ('A', row1, colOrd.maxColLetter(), row2)
        try:
            oRange = self.unoObjs.sheet.getCellRangeByName(rangeName)
            rowTuples = oRange.getDataArray()
        except RuntimeError as exc:
            self.msgbox.display("Error reading the list.\n\n%s", str(exc))
            return []
        if len(rowTuples) == 0:
            logger.debug("Could not get data.")
            return []

        datalist = []
        for rowTuple in rowTuples:
            colOrd.setRowTuple(rowTuple)
            wordInList = WordInList()
            wordInList.text = colOrd.getRowVal('colWord')
            wordInList.occurrences = colOrd.getRowVal('colOccur')
            wordInList.correction = colOrd.getRowVal('colChange')
            wordInList.converted1 = colOrd.getRowVal('colConv1')
            wordInList.converted2 = colOrd.getRowVal('colConv2')
            wordInList.setSources(colOrd.getRowVal('colSrc'))
            wordInList.setSimilarWords(colOrd.getRowVal('colSimilar'))
            wordInList.setIsCorrect(colOrd.getRowVal('colOk'))
            datalist.append(wordInList)
        return datalist
class DlgSpellingStep:
    """Main class for this dialog."""
    def __init__(self, calcUnoObjs):
        self.unoObjs = calcUnoObjs
        finder = uservars.SettingsDocFinder(uservars.Prefix.SPELLING,
                                            self.unoObjs)
        writerUnoObjs = finder.getWriterDoc()
        self.userVars = uservars.UserVars(uservars.Prefix.SPELLING,
                                          writerUnoObjs.document, logger)
        self.app = SpellingStepper(self.unoObjs, self.userVars)
        self.msgbox = MessageBox(self.unoObjs)
        self.maxRow = -1
        self.scrollbarAlreadyMoved = False
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(self.unoObjs, ctrl_getter, self.evtHandler)
        self.evtHandler.setCtrls(self.dlgCtrls)

        # This fixes two problems, at least on Ubuntu:
        # - bar on scrollbar control doesn't show in viewable area
        # - cannot set background color of text box
        dlg.getPeer().setProperty("NativeWidgetLook", False)

        self.dlgCtrls.loadValues(self.userVars, self.app)

        ## Go to first row

        self.dlgCtrls.lblWordText.setText("")
        self.dlgCtrls.lblConvertedText.setText("")
        dataFound = self.loadData()
        if not dataFound:
            self.msgbox.display("No data found.")
            dlg.dispose()
            return
        startingRow = "2"
        varname = "CurrentRow"
        if not self.userVars.isEmpty(varname):
            startingRow = self.userVars.get(varname)
        self.dlgCtrls.txtRowNum.setText(startingRow)  # row 1 contains headings
        self.gotoRow()

        ## Display the dialog

        self.dlgClose = dlg.endExecute
        dlg.execute()

        dlg.dispose()

    def loadData(self):
        dataLen = self.app.loadData()
        logger.debug("Data len: %d", dataLen)
        self.maxRow = dataLen + 1  # skip first row
        self.dlgCtrls.scrollbarRow.setMaximum(self.maxRow)
        self.dlgCtrls.scrollbarRow.setBlockIncrement(dataLen // 20)
        return dataLen > 0

    def gotoRow(self):
        """Go to a particular row in the spreadsheet and display its
        information in the dialog.
        """
        logger.debug(util.funcName('begin'))
        txtVal = self.dlgCtrls.txtRowNum.getText()
        lightRedColor = int("FF8888", 16)
        if txtVal.strip() == '':
            self.dlgCtrls.txtRowNum.getModel().BackgroundColor = lightRedColor
            return
        try:
            rowNum = int(txtVal)
        except ValueError:
            logger.warning("Couldn't parse '%s' as integer.", txtVal)
            self.dlgCtrls.txtRowNum.getModel().BackgroundColor = lightRedColor
            return
        if rowNum < 2 or rowNum > self.maxRow:
            self.dlgCtrls.txtRowNum.getModel().BackgroundColor = lightRedColor
            return
        self.dlgCtrls.txtRowNum.getModel().setPropertyToDefault(
            "BackgroundColor")
        if self.scrollbarAlreadyMoved:
            self.scrollbarAlreadyMoved = False
        else:
            self.dlgCtrls.scrollbarRow.setValue(rowNum)

        wordInList = self.app.gotoRow(rowNum)
        self.userVars.store("CurrentRow", str(rowNum))
        self.dlgCtrls.lblWordText.setText(wordInList.text)
        self.dlgCtrls.lblConvertedText.setText(wordInList.converted1)
        if wordInList.correction:
            self.dlgCtrls.txtCorrection.setText(wordInList.correction)
        else:
            self.dlgCtrls.txtCorrection.setText(wordInList.text)
        dutil.set_tristate_checkbox(self.dlgCtrls.chkIsCorrect,
                                    wordInList.isCorrect)
        dutil.fill_list_ctrl(self.dlgCtrls.listSimilarWords,
                             wordInList.similarWords)
        suggestions = []
        if self.app.wantSuggestions:
            suggestions = self.app.getSuggestions(wordInList.similarWords)
        dutil.fill_list_ctrl(self.dlgCtrls.listSuggestions, suggestions)
        logger.debug(util.funcName('end'))

    def enableDisable(self):
        newVal = self.dlgCtrls.txtCorrection.getText()
        wordInList = self.app.currentRowData()
        if newVal == wordInList.text or newVal == wordInList.correction:
            self.dlgCtrls.btnSetCorrection.getModel().Enabled = False
        else:
            self.dlgCtrls.btnSetCorrection.getModel().Enabled = True

    def setCorrection(self):
        logger.debug("Setting Correction...")
        if self.dlgCtrls.chkIsCorrect.getState() == dutil.CHECKED:
            ok = self.msgbox.displayOkCancel(
                "This word was already set to correct.  Change anyway?")
            if not ok:
                return
        correctionStr = self.dlgCtrls.txtCorrection.getText()
        self.app.setCorrection(correctionStr)
        if correctionStr.strip() == "":
            self.app.setIsCorrect(True)
            self.dlgCtrls.chkIsCorrect.setState(dutil.CHECKED)
        else:
            self.app.setIsCorrect(False)
            self.dlgCtrls.chkIsCorrect.setState(dutil.UNCHECKED)
        self.enableDisable()

    def checkSuggestions(self):
        self.userVars.store("GiveSuggestions",
                            str(self.dlgCtrls.chkSuggestions.getState()))
        if self.dlgCtrls.chkSuggestions.getState() == 1:
            self.app.wantSuggestions = True
        else:
            self.app.wantSuggestions = False
        self.gotoRow()
class DlgWordListFile:
    """Main class for this dialog."""
    def __init__(self, fileItem, unoObjs, userVars):
        """fileItem is expected to be of type WordListFileItem.
        It will be modified by reference,
        so the new value can be used when this dialog is finished.
        """
        self.fileItem = fileItem
        self.filetype = fileItem.filetype
        self.thingsToGrab = [
            copy.copy(whatToGrab) for whatToGrab in fileItem.thingsToGrab
        ]
        logger.debug("len(self.thingsToGrab) = %d", len(self.thingsToGrab))
        self.unoObjs = unoObjs
        self.userVars = userVars
        self.msgbox = MessageBox(unoObjs)  # calls theLocale.loadUnoObjs()
        self.ok = False
        self.titles = None
        self.paraStyleNames = []
        self.charStyleNames = []
        self.fileTypeDict = dict()
        self.fileTypeNames = []
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None
        self.dlgDispose = None

    def getResult(self):
        return self.ok

    def showDlg(self):
        logger.debug(util.funcName('begin', obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(self.unoObjs, ctrl_getter, self.evtHandler)
        self.evtHandler.setCtrls(self.dlgCtrls)

        styleNames = styles.getListOfStyles('ParagraphStyles', self.unoObjs)
        self.paraStyleNames = dict(styleNames)
        paraStyleDispNames = tuple([dispName for dispName, name in styleNames])

        styleNames = styles.getListOfStyles('CharacterStyles', self.unoObjs)
        self.charStyleNames = dict(styleNames)
        charStyleDispNames = tuple([dispName for dispName, name in styleNames])
        self.dlgCtrls.loadValues(paraStyleDispNames,
                                 charStyleDispNames, self.fileItem,
                                 self.getTypesTuple(), self.fileTypeDict,
                                 self.fillFieldList)
        self.dlgCtrls.enableDisable(self.filetype)

        self.dlgClose = dlg.endExecute
        self.dlgDispose = dlg.dispose
        logger.debug(util.funcName('end', obj=self))
        dlg.execute()

    def fillFieldList(self):
        """Fills listWhatToGrab based on self.filetype."""
        count = self.dlgCtrls.listWhatToGrab.getItemCount()
        self.dlgCtrls.listWhatToGrab.removeItems(0, count)
        self.titles = [("", "")]
        if self.filetype in PhonReader.supportedNames():
            self.titles.extend(lingex_structs.LingPhonExample.GRAB_FIELDS)
        elif self.filetype in InterlinReader.supportedNames():
            self.titles.extend(lingex_structs.LingGramExample.GRAB_FIELDS)
        elif self.filetype in DocReader.supportedNames():
            self.titles.append((WhatToGrab.WHOLE_DOC, "Whole Document"))
        elif self.filetype in CalcFileReader.supportedNames():
            for char in string.ascii_uppercase:
                self.titles.append(
                    (char, "%s %s" % (theLocale.getText("Column"), char)))
        if len(self.titles) > 1:
            stringList = [
                theLocale.getText(display)
                for dummy_key, display in self.titles
            ]
            self.dlgCtrls.listWhatToGrab.addItems(tuple(stringList), 0)

    def useCurrent(self):
        logger.debug(util.funcName('begin'))
        url = self.unoObjs.document.getURL()
        if not url:
            self.msgbox.display("Please save the current document first.")
            return
        syspath = uno.fileUrlToSystemPath(url)
        self.dlgCtrls.fileControl.setText(syspath)
        dummy, title = DocReader.SUPPORTED_FORMATS[0]
        self.dlgCtrls.listboxFileType.selectItem(title, False)
        self.dlgCtrls.listboxFileType.selectItem(title, True)

    def selectWritingSys(self):
        logger.debug(util.funcName('begin'))
        filepath = self.dlgCtrls.fileControl.getText()
        defaultCode = self.dlgCtrls.txtWS.getText()
        dlgWS = DlgWritingSystem(defaultCode, self.unoObjs)
        dlgWS.readFile(filepath)
        dlgWS.showDlg()
        writingSystem = dlgWS.getResult()
        dlgWS.call_dispose()
        self.dlgCtrls.txtWS.setText(writingSystem.internalCode)

    def addItem(self):
        """Handle button press.  Add whatever form field was changed."""
        logger.debug(
            util.funcName('begin',
                          args="%d control(s) changed." %
                          len(self.dlgCtrls.ctrlsChanged)))
        something_to_add = False
        for ctrlName, ctrl in self.dlgCtrls.ctrlsChanged.items():
            logger.debug(ctrlName)
            if ctrl == self.dlgCtrls.listWhatToGrab:
                newObj = self.fieldItemToAdd(ctrl.getSelectedItemPos())
            else:
                newObj = self.formItemToAdd(ctrlName, ctrl)
            if (newObj.grabType != WhatToGrab.UNSPECIFIED
                    and newObj.whichOne.strip() != ""):
                self.addWhatToGrab(newObj)
                something_to_add = True
        if not something_to_add:
            self.msgbox.display("Please select or enter something to find.")
        self.dlgCtrls.clearWhatToFind()
        logger.debug(util.funcName('end'))

    def fieldItemToAdd(self, itemPos):
        """Create a field item to be added."""
        newObj = WhatToGrab(self.userVars)
        if itemPos >= 0:
            key, dummy_display = self.titles[itemPos]
            newObj.whichOne = key
        if self.filetype in CalcFileReader.supportedNames():
            newObj.grabType = WhatToGrab.COLUMN
        elif self.filetype in DocReader.supportedNames():
            newObj.grabType = WhatToGrab.PART
        else:
            newObj.grabType = WhatToGrab.FIELD
        logger.debug(
            util.funcName('end', args=(newObj.whichOne, newObj.grabType)))
        return newObj

    def formItemToAdd(self, ctrlName, ctrl):
        """Create a form item to be added."""
        newObj = WhatToGrab(self.userVars)
        newObj.whichOne = ctrl.getText()
        if ctrlName == self.dlgCtrls.comboParaStyle.getModel().Name:
            # use display name to search
            newObj.grabType = WhatToGrab.PARASTYLE
            displayName = ctrl.getText()
            if displayName in self.paraStyleNames:
                newObj.whichOne = self.paraStyleNames[displayName]
        elif ctrlName == self.dlgCtrls.comboCharStyle.getModel().Name:
            newObj.grabType = WhatToGrab.CHARSTYLE
            displayName = ctrl.getText()
            if displayName in self.charStyleNames:
                newObj.whichOne = self.charStyleNames[displayName]
        elif ctrlName == self.dlgCtrls.comboFont.getModel().Name:
            newObj.grabType = WhatToGrab.FONT
            newObj.fontType = 'Western'
            if self.dlgCtrls.optFontTypeComplex.getState() == 1:
                newObj.fontType = 'Complex'
            elif self.dlgCtrls.optFontTypeAsian.getState() == 1:
                newObj.fontType = 'Asian'
        elif ctrlName == self.dlgCtrls.txtSFM.getModel().Name:
            newObj.grabType = WhatToGrab.SFM
        logger.debug(
            util.funcName('end', args=(newObj.whichOne, newObj.grabType)))
        return newObj

    def addWhatToGrab(self, newObj):
        """Add newObj to the list."""
        logger.debug(
            util.funcName('begin',
                          args="len(self.thingsToGrab) = %d" %
                          len(self.thingsToGrab)))
        newObj.whichOne = newObj.whichOne.strip()
        for whatToGrab in self.thingsToGrab:
            if str(whatToGrab) == str(newObj):
                self.msgbox.display("%s is already in the list.",
                                    str(whatToGrab))
                return
        self.thingsToGrab.append(newObj)
        self.thingsToGrab.sort(key=str)

        stringList = [str(df) for df in self.thingsToGrab]
        dutil.fill_list_ctrl(self.dlgCtrls.listboxFields, stringList,
                             str(newObj))
        logger.debug(
            util.funcName('end',
                          args="len(self.thingsToGrab) = %d" %
                          len(self.thingsToGrab)))

    def removeItem(self):
        """Handle button press."""
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(self.dlgCtrls.listboxFields)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        del self.thingsToGrab[itemPos]
        self.dlgCtrls.listboxFields.removeItems(itemPos, 1)
        # Select the next item
        dutil.select_index(self.dlgCtrls.listboxFields, itemPos)
        logger.debug(
            util.funcName('end',
                          args="len(self.thingsToGrab) = %d" %
                          len(self.thingsToGrab)))

    def doOk(self):
        """Handle button press."""
        logger.debug(
            util.funcName('begin',
                          args="len(self.thingsToGrab) = %d" %
                          len(self.thingsToGrab)))
        if (len(self.thingsToGrab) == 0
                and self.filetype not in ['spellingStatus']):
            ok = self.msgbox.displayOkCancel(
                "You did not specify anything to find.  Continue anyway?")
            if not ok:
                return
        for whatToGrab in self.thingsToGrab:
            if whatToGrab.whichOne == WhatToGrab.WHOLE_DOC:
                if len(self.thingsToGrab) > 1:
                    self.msgbox.display(
                        "'Whole Document' must be the only thing to find.")
                    return

        self.fileItem.filepath = self.dlgCtrls.fileControl.getText()
        self.fileItem.filetype = self.filetype
        self.fileItem.writingSystem = self.dlgCtrls.txtWS.getText()
        self.fileItem.thingsToGrab = self.thingsToGrab
        logger.debug("len(self.thingsToGrab) = %d", len(self.thingsToGrab))
        self.fileItem.includeMisspellings = (
            self.dlgCtrls.checkboxMiss.getState() == 1)
        self.fileItem.skipFirstRow = (
            self.dlgCtrls.checkboxSkipRow.getState() == 1)
        self.fileItem.splitByWhitespace = (
            self.dlgCtrls.checkboxSplit.getState() == 1)

        self.ok = True
        self.dlgClose()

    def getTypesTuple(self):
        """Get file types that can be read for a word list.
        Returns a tuple suitable for filling a list box.

        Note: This method cannot be named getTypes(), apparently because that
        name is used in an unohelper.Base interface, XTypeProvider.
        Update 02-Jul-2015: This is probably only the case if this class
        inherits from unohelper.Base, which it no longer does.
        """
        fileTypes = (DocReader.SUPPORTED_FORMATS +
                     CalcFileReader.SUPPORTED_FORMATS +
                     WordsReader.SUPPORTED_FORMATS +
                     PhonReader.SUPPORTED_FORMATS +
                     InterlinReader.SUPPORTED_FORMATS +
                     SFM_Reader.SUPPORTED_FORMATS)
        self.fileTypeDict = dict(fileTypes)
        self.fileTypeNames, titles = zip(*fileTypes)
        return titles
class AbbrevList(ItemList, Syncable):
    """Maintains a list of abbreviations."""

    ITEM_DESC_GENERIC = "an abbreviation"
    ITEM_DESC_SPECIFIC = "Abbreviation"

    def __init__(self, unoObjs, userVars):
        ItemList.__init__(self)
        Syncable.__init__(self, userVars)
        self.msgbox = MessageBox(unoObjs)

    def getUniqueList(self):
        """Return a lowercased set of the abbreviations."""
        newList = [item.abbrevText.lower() for item in self.itemList]
        # make the list unique
        newList = list(set(newList))
        return newList

    def loadUserVars(self):
        logger.debug(util.funcName())
        self.itemList = []
        varname = "Abbreviations"
        abbrevs_repr = self.userVars.get(varname)
        if abbrevs_repr == "":
            self.loadDefaultList()
            return

        ## Verify the string is correctly formed, like "(a,b,c,d)(e,f,g,h)"
        if not re.search(r'^(?:\(.*,.*,.*,.*\))*$', abbrevs_repr):
            self.msgbox.display(
                self.noUserVarData(self.userVars.VAR_PREFIX + varname))
            return

        ## Split by parenthesis into tuples.
        for abbrev_repr in re.split(r'(?<!\\)[()]', abbrevs_repr):
            if abbrev_repr == "":
                # Splitting "(a)(b)" by () results in three empty strings:
                # initially before "(", medially between ")(",
                # and finally after ")".  Just ignore these.
                continue
            newAbbrev = Abbrev()
            newAbbrev.loadFromRepr(abbrev_repr)
            self.itemList.append(newAbbrev)
        self.sortItems()

    def storeUserVars(self):
        """The string will look like:
        (abbrev1,fullName1,True,0)(abbrev2,fullName2,True,0)
        """
        if not self.changed:
            return
        logger.debug(util.funcName())

        abbrevs_repr = "".join(
            [repr(abbrev) for abbrev in self.itemList])
        self.userVars.store("Abbreviations", abbrevs_repr)
        self.changed = False
        logger.debug(util.funcName('end'))

    def loadDefaultList(self):
        """Loads the default list, taken from Leipzig Glossing Rules."""
        logger.debug(util.funcName())
        self.itemList = []
        defaultAbbrevs = [
            ("1", "first person"),
            ("2", "second person"),
            ("3", "third person"),
            ("A", "agent-like argument of canonical transitive verb"),
            ("ABL", "ablative"),
            ("ABS", "absolutive"),
            ("ACC", "accusative"),
            ("ADJ", "adjective"),
            ("ADV", "adverb(ial)"),
            ("AGR", "agreement"),
            ("ALL", "allative"),
            ("ANTIP", "antipassive"),
            ("APPL", "applicative"),
            ("ART", "article"),
            ("AUX", "auxiliary"),
            ("BEN", "benefactive"),
            ("CAUS", "causative"),
            ("CLF", "classifier"),
            ("COM", "comitative"),
            ("COMP", "complementizer"),
            ("COMPL", "completive"),
            ("COND", "conditional"),
            ("COP", "copula"),
            ("CVB", "converb"),
            ("DAT", "dative"),
            ("DECL", "declarative"),
            ("DEF", "definite"),
            ("DEM", "demonstrative"),
            ("DET", "determiner"),
            ("DIST", "distal"),
            ("DISTR", "distributive"),
            ("DU", "dual"),
            ("DUR", "durative"),
            ("ERG", "ergative"),
            ("EXCL", "exclusive"),
            ("F", "feminine"),
            ("FOC", "focus"),
            ("FUT", "future"),
            ("GEN", "genitive"),
            ("IMP", "imperative"),
            ("INCL", "inclusive"),
            ("IND", "indicative"),
            ("INDF", "indefinite"),
            ("INF", "infinitive"),
            ("INS", "instrumental"),
            ("INTR", "intransitive"),
            ("IPFV", "imperfective"),
            ("IRR", "irrealis"),
            ("LOC", "locative"),
            ("M", "masculine"),
            ("N", "neuter"),
            ("N", "non- (e.g. NSG nonsingular, NPST nonpast)"),
            ("NEG", "negation, negative"),
            ("NMLZ", "nominalizer/nominalization"),
            ("NOM", "nominative"),
            ("OBJ", "object"),
            ("OBL", "oblique"),
            ("P", "patient-like argument of canonical transitive verb"),
            ("PASS", "passive"),
            ("PFV", "perfective"),
            ("PL", "plural"),
            ("POSS", "possessive"),
            ("PRED", "predicative"),
            ("PRF", "perfect"),
            ("PRS", "present"),
            ("PROG", "progressive"),
            ("PROH", "prohibitive"),
            ("PROX", "proximal/proximate"),
            ("PST", "past"),
            ("PTCP", "participle"),
            ("PURP", "purposive"),
            ("Q", "question particle/marker"),
            ("QUOT", "quotative"),
            ("RECP", "reciprocal"),
            ("REFL", "reflexive"),
            ("REL", "relative"),
            ("RES", "resultative"),
            ("S", "single argument of canonical intransitive verb"),
            ("SBJ", "subject"),
            ("SBJV", "subjunctive"),
            ("SG", "singular"),
            ("TOP", "topic"),
            ("TR", "transitive"),
            ("VOC", "vocative")]
        for defaultTuple in defaultAbbrevs:
            newAbbrev = Abbrev()
            newAbbrev.abbrevText, newAbbrev.fullName = defaultTuple
            self.itemList.append(newAbbrev)
        self.sortItems()
        self.changed = True
        self.storeUserVars()

    def sortItems(self):
        """Sort by abbreviation."""
        logger.debug(util.funcName())
        self.itemList.sort()

    def setOccurrences(self, itemPos, newValue):
        self.itemList[itemPos].occurrences = newValue
        self.changed = True

    def changeAllCaps(self):
        """Rotate between three options:
        All caps, all lower, and first char upper.
        Returns True if change is made.
        """
        allCapsNew = "UPPER"
        allCapsPrev = self.userVars.get("AllCaps")
        if allCapsPrev == "":
            allCapsPrev = "UPPER"
        if allCapsPrev == "UPPER":
            allCapsNew = "lower"
        elif allCapsPrev == "lower":
            allCapsNew = "Capitalized"
        elif allCapsPrev == "Capitalized":
            allCapsNew = "UPPER"

        result = self.msgbox.displayOkCancel(
            "This will change the case of the entire list from '%s' "
            "to '%s.' Continue?", allCapsPrev, allCapsNew)
        if not result:
            logger.debug("Not changing caps.")
            return False
        logger.debug("Changing caps.")

        for abbr in self.itemList:
            if allCapsNew == "UPPER":
                abbr.abbrevText = abbr.abbrevText.upper()
            elif allCapsNew == "lower":
                abbr.abbrevText = abbr.abbrevText.lower()
            elif allCapsNew == "Capitalized":
                abbr.abbrevText = abbr.abbrevText.capitalize()
            else:
                self.msgbox.display("Unexpected new value %s.", allCapsNew)
                return False

        self.changed = True
        self.userVars.store("AllCaps", allCapsNew)
        return True
class WordList:

    def __init__(self, writerUnoObjs, fileItems, columnOrder, userVars):
        self.unoObjs = writerUnoObjs
        self.fileItems = fileItems    # FileItemList of WordListFileItem
        self.columnOrder = columnOrder
        self.userVars = userVars
        self.msgbox = MessageBox(self.unoObjs)
        self.words = []
        self.progressBar = None

    def generateList(self, punctToRemove, normForm, outputToCalc=True):
        """Harvest words from various files.
        If outputToCalc is True, then output a word list in Calc.
        """
        logger.debug(util.funcName('begin'))
        all_words_read = []
        self.progressBar = ProgressBar(self.unoObjs, "Reading...")
        self.progressBar.show()
        self.progressBar.updateBeginning()
        progressRange = ProgressRange(
            ops=len(self.fileItems), pbar=self.progressBar)
        try:
            for fileItemIndex, fileItem in enumerate(self.fileItems):
                try:
                    new_words = self._harvestWords(fileItem)
                    all_words_read.extend(new_words)
                    logger.debug("Word count: %d", len(all_words_read))
                except (exceptions.DataNotFoundError,
                        exceptions.FileAccessError) as exc:
                    self.msgbox.displayExc(exc)
                progressRange.update(fileItemIndex)
            self.progressBar.updateFinishing()
        finally:
            self.progressBar.close()
        self.progressBar = ProgressBar(self.unoObjs, "Sorting...")
        self.progressBar.show()
        self.progressBar.updateBeginning()
        try:
            splitByWhitespace = True
            if len(self.fileItems) > 0:
                splitByWhitespace = self.fileItems[0].splitByWhitespace
            self.words = organizeList(
                all_words_read, punctToRemove, splitByWhitespace, normForm,
                self.progressBar)
            self.progressBar.updateFinishing()
        finally:
            self.progressBar.close()
        if self.words or len(self.fileItems) == 0:
            if outputToCalc:
                self.progressBar = ProgressBar(
                    self.unoObjs, "Generating List...")
                self.progressBar.show()
                self.progressBar.updateBeginning()
                try:
                    self._generateCalcList()
                    self.progressBar.updateFinishing()
                finally:
                    self.progressBar.close()
            else:
                self.msgbox.display("Found %d words.", len(self.words))
        else:
            self.msgbox.display("Did not find any words for the list.")

    def _harvestWords(self, fileItem):
        """Harvest words from the specified file."""
        fileType = fileItem.filetype  # short variable name
        logger.debug(util.funcName(args=fileType))
        words = []
        if fileType in WordsReader.supportedNames():
            reader = WordsReader(fileItem, self.unoObjs)
            words = reader.read()
        elif fileType in SFM_Reader.supportedNames():
            reader = SFM_Reader(fileItem, self.unoObjs)
            words = reader.read()
        elif fileType in InterlinReader.supportedNames():
            config = fileitemlist.InterlinInputSettings(self.userVars)
            config.showMorphLine2 = True
            config.separateMorphColumns = True
            lingExFileItem = fileitemlist.LingExFileItem(self.userVars)
            lingExFileItem.filepath = fileItem.filepath
            config.fileList.addItem(lingExFileItem)
            reader = InterlinReader(self.unoObjs, self.userVars, config)
            words = reader.grabWords(fileItem.thingsToGrab)
        elif fileType in PhonReader.supportedNames():
            config = lingex_structs.PhonInputSettings(self.userVars)
            config.filepath = fileItem.filepath
            config.phoneticWS = fileItem.writingSystem
            config.isLexemePhonetic = True
            phonUserVars = UserVars(
                Prefix.PHONOLOGY, self.unoObjs.document, logger)
            if phonUserVars.get("FlexLexeme") == 'phonemic':
                config.isLexemePhonetic = False
            reader = PhonReader(self.unoObjs, self.userVars, config)
            words = reader.grabWords(fileItem.thingsToGrab)
        elif fileType in DocReader.supportedNames():
            settings = TextSearchSettings()
            settings.load_userVars(self.userVars)
            reader = DocReader(fileItem, self.unoObjs, settings.matchesLimit)
            words = reader.read()
        elif fileType in CalcFileReader.supportedNames():
            reader = CalcFileReader(self.unoObjs)
            reader.setFileConfig(fileItem)
            words = reader.read()
        return words


    def _generateCalcList(self):
        """Generate list in calc."""
        listOutput = WordlistIO(self.unoObjs, self.columnOrder)
        listOutput.outputList(self.words, self.progressBar)
        msgbox = listOutput.getMsgbox()  # for Calc spreadsheet

        ## Copy some user vars for the Spelling component.

        userVarsSp = UserVars(
            Prefix.SPELLING, self.unoObjs.document, logger)
        varname = "HasSettings"
        userVarsSp.store(varname, self.userVars.get(varname))
        columnOrderSp = ColumnOrder(userVarsSp)
        columnOrderSp.sortOrder = self.columnOrder.sortOrder
        columnOrderSp.storeUserVars()

        # Initialize some user vars for Calc dialogs.  We do this here
        # to reset properly if a new word list is made.
        self.userVars.store("ConvSourceColumn",
                            self.columnOrder.getColLetter('colWord'))
        self.userVars.store("ConvTargetColumn",
                            self.columnOrder.getColLetter('colConv1'))
        userVarsSp.store("CurrentRow", "")
        msgbox.display("Made list of %d words.", len(self.words))
Beispiel #18
0
class DlgChangerMaker:
    """Main class for this dialog."""
    def __init__(self, calcUnoObjs):
        self.unoObjs = calcUnoObjs
        self.msgbox = MessageBox(self.unoObjs)
        finder = uservars.SettingsDocFinder(uservars.Prefix.SPELLING,
                                            self.unoObjs)
        self.writerUnoObjs = finder.getWriterDoc()
        self.userVars = uservars.UserVars(uservars.Prefix.SPELLING,
                                          self.writerUnoObjs.document, logger)
        self.app = ChangerMaker(self.unoObjs, self.userVars)
        self.exportOnClose = False
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(self.unoObjs, ctrl_getter, self.evtHandler)
        self.evtHandler.setCtrls(self.dlgCtrls)
        self.dlgCtrls.loadValues(self.userVars)

        ## Display the dialog

        self.dlgClose = dlg.endExecute
        dlg.execute()

        if self.exportOnClose:
            self.app.make()
        dlg.dispose()

    def showFilePicker(self):
        logger.debug(util.funcName('begin'))
        filetype = "CCT"
        extension = CCT_EXT
        if self.dlgCtrls.optXSLT.getState() == 1:  # selected
            filetype = "XSLT"
            extension = XSLT_EXT
        logger.debug("Extension %s", extension)
        defaultFilename = "spelling_changes" + extension
        if filetype == "CCT":
            filters = [[
                "Consistent Change Table (%s)" % CCT_EXT, "*" + CCT_EXT
            ]]
        elif filetype == "XSLT":
            filters = [["XSL Transformations (%s)" % XSLT_EXT, "*" + XSLT_EXT]]
        filepath = filepicker.showFilePicker(self.unoObjs, True, filters,
                                             defaultFilename)
        logger.debug(repr(filepath))
        if filepath == "":
            logger.debug("No filepath specified.")
            return
        if not filepath.lower().endswith(extension):
            filepath = "%s%s" % (filepath, extension)  # += fails in python3
        self.dlgCtrls.txtFilePath.setText(filepath)
        logger.debug("set filepath to '%s'", filepath)

    def addXpath(self):
        logger.debug(util.funcName('begin'))
        newValue = self.dlgCtrls.txtXpath.getText()
        newValue = newValue.strip()
        stringList = dutil.listbox_items(self.dlgCtrls.listXpaths)
        logger.debug(repr(stringList))
        if newValue in stringList:
            self.msgbox.display("This expression is already in the list.")
            return
        stringList.append(newValue)
        stringList.sort()
        dutil.fill_list_ctrl(self.dlgCtrls.listXpaths, stringList, newValue)

    def removeXpath(self):
        logger.debug(util.funcName('begin'))
        try:
            itemPos = dutil.get_selected_index(self.dlgCtrls.listXpaths)
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
            return
        self.dlgCtrls.listXpaths.removeItems(itemPos, 1)
        # Select the next item
        dutil.select_index(self.dlgCtrls.listXpaths, itemPos)

    def closeAndExport(self):
        logger.debug(util.funcName('begin'))
        try:
            self.getFormResults()
            self.exportOnClose = True
            self.dlgClose()
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
        except exceptions.UserInterrupt:
            pass

    def closeDlg(self):
        logger.debug(util.funcName('begin'))
        self.getFormResults(verify=False)
        self.dlgClose()

    def getFormResults(self, verify=True):
        """Reads form fields and gets settings.
        If verify is True, raises an exception if there is a problem.
        """
        logger.debug(util.funcName('begin'))
        exportType = ""
        if self.dlgCtrls.optReplacementCCT.getState() == 1:  # selected
            exportType = "ReplacementCCT"
        elif self.dlgCtrls.optSFM_CCT.getState() == 1:
            exportType = "SFM_CCT"
            sfMarkers = self.dlgCtrls.txtSFM.getText().strip()
            if verify and sfMarkers == "":
                ok = self.msgbox.displayOkCancel(
                    "No SF markers were specified.  Continue anyway?")
                if not ok:
                    raise exceptions.UserInterrupt()
            self.userVars.store("SFM_Markers", sfMarkers)
            self.app.setSFM(sfMarkers)
        elif self.dlgCtrls.optXSLT.getState() == 1:
            exportType = "XSLT"
            if verify and self.dlgCtrls.listXpaths.getItemCount() == 0:
                ok = self.msgbox.displayOkCancel(
                    "No Xpath expressions were specified.  Continue anyway?")
                if not ok:
                    raise exceptions.UserInterrupt()
            self.userVars.store("XSLT_MatchPartial",
                                str(self.dlgCtrls.chkMatchPartial.getState()))
            self.app.setMatchPartial(
                self.dlgCtrls.chkMatchPartial.getState() == 1)
            self.userVars.store("XpathCount",
                                str(self.dlgCtrls.listXpaths.getItemCount()))
            stringList = dutil.listbox_items(self.dlgCtrls.listXpaths)
            for exprNum, exprVal in enumerate(stringList):
                varname = "XpathExpr%02d" % exprNum
                self.userVars.store(varname, exprVal)
            self.app.setXpathExprs(stringList)
        self.userVars.store("ExportType", exportType)
        self.app.setExportType(exportType)

        filepath = self.dlgCtrls.txtFilePath.getText().strip()
        if verify and filepath == "":
            raise exceptions.ChoiceProblem("Please specify a file to export.")
        self.userVars.store("Filepath", filepath)
        self.app.setFilepath(filepath)
        logger.debug(util.funcName('end'))
class DataConversion:
    """Main class for this module."""
    def __init__(self, docUnoObjs, userVars, styleFonts=None):
        """unoObjs needs to be for a writer doc if calling
        doConversions_writer(),
        and for a calc spreadsheet if calling doConversion_calc().
        Set styleFonts if calling setAndVerifyConfig(),
        which is probably only for the DlgBulkConv dialog.
        """
        self.unoObjs = docUnoObjs
        self.userVars = userVars
        self.changerSettings = TextChangerSettings()
        self.changerSettings.load_userVars(userVars)
        self.styleFonts = styleFonts
        self.msgbox = MessageBox(self.unoObjs)
        self.secCall = SEC_wrapper(self.msgbox, userVars)
        self.config = None

    def selectConverter(self):
        """Returns SEC_wrapper.ConverterSettings object.
        Saves normalization value, since it is not configurable in the dialog.
        """
        logger.debug(util.funcName('begin'))
        try:
            self.secCall.pickConverter()
            logger.debug("Picked converter.")
        except exceptions.FileAccessError as exc:
            self.msgbox.displayExc(exc)
        logger.debug("Converter name '%s'", self.secCall.config.convName)
        self.secCall.config.storeUserVars()  # for normalize
        return self.secCall.config

    def setAndVerifyConverter(self, newConv):
        """Parameter should be of type SEC_wrapper.ConverterSettings.
        Call this method before calling one of the doConversion() methods.
        """
        ## Get the converter if not yet done

        if newConv.convName == "":
            raise exceptions.ChoiceProblem("Please select a converter.")
        if newConv.convName == "<No converter>":
            return
        if self.secCall.config != newConv:
            try:
                self.secCall.setConverter(newConv)
                logger.debug("Did set converter.")
            except exceptions.FileAccessError as exc:
                self.msgbox.displayExc(exc)
                self.secCall.config.convName = ""
                raise exceptions.ChoiceProblem(
                    "Please select the converter again.")

    def setAndVerifyConfig(self, newConfig):
        """Sets self.config from newConfig, which should be type
        ConversionSettings.
        Throws exceptions.ChoiceProblem if the choices are not acceptable.
        """
        logger.debug(util.funcName('begin'))
        if not self.styleFonts:
            raise exceptions.LogicError("Expected styleFonts to be set.")

        if not newConfig.whichScope:
            raise exceptions.ChoiceProblem("Please specify a scope.")
        if (newConfig.whichScope == 'ParaStyle'
                and not newConfig.searchConfig.style):
            raise exceptions.ChoiceProblem(
                "Please select a scope paragraph style.")
        if (newConfig.whichScope == 'CharStyle'
                and not newConfig.searchConfig.style):
            raise exceptions.ChoiceProblem(
                "Please select a scope character style.")
        if (newConfig.whichScope == 'Font'
                and not newConfig.searchConfig.fontName):
            raise exceptions.ChoiceProblem("Please select a scope font.")
        if (newConfig.whichScope == 'SFMs'
                and not newConfig.searchConfig.SFMs):
            raise exceptions.ChoiceProblem("Please specify SFMs.")

        if not newConfig.whichTarget:
            raise exceptions.ChoiceProblem("Please specify a target.")
        if (newConfig.whichTarget == 'ParaStyle'
                and not newConfig.targetStyle):
            raise exceptions.ChoiceProblem("Please select a target style.")
        if (newConfig.whichTarget == 'CharStyle'
                and not newConfig.targetStyle):
            raise exceptions.ChoiceProblem("Please select a target style.")
        if (newConfig.whichTarget == 'FontOnly'
                and not newConfig.targetFont.fontName):
            raise exceptions.ChoiceProblem("Please select a target font.")

        self.config = newConfig
        try:
            if newConfig.whichTarget == 'ParaStyle':
                self.styleFonts.setParaStyleWithFont(newConfig.targetFont,
                                                     newConfig.targetStyle)
            elif newConfig.whichTarget == 'CharStyle':
                self.styleFonts.setCharStyleWithFont(newConfig.targetFont,
                                                     newConfig.targetStyle)
        except RuntimeException as exc:
            logger.exception(exc)
            raise exceptions.StyleError("Could not create style '%s'.",
                                        newConfig.targetStyle)
        logger.debug(util.funcName('end'))

    def doConversions_writer(self):
        """For converting data in a Writer doc."""
        logger.debug(util.funcName('begin'))

        ## Start progress bar

        progressBar = ProgressBar(self.unoObjs, "Converting...")
        progressBar.show()
        progressBar.updateBeginning()

        ## Find the text ranges

        textSearch = TextSearch(self.unoObjs, progressBar)
        textSearch.setConfig(self.config.searchConfig)
        try:
            if self.config.whichScope == 'WholeDoc':
                textSearch.scopeWholeDoc()
            elif self.config.whichScope == 'Selection':
                textSearch.scopeSelection()
            elif self.config.whichScope == 'ParaStyle':
                textSearch.scopeParaStyle()
            elif self.config.whichScope == 'CharStyle':
                textSearch.scopeCharStyle()
            elif self.config.whichScope == 'Font':
                textSearch.scopeFont()
            elif self.config.whichScope == 'SFMs':
                textSearch.scopeSFMs()
            else:
                raise exceptions.LogicError("Unexpected value %s",
                                            self.config.whichScope)
        except (exceptions.RangeError, exceptions.LogicError) as exc:
            self.msgbox.displayExc(exc)
            progressBar.close()
            return
        rangesFound = textSearch.getRanges()

        if progressBar.getPercent() < 40:
            progressBar.updatePercent(40)

        ## Do the changes to those ranges

        textChanger = TextChanger(self.unoObjs, progressBar,
                                  self.changerSettings)
        if self.secCall.config.convName:
            textChanger.setConverterCall(self.secCall)
        if self.config.whichTarget == "ParaStyle":
            textChanger.setStyleToChange("ParaStyleName",
                                         self.config.targetStyle)
        elif self.config.whichTarget == "CharStyle":
            textChanger.setStyleToChange("CharStyleName",
                                         self.config.targetStyle)
        elif self.config.whichTarget == "FontOnly":
            textChanger.setFontToChange(self.config.targetFont)
        numDataChanges, numStyleChanges = textChanger.doChanges(
            rangesFound, self.config.askEach)

        progressBar.updateFinishing()
        progressBar.close()

        ## Display results

        paragraphsFound = len(rangesFound)
        if paragraphsFound == 0:
            self.msgbox.display("Did not find scope of change.")
        elif numDataChanges == 0:
            if numStyleChanges == 0:
                self.msgbox.display("No changes.")
            else:
                plural = "" if numStyleChanges == 1 else "s"
                # add "s" if plural
                self.msgbox.display(
                    "No changes, but modified style of %d paragraph%s.",
                    numStyleChanges, plural)
        elif paragraphsFound == 1:
            plural = "" if numDataChanges == 1 else "s"  # add "s" if plural
            self.msgbox.display("Made %d change%s.", numDataChanges, plural)
        else:
            plural = "" if numDataChanges == 1 else "s"  # add "s" if plural
            self.msgbox.display("Found %d paragraphs and made %d change%s.",
                                paragraphsFound, numDataChanges, plural)

    def doConversions_calc(self, sourceCol, destCol, skipFirstRow):
        """For converting data in a Calc spreadsheet."""
        logger.debug(util.funcName('begin'))

        ## Start progress bar

        progressBar = ProgressBar(self.unoObjs, "Converting...")
        progressBar.show()
        progressBar.updateBeginning()

        ## Get list of words from source column
        #  (just strings are enough, no need for a special object)

        reader = SpreadsheetReader(self.unoObjs)
        try:
            inputList = reader.getColumnStringList(sourceCol, skipFirstRow)
        except exceptions.DocAccessError:
            self.msgbox.display("Error reading spreadsheet.")
            progressBar.close()
        if len(inputList) == 0:
            self.msgbox.display("Did not find anything in column %s.",
                                sourceCol)
            progressBar.close()
            return

        if progressBar.getPercent() < 40:
            progressBar.updatePercent(40)

        ## Convert

        outList = []
        problems = False
        numDataChanges = 0
        for inValue in inputList:
            try:
                outValue = self.secCall.convert(inValue)
                outList.append(outValue)
                if outValue != inValue:
                    numDataChanges += 1
            except exceptions.MessageError as exc:
                self.msgbox.displayExc(exc)
                problems = True
                outList.append("")
                break

        ## Output results

        outputter = SpreadsheetOutput(self.unoObjs)
        try:
            outputter.outputToColumn(destCol, outList, skipFirstRow)
        except exceptions.DocAccessError:
            self.msgbox.display("Error writing to spreadsheet.")

        progressBar.updateFinishing()
        progressBar.close()

        ## Display results

        if not problems:
            if numDataChanges == 0:
                self.msgbox.display("No changes.")
            else:
                self.msgbox.display("Successfully finished conversion.")

    def doConversions_draw(self):
        """For converting data in a Draw doc."""
        logger.debug(util.funcName('begin'))

        ## Start progress bar

        progressBar = ProgressBar(self.unoObjs, "Converting...")
        progressBar.show()
        progressBar.updateBeginning()

        ## Find the text ranges

        shapeSearch = ShapeSearch(self.unoObjs, progressBar)
        shapeSearch.setConfig(self.config.searchConfig)
        try:
            if self.config.whichScope == 'WholeDoc':
                shapeSearch.scopeWholeDoc()
            elif self.config.whichScope == 'Selection':
                shapeSearch.scopeSelection()
            elif self.config.whichScope == 'Font':
                shapeSearch.scopeFont()
            else:
                raise exceptions.LogicError("Unexpected value %s",
                                            self.config.whichScope)
        except (exceptions.RangeError, exceptions.LogicError) as exc:
            self.msgbox.displayExc(exc)
            progressBar.close()
            return
        rangesFound = shapeSearch.getRanges()

        if progressBar.getPercent() < 40:
            progressBar.updatePercent(40)

        ## Do the changes to those ranges

        textChanger = TextChanger(self.unoObjs, progressBar,
                                  self.changerSettings)
        if self.secCall.config.convName:
            textChanger.setConverterCall(self.secCall)
        textChanger.setFontToChange(self.config.targetFont)
        # Apparently, if we change text in front of a range in Draw,
        # the range can move.  So, start from the end and work backwards.
        rangesFound.reverse()
        numDataChanges, numStyleChanges = textChanger.doChanges(
            rangesFound, self.config.askEach)

        progressBar.updateFinishing()
        progressBar.close()

        ## Display results

        paragraphsFound = len(rangesFound)
        if paragraphsFound == 0:
            self.msgbox.display("Did not find scope of change.")
        elif numDataChanges == 0:
            if numStyleChanges == 0:
                self.msgbox.display("No changes.")
            else:
                plural = "" if numStyleChanges == 1 else "s"
                # add "s" if plural
                self.msgbox.display(
                    "No changes, but modified style of %d paragraph%s.",
                    numStyleChanges, plural)
        elif paragraphsFound == 1:
            plural = "" if numDataChanges == 1 else "s"  # add "s" if plural
            self.msgbox.display("Made %d change%s.", numDataChanges, plural)
        else:
            plural = "" if numDataChanges == 1 else "s"  # add "s" if plural
            self.msgbox.display("Found %d paragraphs and made %d change%s.",
                                paragraphsFound, numDataChanges, plural)
class DlgMkoxt:
    """Main class for this dialog."""
    def __init__(self, unoObjs):
        self.unoObjs = unoObjs
        self.msgbox = MessageBox(self.unoObjs)
        uservars.SettingsDocPreparer(uservars.Prefix.MAKE_OXT,
                                     unoObjs).prepare()
        self.userVars = uservars.UserVars(uservars.Prefix.MAKE_OXT,
                                          unoObjs.document, logger)
        self.settings = None
        self.runOnClose = False
        self.dlgCtrls = None
        self.evtHandler = None
        self.dlgClose = None

    def showDlg(self):
        logger.debug(util.funcName(obj=self))
        dlg = dutil.createDialog(self.unoObjs, _dlgdef)
        if not dlg:
            return
        ctrl_getter = dutil.ControlGetter(dlg)
        self.evtHandler = DlgEventHandler(self)
        self.dlgCtrls = DlgControls(self.unoObjs, ctrl_getter, self.evtHandler,
                                    self.userVars)
        self.evtHandler.setCtrls(self.dlgCtrls)
        self.dlgCtrls.loadValues()

        ## Display the dialog

        self.dlgClose = dlg.endExecute
        dlg.execute()

        if self.runOnClose:
            _mkoxt(self.settings, self.msgbox)
            filename = os.path.basename(self.settings.outfile)
            self.msgbox.display("%s finished." % filename)

        dlg.dispose()

    def showFilePicker(self):
        logger.debug(util.funcName('begin'))
        OXT_EXT = ".oxt"
        extension = OXT_EXT
        defaultFilename = "MyLanguage" + extension
        filters = [["OpenOffice Extension (%s)" % OXT_EXT, "*" + OXT_EXT]]
        filepath = filepicker.showFilePicker(self.unoObjs, True, filters,
                                             defaultFilename)
        logger.debug(repr(filepath))
        if filepath == "":
            logger.debug("No filepath specified.")
            return
        if not filepath.lower().endswith(extension):
            filepath = "{}{}".format(filepath, extension)
        self.dlgCtrls.txtOutfile.setText(filepath)
        logger.debug("set filepath to '%s'", filepath)

    def closeAndRun(self):
        logger.debug(util.funcName('begin'))
        try:
            self.settings = self.dlgCtrls.getFormResults()
            self.settings.empty_to_none()
            self.runOnClose = True
            self.dlgClose()
        except exceptions.ChoiceProblem as exc:
            self.msgbox.displayExc(exc)
        logger.debug(util.funcName('end'))
Beispiel #21
0
class ExServices:
    """Services that can conveniently be called from other modules."""

    def __init__(self, exType, unoObjs):
        self.exType = exType
        self.unoObjs = unoObjs
        if self.exType == EXTYPE_PHONOLOGY:
            USERVAR_PREFIX = Prefix.PHONOLOGY
        else:
            USERVAR_PREFIX = Prefix.GRAMMAR
        self.userVars = UserVars(
            USERVAR_PREFIX, unoObjs.document, logger)
        self.msgbox = MessageBox(unoObjs)
        self.settings = ExSettings(self.exType, self.unoObjs, self.userVars)
        self.operations = ExOperations(
            self.exType, self.unoObjs, self.userVars, self.settings)
        self.replacingRefs = True  # find and replace ref numbers
        logger.debug("ExGrabber init() finished")

    def getAllRefnums(self):
        """Returns an iterable of all ref numbers in the data.
        Items are in the order that they were read from the file.
        """
        try:
            self.operations.readData()
            return self.operations.examplesDict.keys()
        except exceptions.MessageError as exc:
            self.msgbox.displayExc(exc)

    def insertByRefnum(self, refTextRough):
        try:
            self.operations.readData()
            if not refTextRough.strip():
                raise exceptions.ChoiceProblem(
                    *self.operations.messageAndSuggestions(
                        "Please enter a ref number."))
            logger.debug("do the insertion.")
            self.operations.insertEx(refTextRough, False, False)
        except exceptions.MessageError as exc:
            self.msgbox.displayExc(exc)

    def setUpdateExamples(self, newVal):
        self.replacingRefs = not newVal

    def isUpdatingExamples(self):
        return not self.replacingRefs

    def findNext(self, searchFromBeginning):
        """Returns true if a ref number is found."""
        logger.debug("findNext(%s)", searchFromBeginning)
        oldFoundString = self.operations.getFoundString()
        newFoundString = self.operations.doSearch(
            self.replacingRefs, searchFromBeginning)
        if oldFoundString and not newFoundString:
            return bool(oldFoundString)
        return bool(newFoundString)

    def replace(self, searchFromBeginning):
        """Returns True if another ref number is found after replacing."""
        logger.debug(util.funcName('begin'))
        if (self.exType == EXTYPE_GRAMMAR and self.isUpdatingExamples() and
                not self.settings.getOutconfig().makeOuterTable):
            self.msgbox.display(
                "To update examples, 'Outer table' must be "
                "marked in Grammar Settings.")
            return False
        if not self.operations.getFoundString():
            return self.findNext(searchFromBeginning)
        refnumFound = self.operations.getFoundString()
        try:
            self.operations.readData()
            if self.replacingRefs:
                self.operations.insertEx(refnumFound, True, False)
            else:
                self.operations.updateEx(refnumFound)
            self.operations.doSearch(self.replacingRefs, False)
        except exceptions.MessageError as exc:
            self.msgbox.displayExc(exc)
        return bool(self.operations.getFoundString())

    def replaceAll(self):
        """Replace all #ref no's or update all existing examples."""
        if (self.exType == EXTYPE_GRAMMAR and self.isUpdatingExamples() and
                not self.settings.getOutconfig().makeOuterTable):
            self.msgbox.display(
                "To update examples, 'Outer table' must be "
                "marked in Grammar Settings.")
            return
        try:
            self.operations.readData()
            repeater = ExRepeater(
                self.msgbox, self.settings, self.operations,
                self.replacingRefs)
            repeater.replaceAll()
        except exceptions.MessageError as exc:
            self.msgbox.displayExc(exc)

    def addExampleNumbers(self):
        self.operations.addExampleNumbers()