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'))
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
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]
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'))
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'))
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
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)
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))
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'))
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()