class AbstractEngineSettingsPanel(SettingsPanel): """ Settings panel of external services. ocrHandler must be specified before use. """ # Developers: Please also specify a comment for translators name = _("Engine") title = _("Engine") descEngineNameCtrl = None # type: ExpandoTextCtrl engineSettingPanel = None # type: SpecificEnginePanel handler = AbstractEngineHandler # type: AbstractEngineHandler def makeGeneralSettings(self, settingsSizerHelper): """ Generate general settings for engine ocrHandler @param settingsSizerHelper: @type settingsSizerHelper: """ pass def makeSettings(self, settingsSizer): settingsSizerHelper = guiHelper.BoxSizerHelper(self, sizer=settingsSizer) # Translators: A label for the engines on the engine panel. engineLabel = self.title + _(" Engines") engineBox = wx.StaticBox(self, label=engineLabel) engineGroup = guiHelper.BoxSizerHelper(self, sizer=wx.StaticBoxSizer( engineBox, wx.HORIZONTAL)) settingsSizerHelper.addItem(engineGroup) # Use a ExpandoTextCtrl because even when readonly it accepts focus from keyboard, which # standard readonly TextCtrl does not. ExpandoTextCtrl is a TE_MULTILINE control, however # by default it renders as a single line. Standard TextCtrl with TE_MULTILINE has two lines, # and a vertical scroll bar. This is not necessary for the single line of text we wish to # display here. engine = self.handler.getCurrentEngine() engineDesc = engine.description msg = "Engine:\n{0}\nDescription:\n{1}\n".format(engine, engineDesc) log.debug(msg) self.descEngineNameCtrl = ExpandoTextCtrl(self, size=(self.scaleSize(250), -1), value=engineDesc, style=wx.TE_READONLY) self.descEngineNameCtrl.Bind(wx.EVT_CHAR_HOOK, self._enterTriggersOnChangeEngine) # Translators: This is the label for the button used to change engines, # it appears in the context of a engine group on the Online OCR settings panel. changeEngineBtn = wx.Button(self, label=_("C&hange...")) engineGroup.addItem( guiHelper.associateElements(self.descEngineNameCtrl, changeEngineBtn)) changeEngineBtn.Bind(wx.EVT_BUTTON, self.onChangeEngine) self.engineSettingPanel = SpecificEnginePanel(self, self.handler) settingsSizerHelper.addItem(self.engineSettingPanel) self.makeGeneralSettings(settingsSizerHelper) def _enterTriggersOnChangeEngine(self, evt): if evt.KeyCode == wx.WXK_RETURN: self.onChangeEngine(evt) else: evt.Skip() def onChangeEngine(self, evt): change_engine = EnginesSelectionDialog(self, self.handler, multiInstanceAllowed=True) ret = change_engine.ShowModal() if ret == wx.ID_OK: self.Freeze() # trigger a refresh of the settings self.onPanelActivated() self._sendLayoutUpdatedEvent() self.Thaw() def updateCurrentEngine(self): engine_description = self.handler.getCurrentEngine().description self.descEngineNameCtrl.SetValue(engine_description) def onPanelActivated(self): # call super after all panel updates have been completed, we do not want the panel to show until this is complete. self.engineSettingPanel.onPanelActivated() super(AbstractEngineSettingsPanel, self).onPanelActivated() def onPanelDeactivated(self): self.engineSettingPanel.onPanelDeactivated() super(AbstractEngineSettingsPanel, self).onPanelDeactivated() def onDiscard(self): self.engineSettingPanel.onDiscard() def onSave(self): self.engineSettingPanel.onSave()
def addRow(self, row, rowLabel=None): """Add one row of info, either header (col names) or normal data Adds items sequentially; FlexGridSizer moves to next row automatically """ labelBox = wx.BoxSizer(wx.HORIZONTAL) if not rowLabel: if sys.platform == 'darwin': self.SetWindowVariant(variant=wx.WINDOW_VARIANT_SMALL) label = _translate('cond %s:') % str(row + 1 - int(self.hasHeader)).zfill(2) rowLabel = wx.StaticText(self, -1, label=label) rowLabel.SetForegroundColour(darkgrey) if sys.platform == 'darwin': self.SetWindowVariant(variant=wx.WINDOW_VARIANT_NORMAL) labelBox.Add(rowLabel, 1, flag=wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM) self.sizer.Add(labelBox, 1, flag=wx.ALIGN_CENTER) lastRow = [] for col in range(self.cols): # get the item, as unicode for display purposes: if len(str(self.grid[row][col])): # want 0, for example item = str(self.grid[row][col]) else: item = u'' # make a textbox: field = ExpandoTextCtrl(self, -1, item, size=(self.colSizes[col], 20)) field.Bind(EVT_ETC_LAYOUT_NEEDED, self.onNeedsResize) field.SetMaxHeight(100) # ~ 5 lines if self.hasHeader and row == 0: # add a default column name (header) if none provided header = self.grid[0] if item.strip() == '': c = col while self.colName(c) in header: c += 1 field.SetValue(self.colName(c)) field.SetForegroundColour(darkblue) # dark blue # or (self.parent and if not valid_var_re.match(field.GetValue()): # self.parent.exp.namespace.exists(field.GetValue()) ): # was always red when preview .xlsx file -- in # namespace already is fine if self.fixed: field.SetForegroundColour("Red") field.SetToolTip( wx.ToolTip( _translate( 'Should be legal as a variable name (alphanumeric)' ))) field.Bind(wx.EVT_TEXT, self.checkName) elif self.fixed: field.SetForegroundColour(darkgrey) field.SetBackgroundColour(white) # warn about whitespace unless will be auto-removed. invisible, # probably spurious: if (self.fixed or not self.clean) and item != item.strip(): field.SetForegroundColour('Red') # also used in show(): self.warning = _translate('extra white-space') field.SetToolTip(wx.ToolTip(self.warning)) if self.fixed: field.Disable() lastRow.append(field) self.sizer.Add(field, 1) self.inputFields.append(lastRow) if self.hasHeader and row == 0: self.header = lastRow
class spellCheckerDialog(wx.Dialog): # A dialog to show spellchecker _instance = None def __new__(cls, *args, **kwargs): if spellCheckerDialog._instance is None: return wx.Dialog.__new__(cls) return spellCheckerDialog._instance def __init__ (self, parent): spellCheckerDialog._instance = self # Translators: Title of the dialog. super (spellCheckerDialog, self).__init__(parent, wx.ID_ANY, title = _("Spell checker")) title = _("Spell checker") self.title = title self.makeSettings() def makeSettings(self): mainSizer = wx.BoxSizer(wx.VERTICAL) tasksSizer = wx.BoxSizer(wx.VERTICAL) # Translators: A label for the the Not in dictionary field NotInDictionLabel = _("&Not in dictionary") notDictBox = wx.StaticBox(self, label = NotInDictionLabel) self.misspelledCtrl = ExpandoTextCtrl(self, size = (250, -1), value = misspelled, style=wx.TE_READONLY) # Translators: A label for the paragraph field NotInDiction1Label = _("in the following paragraph:") notDict1Box = wx.StaticBox(self, label = NotInDiction1Label) self.msParagraphCtrl = ExpandoTextCtrl(self, size = (250, -1), value = msParagraph, style=wx.TE_READONLY) # Translators: The label for the list of suggestions. sHelper = guiHelper.BoxSizerHelper(self, orientation=wx.VERTICAL) entriesLabelText=_("&Suggestions") self.dictList = sHelper.addLabeledControl(entriesLabelText, wx.ListBox, id = wx.ID_ANY, choices = candidates, style = wx.LB_SINGLE, size = (700,580)) #self.editingIndex=-1 # Create buttons. # Buttons are in a horizontal row buttonsSizer = wx.BoxSizer(wx.HORIZONTAL) addButtonID = wx.Window.NewControlId() # Translators: Label of button to add the misspelled word to the personal dictionary. self.addButton = wx.Button(self, addButtonID, _('&Add')) buttonsSizer.Add (self.addButton) ignoreButtonID = wx.Window.NewControlId() # Translators: Label of button to ignore the misspelled word once. self.ignoreButton = wx.Button (self, ignoreButtonID, _('Ignore &once')) buttonsSizer.Add(self.ignoreButton) ignoreAllButtonID = wx.Window.NewControlId() # Translators: Label of button to ignore all cases of the misspelled word. self.ignoreAllButton = wx.Button(self, ignoreAllButtonID, _('&Ignore all')) buttonsSizer.Add (self.ignoreAllButton) substituteButtonID = wx.Window.NewControlId() # Translators: Label of button to replace the misspelled word by the suggestion. self.substituteButton = wx.Button(self, substituteButtonID, _('&Substitute')) buttonsSizer.Add (self.substituteButton) substituteAllButtonID = wx.Window.NewControlId() # Translators: Label of button to replace all occurrences of the misspelled word by the suggestion. self.substituteAllButton = wx.Button(self, substituteAllButtonID, _('Su&bstitute all')) buttonsSizer.Add (self.substituteAllButton) editButtonID = wx.Window.NewControlId() # Translators: Label of button to allow edition of the text. self.editButton = wx.Button (self, editButtonID, _('&Edit')) buttonsSizer.Add (self.editButton) cancelButtonID = wx.Window.NewControlId() # Translators: Button Label that closes the add-on. self.cancelButton = wx.Button(self, cancelButtonID, _('&Close')) buttonsSizer.Add(self.cancelButton) tasksSizer.Add(buttonsSizer) mainSizer.Add(tasksSizer) # Bind the buttons. self.Bind(wx.EVT_BUTTON, self.onAdd, id = addButtonID) self.Bind (wx.EVT_BUTTON, self.onIgnoreOnce, id = ignoreButtonID ) self.Bind(wx.EVT_BUTTON, self.onIgnoreAll, id = ignoreAllButtonID) self.Bind(wx.EVT_BUTTON, self.onSubstitute, id = substituteButtonID) self.Bind(wx.EVT_BUTTON, self.onSubstituteAll, id = substituteAllButtonID) self.Bind(wx.EVT_BUTTON, self.onEdit, id = editButtonID) self.cancelButton.Bind(wx.EVT_BUTTON, lambda evt: self.Destroy()) self.SetEscapeId(wx.ID_CLOSE) self.dictList.Bind(wx.EVT_KEY_DOWN, self.onKeyPress) self.misspelledCtrl.Bind(wx.EVT_KEY_DOWN, self.onKeyPress) self.msParagraphCtrl.Bind(wx.EVT_KEY_DOWN, self.onKeyPress) mainSizer.Fit(self) self.SetSizer(mainSizer) # Show the window if it is hidden if not self.IsShown(): gui.mainFrame.prePopup() self.Show() gui.mainFrame.postPopup() def onAdd(self,evt): global vocabulary, misspelled # Create or open a personal dictionary to add our words or words not in main dictionary... with open (os.path.join (os.path.dirname(__file__), "personal.txt"), "a", encoding = "UTF-8") as g: g.write(misspelled +"\n") g.close() # Temporarily add this word to Vocabulary to allow the added word to be considered as correct... vocabulary.append(misspelled) # Clean the variable... misspelled = "" # Close the dialog... self.Close() # Resume the spellchecking... checkVocabulary() def onIgnoreOnce(self,evt): global misspelled # Just clean the variable and do nothing since the process restart on next word... misspelled = "" self.Close() checkVocabulary() def onIgnoreAll(self,evt): global vocabulary, misspelled # Temporarily add the word to the dictionary to make it considered correct... vocabulary.append(misspelled) misspelled = "" self.Close() checkVocabulary() def onSubstitute(self,evt): global allText, misspelled, candidates, misspelledWord # Get the selected word from the candidates list... index = self.dictList.GetSelection() # Add to replacement word the character before and after the misspelled word to maintain possible punctuations... replacementWord = misspelledWord[0]+str (candidates[index])+misspelledWord[-1] # Replace the misspelled by the candidate word selected... allText = allText.replace (str(misspelledWord), replacementWord, 1) misspelled = "" self.Close() checkVocabulary() def onSubstituteAll(self,evt): global allText, misspelled, candidates, misspelledWord, wordsList # Get the selected word from the candidates list... index = self.dictList.GetSelection() # Add to replacement word the character before and after the misspelled word to maintain possible punctuations... replacementWord = misspelledWord[0]+str (candidates[index])+misspelledWord[-1] # Replace the misspelled by the candidate word selected... allText = allText.replace (str(misspelledWord), replacementWord) # Remove the misspelled word from the list of words... wordsList = list(filter(lambda a: a != misspelled, wordsList)) misspelled = "" self.Close() checkVocabulary() def onEdit(self,evt): global allText, msParagraph # Translators: Message dialog box to change a block of text. dlg = wx.TextEntryDialog(gui.mainFrame, _("Enter the new block of text or press Enter to confirm"), self.title, style = wx.OK | wx.CANCEL | wx.TE_MULTILINE) dlg.SetValue(msParagraph) if dlg.ShowModal() == wx.ID_OK: corParagraph = dlg.GetValue() allText = allText.replace(msParagraph, corParagraph) misspelled = "" else: dlg.Destroy() return misspelled = "" self.Close() checkVocabulary() def onKeyPress(self, evt): # Sets enter key to replace the misspelled word by the suggestion and Escape to close. evt.Skip() keycode = evt.GetKeyCode() if keycode == wx.WXK_RETURN and self.dictList.GetSelection(): self.onSubstitute(evt) elif keycode == wx.WXK_ESCAPE: self.Destroy() def Destroy(self): self = spellCheckerDialog._instance if gui.messageBox(_("Do you want to apply the changes?"), _("Spell checker"), style=wx.ICON_QUESTION|wx.YES_NO) == wx.YES: self.applyCorrections() spellCheckerDialog._instance = None super (spellCheckerDialog, self).Destroy() def applyCorrections(self): self.Close() KeyboardInputGesture.fromName("Control+home").send() KeyboardInputGesture.fromName("Control+Shift+end").send() api.copyToClip(str(allText)) time.sleep(2.0) KeyboardInputGesture.fromName("Control+v").send() spellCheckerDialog._instance = None super (spellCheckerDialog, self).Destroy()