def loadRegister(self, name): self.SetTitle(titleTemplate % name) # TODO: should be set after loading item = self.app.config.registers[name] self.dictName = name self.entry.Disable() if item[1] == "dwa": self.timerLoad.Start(self.delay) self.load = Process(SlowoParser, item[0], self) elif item[1] == "mova": self.timerLoad.Start(self.delay) self.load = Process(MovaParser, item[0], self) elif item[1] == "tmx": self.timerLoad.Start(self.delay) self.load = Process(TMXParser, item[0], self) elif item[1] == "dz": self.timerLoad.Start(self.delay) self.load = Process(DictParser, item[0], self) else: self.SetStatusText(_("Error: not supported dictionary type")) return self.app.config.encoding = item[2] self.checkEncMenuItem(self.app.config.encoding)
def onPronounce(self, event): """Pronouce word using external software.""" word = self.entry.GetValue().strip() if word: cmd = self.app.config.get( 'pronunciationCommand') or prefswin.PRON_COMMAND if self.app.config.get('pronounceTrans') == 'True': word = html2text(self.htmlCode) import locale localeCharset = locale.getpreferredencoding() try: word = word.replace('(', '').replace(')', '').replace( '\n', '').replace('\r', '').replace('"', '\\"') cmd = (cmd % word).encode(localeCharset) Process(os.system, cmd) except Exception as e: traceback.print_exc() title = _("Error") msg = _("Unable to decode text using your locale charset %s" \ % localeCharset) errorwin.showErrorMessage(title, msg)
def OnLinkClicked(self, linkInfo): global lastLookupWord lastLookupWord = linkInfo.GetHref() wx.BeginBusyCursor() parent = self.GetParent().GetParent().GetParent() word = enc.fromWX(lastLookupWord) try: word = word.encode(parent.activeDictionary.getEncoding()) except Exception as e: # FIXME: Code duplicates traceback.print_exc() parent.buttonStop.Disable() parent.entry.Enable(True) parent.timerSearch.Stop() parent.SetStatusText(_('Stopped')) wx.EndBusyCursor() systemLog(ERROR, "Unable to decode '%s': %s" % (word.encode('UTF-8'), e)) title = _("Encode Failed") msg = _("Unable to encode text \"%s\" in %s for \"%s\".") \ % (enc.toWX(word), parent.activeDictionary.getEncoding(), parent.activeDictionary.getName()) errorwin.showErrorMessage(title, msg) return parent.SetStatusText(_("Searching...")) parent.entry.SetValue(word) parent.timerSearch.Start(parent.delay) parent.search = Process(parent.activeDictionary.search, word)
def onUpdateDB(self, event): self.SetStatusText(_("Connecting...")) self.timerUpdateDB.Start(CONNECTION_CHECK_INTERVAL) self.update = Process(dictclient.Connection, self.entryServer.GetValue(), int(self.entryPort.GetValue()))
def onTimerUpdateDB(self, event): systemLog(DEBUG, "DictConnection: [IDLE] Receiving DB list...") if self.update != None: if self.update.isDone(): systemLog(DEBUG, "DictConnection: DB list received") obj = self.update() if type(obj) == type({}): self.timerUpdateDB.Stop() self.update = None self.choiceDB.Clear() self.choiceDB.Append(self.msgSearchInAll) for name in list(obj.values()): self.choiceDB.Append(name) self.SetStatusText(_("Done")) self.choiceDB.SetValue(self.msgSearchInAll) self.choiceDB.SetInsertionPoint(0) elif obj != None: self.SetStatusText(_("Receiving database list...")) self.update = Process(obj.getdbdescs) else: self.timerUpdateDB.Stop() self.SetStatusText('') title = _("Connection Error") msg = _("Unable to connect to server") errorwin.showErrorMessage(title, msg)
def onWordSelected(self, event): """Is called when word list item is selected""" if self.search and not self.search.isDone(): return self.__searchedBySelecting = 1 self.SetStatusText(_("Searching...")) self.buttonStop.Enable(1) self.timerSearch.Start(self.delay) word = event.GetString() global lastLookupWord lastLookupWord = word self.entry.SetValue(word) word = enc.fromWX(word) word = word.encode(self.activeDictionary.getEncoding()) self.search = Process(self.activeDictionary.search, word) wx.BeginBusyCursor()
def onOK(self, event): self.server = self.entryServer.GetValue() self.app.config.set('dictServer', self.server) self.port = self.entryPort.GetValue() encName = self.entryEncoding.GetValue() try: enc = misc.encodings[encName] except KeyError: print('Error: invalid encoding name "%s", defaulting to UTF-8' % \ encName) enc = 'UTF-8' self.encoding = (enc, encName) self.timerConnect.Stop() self.timerUpdateDB.Stop() self.SetStatusText(_("Connecting to %s...") % self.server) self.timerConnect.Start(CONNECTION_CHECK_INTERVAL) self.connection = Process(dictclient.Connection, self.server, int(self.port))
def onSearch(self, event): if self.activeDictionary == None: if len(self.app.dictionaries): title = _("No dictionary activated") msg = _("No dictionary activated. Please select one from "\ "\"Dictionaries\" menu and try again.") else: title = _("No dictionaries installed") msg = _("There is no dictionaries installed. You can " \ "install one by selecting Tools > Manage " \ "Dictionaries > Available") errorwin.showErrorMessage(title, msg) return if self.search and not self.search.isDone(): self.onStop(None) word = self.entry.GetValue().strip() if word == "": self.SetStatusText(_("Please enter some text and try again")) self.entry.SetFocus() return global lastLookupWord lastLookupWord = word wx.BeginBusyCursor() self.__searchedBySelecting = 0 self.SetStatusText(_("Searching...")) self.timerSearch.Stop() self.search = None self.buttonStop.Enable(1) self.entry.Disable() self.timerSearch.Start(self.delay) word = enc.fromWX(word) try: word = word.encode(self.activeDictionary.getEncoding()) except Exception as e: # FIXME: Code duplicates self.buttonStop.Disable() self.entry.Enable(True) self.timerSearch.Stop() self.SetStatusText(_('Stopped')) wx.EndBusyCursor() systemLog(ERROR, "Unable to decode '%s': %s" % (word.encode('UTF-8'), e)) title = _("Encode Failed") msg = _("Unable to encode text \"%s\" in %s for \"%s\". " "That logically means the word " "definition does not exist in the dictionary.") \ % (enc.toWX(word), self.activeDictionary.getEncoding(), self.activeDictionary.getName()) errorwin.showErrorMessage(title, msg) return self.search = Process(self.activeDictionary.search, word)
class MainWindow(wx.Frame): """Main OpenDict window with basic controls""" def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE): wx.Frame.__init__(self, parent, id, title, pos, size, style) self.app = wx.GetApp() self.printer = wx.html.HtmlEasyPrinting() self.history = History() self.htmlCode = "" self.dictName = "" self.activeDictionary = None self.words = [] self.delay = 10 # miliseconds self.lastInstalledDictName = None # This var is used by onTimerSearch to recognize search method. # If search was done by selecting a word in a list, then word list # is not updated, otherwise is. self.__searchedBySelecting = 0 # Box sizers vboxMain = wx.BoxSizer(wx.VERTICAL) self.hboxToolbar = wx.BoxSizer(wx.HORIZONTAL) # # Menu Bar # self.menuBar = wx.MenuBar() # # File menu # menuFile = wx.Menu() idPrint = wx.NewId() #menuFile.Append(idPrint, _("Print Translation"), "") idPreview = wx.NewId() #menuFile.Append(idPreview, _("Print Preview"), "") idFind = wx.NewId() menuFile.Append(idFind, _("Look Up\tCtrl-U"), _("Lookup up word in the dictionary")) menuFile.AppendSeparator() idCloseDict = wx.NewId() menuFile.Append(idCloseDict, _("&Close Dictionary\tCtrl-W"), _("Close opened dicitonary")) idExit = wx.NewId() menuFile.Append(idExit, _("E&xit\tCtrl-Q"), _("Exit program")) self.menuBar.Append(menuFile, _("&File")) menuEdit = wx.Menu() # # Clear functions # idClearEntry = wx.NewId() menuEdit.Append(idClearEntry, _("&Clear Search Entry\tCtrl-L")) idClearHistory = wx.NewId() menuEdit.Append(idClearHistory, _("Clear History")) menuEdit.AppendSeparator() # # Clipboard functions # idCopy = wx.NewId() menuEdit.Append(idCopy, _("Copy\tCtrl-C"), _("Copy selected translation text")) idPaste = wx.NewId() menuEdit.Append(idPaste, _("Paste\tCtrl-V"), _("Paste clipboard text into the search entry")) menuEdit.AppendSeparator() idPrefs = wx.NewId() menuEdit.Append(idPrefs, _("Preferences...\tCtrl-P"), _("Edit preferences")) self.menuBar.Append(menuEdit, _("&Edit")) # # View menu # menuView = wx.Menu() # Font size self.menuFontSize = wx.Menu() self.menuFontSize.Append(2007, _("Increase\tCtrl-="), _("Increase text size")) self.menuFontSize.Append(2008, _("Decrease\tCtrl--"), _("Decrease text size")) self.menuFontSize.AppendSeparator() self.menuFontSize.Append(2009, _("Normal\tCtrl-0"), _("Set normal text size")) menuView.Append(2002, _("Font Size"), self.menuFontSize) # Font face self.menuFontFace = wx.Menu() i = 0 keys = list(misc.fontFaces.keys()) keys.sort() for face in keys: self.menuFontFace.AppendRadioItem(2500 + i, face, "") self.Bind(wx.EVT_MENU, self.onDefault, id=2500 + i) if self.app.config.get('fontFace') == misc.fontFaces[face]: self.menuFontFace.FindItemById(2500 + i).Check(1) i += 1 menuView.Append(2001, _("Font Face"), self.menuFontFace) # Font encoding self.menuEncodings = wx.Menu() i = 0 keys = list(misc.encodings.keys()) keys.sort() for encoding in keys: self.menuEncodings.AppendRadioItem(2100 + i, encoding, "") self.Bind(wx.EVT_MENU, self.onDefault, id=2100 + i) if self.app.config.get('encoding') == misc.encodings[encoding]: self.menuEncodings.FindItemById(2100 + i).Check(1) i += 1 menuView.Append(2000, _("Character Encoding"), self.menuEncodings) menuView.AppendSeparator() idShowHide = wx.NewId() menuView.Append(idShowHide, _("Show/Hide Word List...\tCtrl-H"), _("Show or hide word list")) self.menuBar.Append(menuView, _("&View")) # # Dictionaries menu # self.menuDict = wx.Menu() dicts = [] for dictionary in list(self.app.dictionaries.values()): dicts.append([dictionary.getName(), dictionary.getActive()]) dicts.sort() for name, active in dicts: #if not self.app.config.activedict.enabled(name): # continue if not active: continue encoded = enc.toWX(name) itemID = list(self.app.config.ids.keys())[\ list(self.app.config.ids.values()).index(name)] try: # item = wx.MenuItem(self.menuDict, # itemID, # encoded) # self.menuDict.AppendItem(item) self.menuDict.AppendRadioItem(itemID, encoded, "") self.Bind(wx.EVT_MENU, self.onDefault, id=itemID) if self.app.config.get('defaultDict') == name: self.menuDict.FindItemById(itemID).Check(1) except Exception as e: systemLog(ERROR, "Unable to create menu item for '%s' (%s)" \ % (name, e)) self.menuDict.AppendSeparator() idAddDict = wx.NewId() self.menuDict.Append(idAddDict, _("&Install Dictionary From File...")) self.menuBar.Append(self.menuDict, _("&Dictionaries")) # # Tools menu # menuTools = wx.Menu() idManageDict = wx.NewId() menuTools.Append(idManageDict, _("Manage Dictionaries...\tCtrl-M"), _("Install or remove dictionaries")) menuTools.Append(5002, _("Create Dictionaries..."), _("Create and edit dictionaries")) menuTools.AppendSeparator() idUseScan = wx.NewId() item = wx.MenuItem(menuTools, idUseScan, _("Take Words From Clipboard"), _("Scan the clipboard for text to translate"), wx.ITEM_CHECK) menuTools.Append(item) menuTools.Check(idUseScan, self.app.config.get('useClipboard') == 'True') menuTools.AppendSeparator() idDictServer = wx.NewId() menuTools.Append(idDictServer, _("Connect to DICT Server..."), _("Open connection to DICT server")) menuTools.AppendSeparator() idPron = wx.NewId() menuTools.Append(idPron, _("Pronounce\tCtrl-E"), _("Pronounce word")) self.menuBar.Append(menuTools, _("Tools")) # # Help menu # menuHelp = wx.Menu() idAbout = wx.NewId() menuHelp.Append(idAbout, _("&About\tCtrl-A")) self.menuBar.Append(menuHelp, _("&Help")) self.SetMenuBar(self.menuBar) # Search Bar labelWord = wx.StaticText(self, -1, _("Word:")) self.hboxToolbar.Add(labelWord, 0, wx.ALL | wx.CENTER, 5) self.entry = wx.ComboBox(self, 153, "", wx.Point(-1, -1), wx.Size(-1, -1), [], wx.CB_DROPDOWN) self.entry.SetToolTip(_("Enter some text and press " \ "\"Look Up\" button or " "[ENTER] key on your keyboard")) self.hboxToolbar.Add(self.entry, 1, wx.ALL | wx.CENTER, 1) #self.buttonSearch = wx.Button(self, wx.ID_FIND) self.buttonSearch = wx.Button(self, idFind, _("Look Up")) self.buttonSearch.SetToolTip(_("Click this button to look " \ "up word in " \ "the dictionary")) self.hboxToolbar.Add(self.buttonSearch, 0, wx.ALL | wx.CENTER, 1) # Back button bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME, "pixmaps", "left.png"), wx.BITMAP_TYPE_PNG) self.buttonBack = wx.BitmapButton(self, 2010, bmp, (24, 24), style=wx.NO_BORDER) self.buttonBack.SetToolTip(_("History Back")) self.buttonBack.Disable() self.hboxToolbar.Add(self.buttonBack, 0, wx.ALL | wx.CENTER, 1) # Forward button bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME, "pixmaps", "right.png"), wx.BITMAP_TYPE_PNG) self.buttonForward = wx.BitmapButton(self, 2011, bmp, (24, 24), style=wx.NO_BORDER) self.buttonForward.SetToolTip(_("History Forward")) self.buttonForward.Disable() self.hboxToolbar.Add(self.buttonForward, 0, wx.ALL | wx.CENTER, 1) # Stop threads # TODO: how thread can be killed? bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME, "pixmaps", "stop.png"), wx.BITMAP_TYPE_PNG) self.buttonStop = wx.BitmapButton(self, 155, bmp, (16, 16), style=wx.NO_BORDER) self.buttonStop.SetToolTip(_("Stop searching")) self.buttonStop.Disable() self.hboxToolbar.Add(self.buttonStop, 0, wx.ALL | wx.CENTER, 1) # Word list is hidden by default self.wlHidden = True bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME, "pixmaps", "hide.png"), wx.BITMAP_TYPE_PNG) self.buttonHide = wx.BitmapButton(self, 152, bmp, (24, 24), style=wx.NO_BORDER) self.hboxToolbar.Add(self.buttonHide, 0, wx.ALL | wx.CENTER, 1) vboxMain.Add(self.hboxToolbar, 0, wx.ALL | wx.EXPAND | wx.GROW, 0) # Splitter Window self.splitter = wx.SplitterWindow(self, -1) # List panel self.createListPanel() # Html window panel self.panelHtml = wx.Panel(self.splitter, -1) sbSizerHtml = wx.StaticBoxSizer( wx.StaticBox(self.panelHtml, -1, _("Translation")), wx.VERTICAL) self.htmlWin = HtmlWindow(self.panelHtml, -1, style=wx.SUNKEN_BORDER) sbSizerHtml.Add(self.htmlWin, 1, wx.ALL | wx.EXPAND, 0) self.panelHtml.SetSizer(sbSizerHtml) self.panelHtml.SetAutoLayout(True) sbSizerHtml.Fit(self.panelHtml) self.splitter.SplitVertically(self.panelList, self.panelHtml, int(self.app.config.get('sashPos'))) self.splitter.SetMinimumPaneSize(90) if not self.activeDictionary: self.hideWordList() vboxMain.Add(self.splitter, 1, wx.ALL | wx.GROW | wx.EXPAND, 0) # Status bar self.CreateStatusBar() # Main sizer self.SetSizer(vboxMain) self.timerSearch = wx.Timer(self, 5000) self.timerLoad = wx.Timer(self, 5001) idClipboard = wx.NewId() self.timerClipboard = wx.Timer(self, idClipboard) self.scanTimeout = 2000 self.search = None self.load = None self.SetIcon( wx.Icon( os.path.join(info.GLOBAL_HOME, "pixmaps", "icon-32x32.png"), wx.BITMAP_TYPE_PNG)) # # Loading default dictionary # if self.app.config.get('defaultDict'): self.loadDictionary(self.app.dictionaries.get(\ self.app.config.get('defaultDict'))) self.SetMinSize((320, 160)) # # Events # # TODO: New-style event definition # File menu events self.Bind(wx.EVT_MENU, self.onPrint, id=idPrint) self.Bind(wx.EVT_MENU, self.onPreview, id=idPreview) self.Bind(wx.EVT_MENU, self.onCloseDict, id=idCloseDict) self.Bind(wx.EVT_MENU, self.onExit, id=idExit) # Edit menu events self.Bind(wx.EVT_MENU, self.onClearHistory, id=idClearHistory) self.Bind(wx.EVT_MENU, self.onCopy, id=idCopy) self.Bind(wx.EVT_MENU, self.onPaste, id=idPaste) self.Bind(wx.EVT_MENU, self.onClean, id=idClearEntry) # View menu events self.Bind( wx.EVT_MENU, self.onIncreaseFontSize, id=2007, ) self.Bind(wx.EVT_MENU, self.onDecreaseFontSize, id=2008) self.Bind(wx.EVT_MENU, self.onNormalFontSize, id=2009) self.Bind(wx.EVT_MENU, self.onHideUnhide, id=idShowHide) # Dictionaries menu events self.Bind(wx.EVT_MENU, self.onAddDict, id=idAddDict) # Tools menu events self.Bind(wx.EVT_MENU, self.onOpenDictConn, id=idDictServer) self.Bind(wx.EVT_MENU, self.onUseScanClipboard, id=idUseScan) self.Bind(wx.EVT_MENU, self.onShowPluginManager, id=idManageDict) self.Bind(wx.EVT_MENU, self.onShowDictEditor, id=5002) self.Bind(wx.EVT_MENU, self.onShowPrefsWindow, id=idPrefs) self.Bind(wx.EVT_MENU, self.onPronounce, id=idPron) # Help menu events self.Bind(wx.EVT_MENU, self.onAbout, id=idAbout) # Other events self.Bind(wx.EVT_BUTTON, self.onSearch, self.buttonSearch) self.Bind(wx.EVT_MENU, self.onSearch, id=idFind) self.Bind(wx.EVT_BUTTON, self.onBack, id=2010) self.Bind(wx.EVT_BUTTON, self.onForward, id=2011) self.Bind(wx.EVT_BUTTON, self.onStop, id=155) self.Bind(wx.EVT_BUTTON, self.onClean, id=151) self.Bind(wx.EVT_BUTTON, self.onHideUnhide, id=152) self.Bind(wx.EVT_TEXT_ENTER, self.onSearch, id=153) self.Bind(wx.EVT_LISTBOX, self.onWordSelected, id=154) self.Bind(wx.EVT_TIMER, self.onTimerSearch, id=5000) self.Bind(wx.EVT_TIMER, self.onTimerClipboard, id=idClipboard) self.Bind(wx.EVT_CLOSE, self.onCloseWindow) self.entry.Bind(wx.EVT_KEY_DOWN, self.onKeyDown) # Prepare help message self.htmlCode = _(""" <html> <head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"> </head> <body> <h3>Welcome to OpenDict</h3> <p><b>Short usage information:</b></p> <ul> <li>To start using dictionary, select one from <i><b>Dictionaries</b></i> menu. </li> <li>To install new dictionary from the Internet, select <i><b>Manage Dictionaries</b></i> from <i><b>Tools</b></i> menu and choose <i><b>Available</b></i> tab.</li> <li>To install new dictionary from file, select <i><b>Install Dictionary From File...</b></i> from <i><b>Dictionaries</b></i> menu. </li> </ul> </body> </html> """) if self.activeDictionary: self.htmlCode = "" self.updateHtmlScreen() if self.app.invalidDictionaries: miscwin.showInvalidDicts(self, self.app.invalidDictionaries) if self.app.config.get('useClipboard') == 'True': self.timerClipboard.Start(self.scanTimeout) def onExit(self, event): self.onCloseWindow(None) def onCloseWindow(self, event): self.onCloseDict(None) self.savePreferences() self.Destroy() # TODO: Move aftersearch actions into separate method def onTimerSearch(self, event): """Search timer. When finished, sets search results""" if self.search != None and self.search.isDone(): self.timerSearch.Stop() self.search.stop() # # Turn back active interface elements state wx.EndBusyCursor() self.SetStatusText("") self.entry.Enable(1) self.buttonStop.Disable() global lastLookupWord word = lastLookupWord if self.entry.FindString(word) == -1: self.entry.Append(word) result = self.search() # Check if search result is SerachResult object. # SearchResult class is used by new-type plugins. try: assert result.__class__ == meta.SearchResult except: self.SetStatusText(errortype.INTERNAL_ERROR.getMessage()) if self.activeDictionary.getType() == dicttype.PLUGIN: title = errortype.INTERNAL_ERROR.getMessage() message = errortype.INTERNAL_ERROR.getLongMessage() else: title = errortype.OPENDICT_BUG.getMessage() message = errortype.OPENDICT_BUG.getLongMessage() systemLog(ERROR, "%s: %s" % (message, misc.getTraceback())) errorwin.showErrorMessage(title, message) return # Check status code if result.getError() != errortype.OK: systemLog(ERROR, result.getError()) self.htmlWin.SetPage("") self.wordList.Clear() if result.getError() in \ [errortype.INTERNAL_ERROR, errortype.INVALID_ENCODING]: errorwin.showErrorMessage( result.getError().getMessage(), result.getError().getLongMessage()) else: self.SetStatusText(result.getError().getMessage()) return # # If dictionary (plugin) does not use NOT_FOUND notification, # check for translation and show it manually # if not result.getTranslation(): self.SetStatusText(errortype.NOT_FOUND.getMessage()) try: transUnicode = str(result.translation, self.activeDictionary.getEncoding()) except Exception as e: systemLog(ERROR, "Unable to decode translation in %s (%s)" \ % (self.activeDictionary.getEncoding(), e)) title = errortype.INVALID_ENCODING.getMessage() msg = _("Translation cannot be displayed using selected " \ "encoding %s. Please try another encoding from " \ "View > Character Encoding menu.") \ % self.activeDictionary.getEncoding() self.SetStatusText(title) errorwin.showErrorMessage(title, msg) return transPreparedForWX = enc.toWX(transUnicode) self.htmlWin.SetPage(transPreparedForWX) self.history.add(transPreparedForWX) # FIXME: Nasty names # Where it is used? htmlWin.GetPage self.htmlCode = transPreparedForWX if not self.wordListHidden(): if not self.__searchedBySelecting: self.wordList.Clear() toUnicode = lambda s: str( s, self.activeDictionary.getEncoding()) wordsInUnicode = list(map(toUnicode, result.words)) wordsPreparedForWX = list(map(enc.toWX, wordsInUnicode)) self.wordList.InsertItems(wordsPreparedForWX, 0) self.words = wordsPreparedForWX if not self.__searchedBySelecting: matches = self.wordList.GetCount() if matches == 1: self.SetStatusText(_("1 word matches")) elif matches > 1: self.SetStatusText(_("%d words match") % matches) else: self.SetStatusText(_("Done")) if self.history.canBack(): self.buttonBack.Enable(1) self.search = None def onTimerClipboard(self, event): """Clipboard timer, used to watch new text in a clipboard""" def getText(): do = wx.TextDataObject() text = None wx.TheClipboard.Open() if wx.TheClipboard.GetData(do): try: text = do.GetText().strip() except Exception as e: print(e) wx.TheClipboard.Close() return enc.toWX(text) text = getText() old_text = '' if hasattr(self, 'old_clipboard_text'): old_text = self.old_clipboard_text if text and text != old_text: self.entry.SetValue(text) self.onSearch(None) self.old_clipboard_text = text def onUseScanClipboard(self, event): """Scan Clipboard menu item selected""" if event and event.GetInt(): self.timerClipboard.Start(self.scanTimeout) else: self.timerClipboard.Stop() def onSearch(self, event): if self.activeDictionary == None: if len(self.app.dictionaries): title = _("No dictionary activated") msg = _("No dictionary activated. Please select one from "\ "\"Dictionaries\" menu and try again.") else: title = _("No dictionaries installed") msg = _("There is no dictionaries installed. You can " \ "install one by selecting Tools > Manage " \ "Dictionaries > Available") errorwin.showErrorMessage(title, msg) return if self.search and not self.search.isDone(): self.onStop(None) word = self.entry.GetValue().strip() if word == "": self.SetStatusText(_("Please enter some text and try again")) self.entry.SetFocus() return global lastLookupWord lastLookupWord = word wx.BeginBusyCursor() self.__searchedBySelecting = 0 self.SetStatusText(_("Searching...")) self.timerSearch.Stop() self.search = None self.buttonStop.Enable(1) self.entry.Disable() self.timerSearch.Start(self.delay) word = enc.fromWX(word) try: word = word.encode(self.activeDictionary.getEncoding()) except Exception as e: # FIXME: Code duplicates self.buttonStop.Disable() self.entry.Enable(True) self.timerSearch.Stop() self.SetStatusText(_('Stopped')) wx.EndBusyCursor() systemLog(ERROR, "Unable to decode '%s': %s" % (word.encode('UTF-8'), e)) title = _("Encode Failed") msg = _("Unable to encode text \"%s\" in %s for \"%s\". " "That logically means the word " "definition does not exist in the dictionary.") \ % (enc.toWX(word), self.activeDictionary.getEncoding(), self.activeDictionary.getName()) errorwin.showErrorMessage(title, msg) return self.search = Process(self.activeDictionary.search, word) def onBack(self, event): self.buttonForward.Enable(1) self.htmlWin.SetPage(self.history.back()) if not self.history.canBack(): self.buttonBack.Disable() def onForward(self, event): self.buttonBack.Enable(1) self.htmlWin.SetPage(self.history.forward()) if not self.history.canForward(): self.buttonForward.Disable() def onStop(self, event): self.entry.Enable(1) self.SetStatusText(_("Stopped")) self.timerSearch.Stop() self.timerLoad.Stop() if self.search: self.search.stop() self.search = None if self.load: self.load.stop() self.load = None wx.EndBusyCursor() self.buttonStop.Disable() def onClean(self, event): self.entry.SetValue("") self.entry.SetFocus() def onKeyDown(self, event): """Key down event handler.""" if event.GetKeyCode() == wx.WXK_ESCAPE: self.onClean(None) event.Skip() def onClearHistory(self, event): self.entry.Clear() self.history.clear() self.buttonBack.Disable() self.buttonForward.Disable() def wordListHidden(self): """Returns True if word list marked to be hidden, False otherwise""" if self.wlHidden: return True return False def onHideUnhide(self, event): if self.wordListHidden(): self.unhideWordList() else: self.hideWordList() def onOpenDictConn(self, event): window = DictConnWindow(self, -1, _("Connect to DICT server"), style=wx.DEFAULT_FRAME_STYLE) window.CentreOnScreen() window.Show(True) def onCloseDict(self, event): """Clear widgets and set messages""" # If there was a registered dict, set it's default encoding # FIXME: new way try: if self.dict.name in list(self.app.config.registers.keys()): self.app.config.registers[ self.dict.name][2] = self.app.config.encoding except: pass self.wordList.Clear() self.htmlWin.SetPage("") self.SetTitle("OpenDict") self.words = [] if self.activeDictionary: self.activeDictionary.stop() self.activeDictionary = None self.SetStatusText(_("Choose a dictionary from \"Dictionaries\" menu")) def onCopy(self, event): self.do = wx.TextDataObject() self.do.SetText(self.htmlWin.SelectionToText()) wx.TheClipboard.Open() wx.TheClipboard.SetData(self.do) wx.TheClipboard.Close() def onPaste(self, event): """This method is invoked when Paste menu item is selected""" do = wx.TextDataObject() wx.TheClipboard.Open() if wx.TheClipboard.GetData(do): try: self.entry.SetValue(do.GetText()) except: self.SetStatusText(_("Failed to copy text from the clipboard")) else: self.SetStatusText(_("Clipboard contains no text data")) wx.TheClipboard.Close() def onPronounce(self, event): """Pronouce word using external software.""" word = self.entry.GetValue().strip() if word: cmd = self.app.config.get( 'pronunciationCommand') or prefswin.PRON_COMMAND if self.app.config.get('pronounceTrans') == 'True': word = html2text(self.htmlCode) import locale localeCharset = locale.getpreferredencoding() try: word = word.replace('(', '').replace(')', '').replace( '\n', '').replace('\r', '').replace('"', '\\"') cmd = (cmd % word).encode(localeCharset) Process(os.system, cmd) except Exception as e: traceback.print_exc() title = _("Error") msg = _("Unable to decode text using your locale charset %s" \ % localeCharset) errorwin.showErrorMessage(title, msg) def onShowGroupsWindow(self, event): """This method is invoked when Groups menu item is selected""" self.groupsWindow = GroupsWindow(self, -1, _("Groups"), size=(330, 150), style=wx.DEFAULT_FRAME_STYLE) self.groupsWindow.CentreOnScreen() self.groupsWindow.Show(True) def onShowPluginManager(self, event): """This method is invoked when Dictionaries Manager menu item is selected""" try: self.pmWindow = PluginManagerWindow(self, -1, _("Manage Dictionaries"), size=(500, 500), style=wx.DEFAULT_FRAME_STYLE) self.pmWindow.CentreOnScreen() self.pmWindow.Show(True) except Exception as e: traceback.print_exc() systemLog(ERROR, "Unable to show prefs window: %s" % e) self.SetStatusText("Error occured, please contact developers (%s)" \ % e) def onShowFileRegistry(self, event): self.regWindow = FileRegistryWindow(self, -1, _("File Register"), size=(340, 200), style=wx.DEFAULT_FRAME_STYLE) self.regWindow.CentreOnScreen() self.regWindow.Show(True) def onShowDictEditor(self, event): editor = DictEditorWindow(self, -1, _("Create Dictionaries"), size=(400, 500), style=wx.DEFAULT_FRAME_STYLE) editor.CentreOnScreen() editor.Show(True) def onShowPrefsWindow(self, event): try: self.prefsWindow = PrefsWindow(self, -1, _("Preferences"), size=(-1, -1), style=wx.DEFAULT_FRAME_STYLE) self.prefsWindow.CentreOnScreen() self.prefsWindow.Show(True) except Exception as e: traceback.print_exc() systemLog(ERROR, "Unable to show preferences window: %s" % e) title = errortype.OPENDICT_BUG.getMessage() msg = errortype.OPENDICT_BUG.getLongMessage() errorwin.showErrorMessage(title, msg) def onDefault(self, event): # FIXME: Bad way. Try setting a few constants for each type # of dictionary and then check this type instead of IDs. eventID = event.GetId() if eventID in list(self.app.config.ids.keys()): dictionary = self.app.dictionaries.get( self.app.config.ids.get(eventID)) self.loadDictionary(dictionary) label = self.menuDict.FindItemById(eventID).GetItemLabelText() self.app.config.set('defaultDict', label) elif 2100 <= eventID < 2500: label = self.menuEncodings.FindItemById(eventID).GetItemLabelText() self.changeEncoding(label) elif 2500 <= eventID < 2600: label = self.menuFontFace.FindItemById(eventID).GetItemLabelText() self.changeFontFace(label) elif 2600 <= eventID < 2700: label = self.menuFontSize.FindItemById(eventID).GetItemLabelText() self.changeFontSize(label) def checkIfNeedsList(self): """Unhides word list if current dictionary uses it""" if self.activeDictionary.getUsesWordList(): if self.wordListHidden(): self.unhideWordList() else: if not self.wordListHidden(): self.hideWordList() def addDictionary(self, dictInstance): """Add dictionary to menu and updates ids""" app = wx.GetApp() app.dictionaries[dictInstance.getName()] = dictInstance unid = util.generateUniqueID() # Insert new menu item only if no same named dictionary exists #if not dictInstance.getName() in app.config.ids.values(): app.config.ids[unid] = dictInstance.getName() item = wx.MenuItem(self.menuDict, unid, dictInstance.getName()) self.Bind(wx.EVT_MENU, self.onDefault, id=unid) #self.menuDict.InsertItem(self.menuDict.GetMenuItemCount()-2, item) self.menuDict.InsertItem(0, item) def removeDictionary(self, name): """Remove dictionary from the menu""" item = self.menuDict.FindItem(name) if item: self.menuDict.Delete(item) def loadDictionary(self, dictInstance): """Prepares main window for using dictionary""" if not dictInstance: systemLog(ERROR, "loadDictionary: dictInstance is False") return # # Check licence agreement # licence = dictInstance.getLicence() if licence \ and not self.app.agreements.getAccepted(dictInstance.getPath()): if not miscwin.showLicenceAgreement(None, licence): from lib.gui import errorwin title = _("Licence Agreement Rejected") msg = _("You cannot use dictionary \"%s\" without accepting "\ "licence agreement") % dictInstance.getName() errorwin.showErrorMessage(title, msg) return else: self.app.agreements.addAgreement(dictInstance.getPath()) self.onCloseDict(None) self.activeDictionary = dictInstance if dictInstance.getType() in dicttype.indexableTypes: if plaindict.indexShouldBeMade(dictInstance): # Notify about indexing from lib.gui import errorwin title = _("Dictionary Index") msg = _("This is the first time you use this dictionary or it " \ "has been changed on disk since last indexing. " \ "Indexing is used to make search more efficient. " \ "The dictionary will be indexed now. It can take a few " \ "or more seconds.\n\n" \ "Press OK to continue...") errorwin.showInfoMessage(title, msg) # Make index try: wx.BeginBusyCursor() plaindict.makeIndex(dictInstance, self.app.config.get('encoding')) wx.EndBusyCursor() except Exception as e: wx.EndBusyCursor() traceback.print_exc() title = _("Index Creation Error") msg = _("Error occured while indexing file. " \ "This may be because of currently selected " \ "character encoding %s is not correct for this " \ "dictionary. Try selecting " \ "another encoding from View > Character Encoding " \ "menu") % self.app.config.get('encoding') from lib.gui import errorwin errorwin.showErrorMessage(title, msg) return # Load index try: wx.BeginBusyCursor() index = plaindict.loadIndex(dictInstance) self.activeDictionary.setIndex(index) wx.EndBusyCursor() except Exception as e: wx.EndBusyCursor() traceback.print_exc() title = _("Error") msg = _("Unable to load dictionary index table. " "Got error: %s") % e from lib.gui import errorwin errorwin.showErrorMessage(title, msg) return wx.BeginBusyCursor() self.activeDictionary.start() self.checkIfNeedsList() self.SetTitle(titleTemplate % dictInstance.getName()) self.SetStatusText(enc.toWX(_("Dictionary \"%s\" loaded") \ % dictInstance.getName())) self.entry.SetFocus() try: self.checkEncMenuItem(self.activeDictionary.getEncoding()) except Exception as e: systemLog(ERROR, "Unable to select encoding menu item: %s" % e) wx.EndBusyCursor() def loadPlugin(self, name): """Sets plugin as currently used dictionary""" systemLog(INFO, "Loading plugin '%s'..." % name) self.entry.Disable() self.dictName = name self.activeDictionary = self.app.dictionaries.get(name) self.checkIfNeedsList() self.SetTitle(titleTemplate % name) self.entry.Enable(1) self.SetStatusText("Done") # TODO: Set something more useful self.htmlWin.SetPage("") # FIXME: deprecated, update! def loadRegister(self, name): self.SetTitle(titleTemplate % name) # TODO: should be set after loading item = self.app.config.registers[name] self.dictName = name self.entry.Disable() if item[1] == "dwa": self.timerLoad.Start(self.delay) self.load = Process(SlowoParser, item[0], self) elif item[1] == "mova": self.timerLoad.Start(self.delay) self.load = Process(MovaParser, item[0], self) elif item[1] == "tmx": self.timerLoad.Start(self.delay) self.load = Process(TMXParser, item[0], self) elif item[1] == "dz": self.timerLoad.Start(self.delay) self.load = Process(DictParser, item[0], self) else: self.SetStatusText(_("Error: not supported dictionary type")) return self.app.config.encoding = item[2] self.checkEncMenuItem(self.app.config.encoding) def changeEncoding(self, name): self.app.config.set('encoding', misc.encodings[name]) if self.activeDictionary: print("Setting encoding %s for dictionary %s" % \ (self.app.config.get('encoding'), self.activeDictionary.name)) self.activeDictionary.setEncoding(self.app.config.get('encoding')) systemLog(INFO, "Dictionary encoding set to %s" \ % self.activeDictionary.getEncoding()) plaindict.savePlainConfiguration(self.activeDictionary) def changeFontFace(self, name): """Save font face changes""" self.app.config.set('fontFace', misc.fontFaces[name]) self.updateHtmlScreen() def changeFontSize(self, name): fontSize = int(name) * 10 systemLog(INFO, "Setting font size %d" % fontSize) self.app.config.set('fontSize', fontSize) self.updateHtmlScreen() def updateHtmlScreen(self): """Update HtmlWindow screen""" self.htmlWin.SetFonts(self.app.config.get('fontFace'), "Fixed", [int(self.app.config.get('fontSize'))] * 7) self.htmlWin.SetPage(self.htmlCode) def onIncreaseFontSize(self, event): """Increase font size""" self.app.config.set('fontSize', int(self.app.config.get('fontSize')) + 2) self.updateHtmlScreen() def onDecreaseFontSize(self, event): """Decrease font size""" self.app.config.set('fontSize', int(self.app.config.get('fontSize')) - 2) self.updateHtmlScreen() def onNormalFontSize(self, event): """Set normal font size""" self.app.config.set('fontSize', NORMAL_FONT_SIZE) self.updateHtmlScreen() def checkEncMenuItem(self, name): """Select menu item defined by name""" ename = "" for key in misc.encodings: if name == misc.encodings[key]: ename = key break if len(ename) == 0: systemLog(ERROR, "Something wrong with encodings (name == None)") return self.menuEncodings.FindItemById( self.menuEncodings.FindItem(ename)).Check(1) def getCurrentEncoding(self): """Return currently set encoding""" # Is this the best way for keeping it? return self.app.config.encoding def onAddDict(self, event): installer = Installer(self, self.app.config) installer.showGUI() def onAddFromFile(self, event): """Starts dictionary registration process""" fileDialog = wx.FileDialog(self, _("Choose dictionary file"), "", "", "", wx.FD_OPEN | wx.FD_MULTIPLE) if fileDialog.ShowModal() == wx.ID_OK: file = fileDialog.GetPaths()[0] else: fileDialog.Destroy() return flist = ["Slowo", "Mova", "TMX", "Dict"] msg = _("Select dictionary format. If you can't find\n" \ "the format of your dictionary, the register\n" \ "system does not support it yet.") formatDialog = wx.SingleChoiceDialog(self, msg, _("Dictionary format"), flist, wx.OK | wx.CANCEL) if formatDialog.ShowModal() == wx.ID_OK: format = formatDialog.GetStringSelection() else: formatDialog.Destroy() return fileDialog.Destroy() formatDialog.Destroy() return self.app.reg.registerDictionary(file, format, self.app.config.defaultEnc) def onAddFromPlugin(self, event): """Starts plugin installation process""" dialog = wx.FileDialog(self, _("Choose plugin file"), "", "", "", wx.FD_OPEN | wx.FD_MULTIPLE) if dialog.ShowModal() == wx.ID_OK: plugin.installPlugin(self.app.config, dialog.GetPaths()[0]) dialog.Destroy() def onManual(self, event): """Shows Manual window""" systemLog(WARNING, "Manual function is not impelemented yet") def onAbout(self, event): """Shows 'About' window""" aboutWindow = AboutWindow(self, -1, _("About"), style=wx.DEFAULT_DIALOG_STYLE) aboutWindow.CentreOnScreen() aboutWindow.Show(True) def onWordSelected(self, event): """Is called when word list item is selected""" if self.search and not self.search.isDone(): return self.__searchedBySelecting = 1 self.SetStatusText(_("Searching...")) self.buttonStop.Enable(1) self.timerSearch.Start(self.delay) word = event.GetString() global lastLookupWord lastLookupWord = word self.entry.SetValue(word) word = enc.fromWX(word) word = word.encode(self.activeDictionary.getEncoding()) self.search = Process(self.activeDictionary.search, word) wx.BeginBusyCursor() def createListPanel(self): self.panelList = wx.Panel(self.splitter, -1) sbSizerList = wx.StaticBoxSizer( wx.StaticBox(self.panelList, -1, _("Word List")), wx.VERTICAL) self.wordList = wx.ListBox(self.panelList, 154, wx.Point(-1, -1), wx.Size(-1, -1), self.words, wx.LB_SINGLE) sbSizerList.Add(self.wordList, 1, wx.ALL | wx.EXPAND, 0) self.panelList.SetSizer(sbSizerList) self.panelList.SetAutoLayout(True) sbSizerList.Fit(self.panelList) def hideWordList(self): """Hides word list""" systemLog(DEBUG, "Hiding word list...") self.splitter.SetSashPosition(0) self.splitter.Unsplit(self.panelList) self.wlHidden = True # And change the button pixmap bmp = wx.Bitmap( os.path.join(info.GLOBAL_HOME, "pixmaps", "unhide.png"), wx.BITMAP_TYPE_PNG) self.buttonHide.SetBitmapLabel(bmp) self.buttonHide.SetToolTip(_("Show word list")) self.buttonHide.Show(False) def unhideWordList(self): """Shows word list""" systemLog(DEBUG, "Showing word list...") self.createListPanel() self.splitter.SplitVertically(self.panelList, self.panelHtml) self.splitter.SetSashPosition(int(self.app.config.get('sashPos'))) self.wlHidden = False # And change the pixmap bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME, "pixmaps", "hide.png"), wx.BITMAP_TYPE_PNG) self.buttonHide.SetBitmapLabel(bmp) self.buttonHide.SetToolTip(_("Hide word list")) def onPrint(self, event): """This method is invoked when print menu item is selected""" try: self.printer.PrintText(self.htmlCode) except Exception as e: self.SetStatusText(_("Failed to print")) systemLog(ERROR, "Unable to print translation (%s)" % e) traceback.print_exc() def onPreview(self, event): """This method is invoked when preview menu item is selected""" try: self.printer.PreviewText(self.htmlCode) except Exception as e: systemLog(ERROR, "Unable to preview translation (%s)" % e) self.SetStatusText(_("Page preview failed")) traceback.print_exc() def savePreferences(self): """Saves window preferences when exiting""" if self.app.config.get('saveWindowSize'): self.app.config.set('windowWidth', self.GetSize()[0]) self.app.config.set('windowHeight', self.GetSize()[1]) if self.app.config.get('saveWindowPos'): self.app.config.set('windowPosX', self.GetPosition()[0]) self.app.config.set('windowPosY', self.GetPosition()[1]) if self.app.config.get('saveSashPos'): if not self.wordListHidden(): self.app.config.set('sashPos', self.splitter.GetSashPosition()) try: self.app.config.save() except Exception as e: systemLog(ERROR, "Unable to save configuration: %s" % e)