opendict-0.6.8/0000775000076400007640000000000013204646653013275 5ustar nerijusnerijusopendict-0.6.8/AUTHORS.txt0000664000076400007640000000065313204646653015167 0ustar nerijusnerijusOpenDict Authors ================ Last updated: 2007-06-20 o Martynas Jocius Maintainer and main developer o Kęstutis Biliūnas Debian developer, contributor o Linas Valiukas MacOS X port o Nerijus Baliūnas Developer of better MS Windows platform support o Mantas Kriaučiūnas Past developer opendict-0.6.8/ChangeLog0000664000076400007640000012554213204646653015060 0ustar nerijusnerijus2017-11-20 nerijus * strip whitespace when searching 2014-04-08 nerijus * PyXML is no longer needed 2006-02-15 18:29 mjoc * lib/gui/mainwin.py, po/lt.po, po/opendict.pot: Window "Edit Dicitonaries" renamed to "Create Dictionaries". 2006-02-14 15:17 mjoc * po/: lt.po, opendict.pot: Translation updated. 2006-02-13 02:08 nerijus * lib/gui/mainwin.py: clear search field on ESC, implements feature request 1351220 2006-02-12 22:10 nerijus * po/lt.po, win32/setup.manifest.py, win32/setup.py: Version changed to 0.6.1 2006-02-12 20:59 mjoc * po/: lt.po, opendict.pot: Translation (po) file updated. 2006-02-12 20:56 mjoc * lib/gui/dictconnwin.py, po/opendict.pot: Bug fix: encoding has not been really used after chaning it in DictConnection dialog. 2006-02-12 02:53 mjoc * ChangeLog, opendict.1, po/lt.po, po/opendict.pot: Manual page added. ChangeLog updated. 2006-01-28 16:45 mjoc * opendict.py, lib/info.py, lib/logger.py, lib/gui/dictconnwin.py, lib/gui/helpwin.py, lib/gui/mainwin.py: 1. Debug logger messages minimized; 2. DICT connection window sets encoding on the main window menu; 3. Version changed to 0.6.1; 2006-01-08 23:12 nerijus * lib/misc.py: fixed spelling 2006-01-08 14:14 mjoc * lib/config.py, lib/gui/dictconnwin.py, po/lt.po, po/opendict.pot: DICT connection window changes: 1) New encoding selection entry added. 2) Windows remembers last server and encoding used. 2005-12-26 20:04 nerijus * lib/: misc.py, parser.py, gui/mainwin.py: fixed grammar 2005-12-26 19:42 nerijus * lib/parser.py: removed duplicated line 2005-11-10 13:45 mjoc * lib/parser.py: If invalid line is found while parsing Slowo format dictionary, error message is written to system.log. Until this bug fix exception had not been cached. 2005-11-02 22:12 mjoc * copying.html: FSF address updated. 2005-11-02 21:58 mjoc * lib/: tests/test_editor.py, extra/html2text.py: First line with #!/exec/path removed. 2005-10-26 00:19 nerijus * win32/compile.bat: copy msvcr71.dll 2005-10-25 17:42 mjoc * TODO.txt, opendict.py, po/opendict.pot: Very small changes: one more todo item, etc. 2005-10-25 16:51 nerijus * win32/: setup.manifest.py, setup.py: updated version to 0.6.0 2005-10-24 22:39 mjoc * ChangeLog: New ChangeLog generated using cvs2cl utility. 2005-10-24 22:04 mjoc * lib/gui/mainwin.py, po/lt.po, po/opendict.pot: Show/Hide button removed (hidden) from the main window, menu item of the same functionality added. Lithuanian translation updated. 2005-10-20 18:26 mjoc * lib/info.py: Version changed to 0.6.0. Going to release stable version 0.6.0. 2005-10-20 18:22 mjoc * misc/opendict.desktop: Name changed from "OpenDict" to "Dictionary OpenDict". More intuitive. 2005-09-06 22:59 mjoc * doc/Plugin-HOWTO.html: Simple plugin example section written. Needs more detailed instructions in the future. 2005-08-31 11:39 mjoc * doc/Plugin-HOWTO.html: Introduction, Types od OpenDict Dictionaries and Plain Dictionary Example sections written. 2005-08-30 00:27 mjoc * doc/: OpenDict_plugin_dev.txt, Plugin-HOWTO.html, Specification.txt: Old plugin-dev doc removed, spefication removed, new plugin-dev howto added (not finished yet). 2005-08-17 19:46 mjoc * pixmaps/: icon-24x24.png, icon-32x32.png, icon-48x48.png, icon-620x620.png, icon-96x96.png, SVG/icon-rune.svg: Icon improved a bit by adding some color transitioning. 2005-08-06 23:37 mjoc * TODO.txt, lib/gui/mainwin.py, lib/gui/prefswin.py, po/lt.po, po/opendict.pot: Option for default clipboard scanner use added into preferences window. 2005-08-05 22:02 mjoc * TODO.txt, lib/info.py, lib/gui/mainwin.py, po/opendict.pot: Version changed to 0.5.9-CVS, clipboard-scanned text is trimmed before searching for translation. New TODO entries added. 2005-06-14 00:47 nerijus * README.txt, TODO.txt: updated README; converted to unix line endings 2005-06-13 23:58 nerijus * README.txt, opendict.py, lib/info.py: improved error message when PyXML is missing, so thhat Fedora users know which package they are missing; bumped version to 0.5.8 2005-06-10 23:35 mjoc * lib/tests/data/sampleplugin/sample.py: Sample plugin for unit testing updated to work with new module tree after adding 'lib' to import path. 2005-06-10 23:17 mjoc * po/: lt.po, opendict.pot: lt.po merging conflict resolved. 2005-06-10 23:10 mjoc * AUTHORS.txt: Added authors file. 2005-06-10 23:04 mjoc * ChangeLog, lib/gui/helpwin.py, lib/gui/mainwin.py, po/lt.po, po/opendict.pot: 1. Controls are enabled before showing search results 2. Nerijus B. added to authors list. 2005-05-31 14:34 nerijus * opendict.py: ask unicode wx version; it still can use ansi version if unicode is not available 2005-05-24 18:05 nerijus * Makefile: simplified install/uninstall 2005-05-16 21:53 mjoc * lib/info.py, lib/newplugin.py, lib/util.py, lib/gui/mainwin.py, po/lt.po, po/opendict.pot: wx.EndBusyCursor bug fixed, no error message on Windows build. Name correction is not used until correct functionality is achieved. 2005-04-29 03:18 nerijus * win32/setup.py: no changes 2005-04-29 03:16 nerijus * win32/: compile.bat, setup.manifest.py: added setup script with manifest 2005-04-29 02:27 nerijus * win32/compile.bat: copy license file manually 2005-04-29 02:09 nerijus * win32/compile.bat: encodings work with py2exe 2005-04-28 06:03 nerijus * lib/info.py: py2exe now works 2005-04-28 05:58 nerijus * opendict.py, lib/info.py, win32/compile.bat, win32/setup.py: py2exe now works 2005-04-27 18:56 mjoc * opendict.py: wxPython 2.5 is selected only if application is not frozen (i.e. compiled using py2exe) 2005-04-27 18:46 mjoc * opendict.py, lib/enc.py: OpenDict now supports wxPython multiversioning. If both wxPython 2.4 and 2.5 are installed on the same system, version 2.5 is used. 2005-04-27 15:54 nerijus * win32/make.py: use python24 2005-04-27 01:02 mjoc * lib/gui/helpwin.py: One more developer Nerijus Baliunas added to "Thanks" window. 2005-04-27 00:43 mjoc * lib/newplugin.py: Some plugins were not working because of deleted sys.modules item after loading plugin. Now just old item is deleted _before_ loding it. 2005-04-27 00:25 mjoc * lib/config.py, lib/info.py, po/opendict.pot: Version changed to 0.5.8-CVS, default window size smaller (370x550) 2005-04-27 00:08 mjoc * opendict.py, lib/installer.py, lib/newplugin.py, lib/plaindict.py, lib/util.py, lib/gui/mainwin.py, lib/gui/miscwin.py, po/lt.po, po/opendict.pot: InvalidDictWindow improved: one can remove invalid directories by pressing Remove button. Small bug fixes. 2005-04-26 19:13 mjoc * ChangeLog: ChangeLog added. 2005-04-26 19:10 mjoc * opendict.py, lib/installer.py, lib/xmltools.py, lib/gui/prefswin.py, po/Makefile, po/lt.po, po/opendict.pot: 1. Default dictionary value encoding fixed. 2. wxPython version is checked using wx module and wxPython on failure. 2005-04-24 14:21 mjoc * README.txt: New information for Windows users added. 2005-04-23 21:17 mjoc * opendict.py, lib/tests/test_editor.py, lib/tests/test_plugin.py, po/opendict.pot: Removed code using "from wxPython import *" imported objects. 2005-04-23 21:02 mjoc * win32/compile.bat: Windows batch file for simplifying py2exe process added. 2005-04-22 00:45 mjoc * lib/gui/mainwin.py, po/lt.po, po/opendict.pot: LT translation updated, small changes. 2005-04-22 00:37 mjoc * lib/gui/dicteditorwin.py, po/lt.po, po/opendict.pot: Lithuanian translation updated. 2005-04-21 22:49 mjoc * opendict.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: 1. After dict installation Install button is disabled. 2. wxPython version is written to log when starting 3. Dict manager clears info about dict after removing it 2005-04-17 01:59 mjoc * README.txt, TODO.txt: README and TODO updated. 2005-04-17 01:55 mjoc * lib/errortype.py, lib/util.py, lib/gui/mainwin.py, po/lt.po, po/opendict.pot: Additional translating strings updated. 2005-04-17 01:36 mjoc * lib/errortype.py, lib/util.py, lib/gui/pluginwin.py, po/lt.po, po/opendict.pot: Lithuanian translation updated. Few bus fixed. 2005-04-17 00:50 mjoc * lib/gui/dictconnwin.py: Grammar mistake fixed: Connectio 2005-04-16 23:16 mjoc * po/: lt.po, opendict.pot: Translation updated. 2005-04-11 13:12 mjoc * lib/gui/mainwin.py, po/opendict.pot: Trailing '\r' removed from mainwin.py, opendict.pot updated. 2005-04-10 11:30 mjoc * po/unix_proceed.sh: Removed. 2005-04-10 11:08 mjoc * po/: messages.pot, opendict.pot: po/lt/ directory removed, message.pot removed, opendict.pot added. 2005-04-10 11:03 mjoc * po/: Makefile, lt.po: opendict.po not removed. 2005-04-09 23:48 mjoc * opendict.py, lib/info.py, lib/logger.py, lib/util.py: Needed directories are created before proceeding with app load. 2005-04-02 19:54 mjoc * opendict.py: Import error bug fix for showing error message about old wxPython version. 2005-04-02 00:25 mjoc * lib/util.py: AgreementManager removes non existent directories. 2005-04-01 20:49 mjoc * lib/: config.py, gui/mainwin.py, gui/pluginwin.py, gui/prefswin.py: URL for dictionaries list file is taken from configuration file now. Small improvements of output messages. 2005-03-31 22:14 mjoc * lib/gui/mainwin.py: MainWindow.loadDictionary(): returns if dictInstance is None. 2005-03-31 20:49 mjoc * lib/gui/mainwin.py: Error message about invalid dictinaries enhanced. 2005-03-29 19:56 mjoc * opendict.py, lib/gui/mainwin.py: Very small bug fix in grammar (message about invalid dictionaries). 2005-03-28 00:29 mjoc * lib/gui/: dicteditorwin.py, mainwin.py: "Save As" button added to DictEditor. 2005-03-27 23:38 mjoc * Makefile: New Makefile style. 2005-03-27 23:36 mjoc * po/: Makefile, lt.po: Makefile for translation files added. 2005-03-27 23:28 mjoc * lib/: installer.py, gui/mainwin.py: Error message is shown when word fails to be encoded in dictionary's own encoding. 2005-03-27 16:51 mjoc * lib/gui/pluginwin.py: Dictionaries are sorted by name in both views. 2005-03-27 16:41 mjoc * lib/gui/mainwin.py: Menu item form scanning clipboard renamed to "Take ..." 2005-03-27 16:33 mjoc * lib/gui/prefswin.py: Dictionary list is sorted in PreferencesWindow. 2005-03-27 15:58 mjoc * lib/gui/mainwin.py: Font size is increased using Ctrl-= instead of Ctrl-+. 2005-03-27 15:25 mjoc * lib/: config.py, gui/prefswin.py: Removed groups and registers setting from configuration as it is outdated and not used anymore. 2005-03-27 15:13 mjoc * lib/gui/mainwin.py: Tooltips added from text entry and lookup button. 2005-03-27 14:50 mjoc * lib/gui/: helpwin.py, mainwin.py: Minimal window width is a bit smaller (320 pixels), "Lookup Up" menu item bug fixed, LicenceWindow widget arrangement improved. 2005-03-27 14:17 mjoc * lib/gui/mainwin.py: MainWindow can be resized to even more smaller window, "Search" button renamed to "Lookup Up" button. "Not Found" message is shown even if plugin does not return error code. 2005-03-27 04:00 mjoc * lib/gui/helpwin.py: Thanks page added to CreditsWindow. 2005-03-27 02:39 mjoc * lib/: xmltools.py, gui/helpwin.py: 1. Buttons made smaller in AboutWindow. 2. Index is written in binary mode. 2005-03-27 02:33 mjoc * lib/gui/: mainwin.py, pluginwin.py: Clipboard scan feature added. 2005-03-26 23:47 mjoc * pixmaps/icon-32x32.png: 32x32 size icon added, for Windows platform. 2005-03-26 21:52 mjoc * scripts/make-addons-list.py: [no log message] 2005-03-26 21:29 mjoc * scripts/make-addons-list.py: Bug fix, didn't fetched description from plugins. 2005-03-26 21:06 mjoc * opendict.py, lib/newplugin.py, lib/gui/dicteditorwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: 1. Error dialog added to notify about failed dictionaries 2. Wildcard bug fixed for DictEditor 2005-03-26 20:37 mjoc * lib/: util.py, gui/helpwin.py, gui/mainwin.py, gui/pluginwin.py: 1. Font style fixed for AboutWindow, didn't work on Windows platform. 2. Plugin ZIP files are opened in binary mode, didn't work on Windows too. 2005-03-26 20:31 mjoc * lib/gui/mainwin.py: After selecting a word busy cursor is started. 2005-03-26 20:27 mjoc * pixmaps/hide.png: Forgotten to upload in the past. 2005-03-26 18:33 mjoc * opendict.py, lib/config.py, lib/dicttype.py, lib/encodings.py, lib/group.py, lib/installer.py, lib/logger.py, lib/meta.py, lib/mywords.py, lib/newplugin.py, lib/parser.py, lib/plaindict.py, lib/util.py, lib/xmltools.py, lib/gui/dictaddwin.py, lib/gui/dictconnwin.py, lib/gui/dicteditorwin.py, lib/gui/errorwin.py, lib/gui/groupswin.py, lib/gui/helpwin.py, lib/gui/mainwin.py, lib/gui/miscwin.py, lib/gui/mywordswin.py, lib/gui/pluginwin.py, lib/gui/prefswin.py: Now lib/ dir is imported before any module because of problems with some same named built-in modules (i.e. parser) on Windows platform. Old files removed. 2005-03-26 18:06 mjoc * lib/__init__.py: Added, as lib dir is going to be imported itself. 2005-03-26 17:08 mjoc * lib/tests/test_editor.py: test_save changed to compare lengths. 2005-03-26 17:04 mjoc * lib/: plugin.py, register.py: Removed, not usable anymore. 2005-03-26 17:02 mjoc * opendict.py, lib/config.py, lib/info.py, lib/installer.py, lib/newplugin.py, lib/gui/helpwin.py, lib/gui/mainwin.py: 1. Global home directory is now the directory where opendict.py is located. 2. Old plugin.py and register.py are not imported anywhere. 2005-03-23 00:06 mjoc * lib/gui/pluginwin.py, scripts/make-addons-list.py: PluginWindow remembers addons variable after closing. Addons script outputs to opendict-add-ons.xml. 2005-03-22 23:47 mjoc * scripts/make-addons-list.py: Several bug fixes and improvements. 2005-03-22 23:10 mjoc * scripts/make-addons-list.py: Script for auto-generating addons list added. 2005-03-22 14:37 mjoc * TODO.txt: New TODO entry. 2005-03-22 02:34 mjoc * lib/gui/pluginwin.py: I'm not sure if this is fixed now, but sometime download progress dialog does not close. For the moment it works correctly. 2005-03-22 02:15 mjoc * lib/: util.py, gui/pluginwin.py: Status messages improved. 2005-03-22 01:29 mjoc * lib/installer.py: Custom installation support for dictionaries added. Runs install.install() if founds install.py. 2005-03-21 22:58 mjoc * TODO.txt, lib/errortype.py, lib/installer.py, lib/parser.py, lib/gui/mainwin.py: DictParser fixed, word is not encoded twice anymore. 2005-03-21 21:10 mjoc * lib/: util.py, gui/pluginwin.py: 1. "Done" is shown when DownloadManager finishes download. 2. No message is shown after cancelling file download. 2005-03-21 21:05 mjoc * lib/gui/: dicteditorwin.py, mainwin.py: Busy cursor is shown while loading dictionary in main window and opening file in editor window. 2005-03-21 20:55 mjoc * lib/gui/dictconnwin.py: Error dialog is shown if unable to connect to server. 2005-03-21 20:39 mjoc * lib/parser.py: MovaParser fixed, word is not encoded 2005-03-21 11:40 mjoc * lib/: parser.py, plaindict.py, gui/mainwin.py: Small improvements. 2005-03-20 18:30 mjoc * lib/gui/mainwin.py: Standard "Find" stock button replaced with simple "Search" button. 2005-03-20 18:12 mjoc * lib/: config.py, gui/mainwin.py: "Find" item added to "File" menu. 2005-03-16 20:57 mjoc * lib/: installer.py, gui/mainwin.py, gui/pluginwin.py: Dictionary name is added to installed list on PluginWindow after installing new dictionary from PluginWindow. 2005-03-16 19:52 mjoc * lib/: installer.py, plaindict.py, xmltools.py, gui/pluginwin.py: Description support for registers added. 2005-03-16 19:09 mjoc * Makefile, lib/installer.py, lib/newplugin.py, lib/plaindict.py, lib/xmltools.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: 1. Version and authors info support to registers added. 2. Bugfixes and improvements in PluginWindow. 2005-03-16 17:03 mjoc * lib/gui/miscwin.py: Miscellaneous GUI classes. 2005-03-11 22:58 mjoc * lib/gui/: helpwin.py, prefswin.py: Very small GUI improvements. 2005-03-11 21:28 mjoc * copying.html, copying.txt, lib/gui/helpwin.py: 1. GNU GPL is shown in HTML window 2. Removed licence text version 3. Added licence HTML version 2005-03-11 21:09 mjoc * opendict.py, lib/info.py, lib/meta.py, lib/newplugin.py, lib/plaindict.py, lib/util.py, lib/xmltools.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: 1. Licence agreement subsystem added for ability to add licence agreement for register or plugin. 2. File path is made to be found automatically when not defined for registered ddictionaries and plugins. 2005-03-11 18:28 mjoc * ChangeLog: Changelog file is generated from CVS logs. 2005-03-11 18:16 mjoc * lib/gui/: mainwin.py, pluginwin.py, prefswin.py: Loads default dictionary on startup. Normal font bug fixed. 2005-03-07 11:25 mjoc * ChangeLog, opendict.py, lib/installer.py, lib/newplugin.py, lib/plaindict.py, lib/util.py, lib/xmltools.py, lib/gui/dicteditorwin.py, lib/gui/helpwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py, lib/gui/prefswin.py: Lots of small changes. 2005-03-04 17:31 mjoc * ChangeLog, lib/gui/mainwin.py: Small changes. 2005-03-04 17:29 mjoc * lib/gui/: helpwin.py, mainwin.py: Close button in LicenceWindow right-aligned. 2005-03-04 17:26 mjoc * lib/gui/prefswin.py: Buttons are right-aligned in PreferencesWindow. 2005-03-04 17:24 mjoc * lib/gui/prefswin.py: "Save" button removed from PreferencesWindow. 2005-03-04 17:15 mjoc * lib/: installer.py, gui/mainwin.py, gui/pluginwin.py: "Install From File" button added to PluginManager. 2005-03-04 16:59 mjoc * TODO.txt, lib/dicttype.py, lib/meta.py, lib/parser.py, lib/plaindict.py, lib/gui/mainwin.py: New function added for writing current dictionary configuration to disk. It is used after indexing and changing text encoding now. 2005-03-04 15:47 mjoc * lib/config.py: Window size/position are now saved by default. 2005-03-04 15:46 mjoc * lib/gui/mainwin.py: Font face/size changing fixed after damage while rewriting configuration hanfler. 2005-03-04 13:32 mjoc * lib/gui/mainwin.py: Sash position is saved only if word list is not hidden when exiting. 2005-03-04 11:36 mjoc * lib/gui/pluginwin.py: OpenDict repository opendict-addons.xml file URL changed to http://files.akl.lt/~mjoc/OpenDict/Data/opendict-addons.xml. Temporarily. 2005-03-03 09:27 mjoc * lib/: config.py, gui/mainwin.py: Small fixes. 2005-03-03 09:15 mjoc * pixmaps/stop.png: Stop PNG icon added. 2005-03-03 08:52 mjoc * lib/: config.py, gui/dictconnwin.py, gui/prefswin.py: Finished with DictConnectionWindow after reimpelenting new configuration handler. 2005-03-03 01:49 mjoc * lib/misc.py: Unsaved changes commited. 2005-03-03 01:34 mjoc * opendict.py, lib/config.py, lib/misc.py, lib/xmltools.py, lib/gui/mainwin.py, lib/gui/prefswin.py: Configuration subsystem rewritten. Now configuration is stored in XML file. 2005-03-02 23:44 mjoc * lib/gui/mainwin.py: Stop button added. 2005-03-02 23:33 mjoc * lib/gui/mainwin.py: Search history for entry field enabled. 2005-03-02 23:21 mjoc * lib/gui/helpwin.py: About window Credits section unicode problem fixed. 2005-03-02 23:15 mjoc * lib/: errortype.py, parser.py, gui/dictconnwin.py, gui/mainwin.py: 1. DictConnectionWindow fixed and improved. 2. Other small changes. 2005-03-01 00:28 mjoc * lib/gui/pluginwin.py: [no log message] 2005-03-01 00:26 mjoc * lib/: dicteditor.py, gui/dicteditorwin.py, gui/pluginwin.py: Editor window almost read for real using. 2005-02-28 22:29 mjoc * opendict.py, lib/installer.py, lib/gui/pluginwin.py: 1. Installer notificates about successful installation 2. PluginManager remembers available dictionaries list for one session 2005-02-27 22:24 mjoc * lib/gui/: dicteditorwin.py, mainwin.py, pluginwin.py: 1. PluginManager and DictEditor uses icon 2. Main window title is set using titleTemplate 2005-02-27 14:59 mjoc * lib/: dicteditor.py, gui/dicteditorwin.py, gui/mainwin.py, tests/test_editor.py: 1. New editor tests 2. Small MainWindow changes 3. EditorWindow improvements 2005-02-23 23:32 mjoc * lib/gui/dicteditorwin.py: [no log message] 2005-02-23 23:32 mjoc * TODO.txt, lib/installer.py, lib/newplugin.py: Editor window improved, some other small improvements. 2005-02-22 23:18 mjoc * lib/: dicteditor.py, gui/dicteditorwin.py, gui/mainwin.py, tests/test_editor.py, tests/test_plugin.py, tests/data/plugin.xml, tests/data/sampleplugin/plugin.xml: Editor window interface uses Editor class (not finished), tests fixed. 2005-02-22 22:23 mjoc * lib/: dicteditor.py, gui/dicteditorwin.py, gui/mainwin.py: Editor class, separate from GUI, added 2005-02-22 22:21 mjoc * lib/tests/data/sampledict.dwa: Sample dict for testing added 2005-02-22 22:20 mjoc * lib/tests/test_editor.py: Editor test added. 2005-02-18 18:16 mjoc * lib/: installer.py, plaindict.py, gui/pluginwin.py: Installer fixed to recongnize normal and plain dict plugins. 2005-02-17 10:23 mjoc * pixmaps/: icon-24x24.png, icon-48x48.png, icon-620x620.png, icon-96x96.png, SVG/icon-rune.svg: Icon color is made to be more yellow. 2005-02-16 21:00 mjoc * opendict.py, lib/info.py: Error report is shown when Python/XML module is not found. 2005-02-16 14:53 mjoc * opendict.py: If wxPython library is not installed, user-friendly message is outputed now. 2005-02-15 19:51 mjoc * lib/: errortype.py, installer.py, parser.py, plaindict.py, xmltools.py, gui/mainwin.py, gui/pluginwin.py: Plain/normal plugin installation system started. 2005-02-15 18:48 mjoc * pixmaps/: icon-24x24.png, icon-48x48.png, icon-620x620.png, icon-96x96.png: New PNGs made. 2005-02-15 18:45 mjoc * pixmaps/SVG/icon-rune.svg: Pages edges thinned. 2005-02-15 18:39 mjoc * pixmaps/SVG/icon-rune.svg: New icon with rune (sun) added. 2005-02-15 11:11 mjoc * pixmaps/SVG/icon.svg: Borders are even stronger now. 2005-02-15 10:57 mjoc * pixmaps/SVG/icon.svg: Book border made stronger. 2005-02-13 01:22 mjoc * run-opendict: run-script removed. 2005-02-13 01:21 mjoc * lib/gui/: errorwin.py, pluginwin.py: Ability to fetch add-ons list added. 2005-02-13 00:13 mjoc * opendict.py, lib/meta.py, lib/newplugin.py, lib/xmltools.py, lib/gui/pluginwin.py: * Add-ons list XML parser written * This parser integrated into pluginwin.py * Small fixes 2005-02-12 22:11 mjoc * opendict.py, lib/installer.py, lib/newplugin.py, lib/parser.py, lib/plaindict.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: Logger integrated in mainwin.py, newplugin.py, plaindict.py 2005-02-12 21:09 mjoc * opendict.py: Logger integrated. 2005-02-12 21:08 mjoc * lib/logger.py: Logger functions added. 2005-02-12 18:30 mjoc * lib/: errortype.py, gui/pluginwin.py: Information about dictionaries showing fixed. 2005-02-11 20:23 mjoc * opendict.py, lib/newplugin.py, lib/gui/mainwin.py: Some bug fixes. 2005-02-11 09:49 mjoc * pixmaps/: icon-24x24.png, icon-48x48.png, icon-620x620.png, icon-96x96.png, SVG/icon.svg: Icons renewed. 2005-02-08 23:25 mjoc * lib/gui/mainwin.py: Started using wx.NewId(), not finished 2005-02-08 23:13 mjoc * misc/opendict.desktop: .desktop file updated. 2005-02-08 23:10 mjoc * opendict.py, lib/installer.py, lib/newplugin.py, lib/plaindict.py, lib/plugin.py, lib/util.py, lib/gui/dictaddwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: Ability to remove dictionaries added (new style) 2005-02-08 20:10 mjoc * opendict.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: PluginManager window changes: installed and avail splitted using notebook. 2005-02-08 08:54 mjoc * lib/gui/pluginwin.py: Small changes on Plugin Manager. 2005-02-08 00:06 mjoc * lib/gui/pluginwin.py: Plugin window improved (buttons, list width) 2005-02-07 23:07 mjoc * lib/: installer.py, misc.py, parser.py, gui/mainwin.py, gui/pluginwin.py: Plugin manager window enhanced. 2005-02-06 01:47 mjoc * lib/: dicttype.py, errortype.py, installer.py, misc.py, parser.py, plaindict.py, gui/mainwin.py, gui/pluginwin.py: 1. DictParser rewritten to be more functional 2. TMXParser disabled 3. Plugin manager started rewriting 2005-02-05 20:15 mjoc * lib/: installer.py, plaindict.py, xmltools.py: XML configs are now written using PrettyPrint. 2005-02-05 19:25 mjoc * lib/parser.py: SlowoParser rewritten. 2005-02-04 16:32 mjoc * lib/parser.py: Reimplementing SlowoParser. 2005-02-04 13:40 mjoc * TODO.txt: New ideas. 2005-02-04 13:33 mjoc * TODO.txt, lib/parser.py: Minor changes. 2005-02-04 13:09 mjoc * lib/: installer.py, util.py: Needed directories are checked and created before installing dictionaries. 2005-02-04 12:35 mjoc * opendict.py, lib/gui/mainwin.py: Minor changes. 2005-02-04 11:25 mjoc * opendict.py, lib/gui/mainwin.py: wxPython 2.4 is not supported anymore. 2005-02-04 02:41 mjoc * lib/: dicttype.py, parser.py, plaindict.py, xmltools.py, gui/errorwin.py, gui/mainwin.py: Serveral changes: 1. Indexing (not finished) 2. MovaParser 2005-02-03 03:00 mjoc * opendict.py, lib/meta.py, lib/parser.py, lib/gui/mainwin.py: 1. MovaParser almost fixed 2. Related changes 2005-02-03 01:10 mjoc * opendict.py, lib/installer.py, lib/meta.py, lib/newplugin.py, lib/plaindict.py, lib/plugin.py, lib/util.py, lib/gui/mainwin.py: Dictionaries installation unified 2005-02-02 23:54 mjoc * lib/tests/test_plugin.py: ./test_plugin.py added (tests suite) 2005-02-02 23:53 mjoc * lib/tests/data/plugin.xml: ./data/plugin.xml added (tests suite) 2005-02-02 23:52 mjoc * lib/tests/data/sampleplugin/plugin.xml: ./data/sampleplugin/plugin.xml added (tests suite) 2005-02-02 23:52 mjoc * lib/tests/data/sampleplugin/sample.py: ./data/sampleplugin/sample.py added (tests suite) 2005-02-02 23:49 mjoc * lib/util.py: Utility module added. 2005-02-02 23:48 mjoc * lib/plaindict.py: Plain dictionaries management module added. 2005-02-02 23:47 mjoc * lib/newplugin.py: New-type plugins module 2005-02-02 23:46 mjoc * lib/meta.py: Metaclass module added. 2005-02-02 23:44 mjoc * lib/enc.py: Encoding module for unicode string 2005-02-02 23:43 mjoc * opendict.py, lib/dicttype.py, lib/info.py, lib/installer.py, lib/parser.py, lib/plugin.py, lib/xmltools.py, lib/gui/errorwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py: 1. Plugin and plain dictionaries load unified 2. Lots of changes everywhere 2005-02-02 00:39 mjoc * lib/: dicttype.py, info.py, installer.py, register.py, xmltools.py, gui/dicteditorwin.py, gui/errorwin.py, gui/mainwin.py, gui/pluginwin.py: XML tools 2005-02-01 19:58 mjoc * lib/: config.py, info.py, gui/helpwin.py, gui/mainwin.py: Changing home path variables. 2005-02-01 02:58 mjoc * lib/: parser.py, gui/dictconnwin.py: Some bug fixes for DICT protocol support 2005-02-01 02:50 mjoc * opendict.py, lib/config.py, lib/parser.py, lib/gui/mainwin.py, misc/opendict.desktop: Started unifying dictionary load. 2005-02-01 00:58 mjoc * pixmaps/icon-620x620.png: Large scale image 2005-02-01 00:53 mjoc * pixmaps/: icon-24x24.png, icon-48x48.png, icon-600x600.png, icon-96x96.png, SVG/icon.svg: Removed 2005-02-01 00:04 mjoc * opendict.py, lib/config.py, lib/info.py, lib/plugin.py, lib/gui/mainwin.py: 1. Unicode support imporoved 2. View menu added 3. Font size change added 4. Fonts increase/decrease functions added 2005-01-31 20:04 mjoc * lib/: encodings.py, parser.py, gui/mainwin.py: Encodings module added. 2005-01-31 00:14 mjoc * misc/opendict.desktop: Comment changed 2005-01-30 14:56 mjoc * TODO.txt, opendict.py, lib/gui/mainwin.py: Working on new dictionary engine. OpenDict is damaged at the moment! 2005-01-30 14:53 mjoc * lib/dicttype.py: Dictionary type module added 2005-01-30 14:52 mjoc * lib/: config.py, errortype.py, info.py, parser.py, plugin.py, register.py, gui/mainwin.py: Error type module added 2005-01-29 01:17 mjoc * Makefile, TODO.txt, opendict.py, lib/gui/dicteditorwin.py, lib/gui/helpwin.py, lib/gui/mainwin.py, misc/opendict.desktop: 1. Some GUI improvements (i.e. button tooltips) 2. Something about writing new TMX parser 3. Small changes 2005-01-28 23:55 mjoc * lib/gui/helpwin.py: New icon added to About window, info text changed. 2005-01-28 22:12 mjoc * pixmaps/SVG/icon.svg: SVG source for icon pixmap added. 2005-01-28 21:11 mjoc * pixmaps/: icon-600x600.png, icon.png: icon.png -> icon-600x600.png 2005-01-28 17:48 mjoc * pixmaps/: splash.png, icon-old.xpm, icon.ico, logo.xpm: Not used anymore 2005-01-28 16:55 mjoc * pixmaps/search.xpm: This image is not used anymore 2005-01-28 16:53 mjoc * pixmaps/: icon-24x24.png, icon-48x48.png, icon-96x96.png, icon.png: New icon by mjoc 2005-01-28 11:54 mjoc * pixmaps/: left.xpm, right.xpm: Removed. 2005-01-28 11:53 mjoc * pixmaps/: add.png, add.xpm: Removed 2005-01-28 11:52 mjoc * pixmaps/unhide.png: unhide.png added. 2005-01-28 11:52 mjoc * pixmaps/hide.xpm: hide.xpm replaced with hide.png. 2005-01-28 11:51 mjoc * lib/gui/mainwin.py: Main window now swaps hide/unhide pixmaps when button clicked. 2005-01-28 02:54 mjoc * scripts/install-odp.sh: Plugin manual installer added. 2005-01-28 02:53 mjoc * lib/: config.py, gui/mainwin.py: Code cleanup. 2005-01-28 02:44 mjoc * README.txt: Micro bug fix :-). 2005-01-28 02:40 mjoc * README.txt: More info added. 2005-01-28 02:35 mjoc * BUGS, Makefile, TODO.txt, misc/opendict.desktop: BUGS -> BUGS.txt 2005-01-28 02:30 mjoc * doc/Specification.txt: Specification added. 2005-01-28 02:27 mjoc * lib/: config.py, installer.py, misc.py, parser.py, gui/mainwin.py, gui/pluginwin.py, gui/prefswin.py: Small code fixes to improve unicode support somehow... 2005-01-27 23:54 mjoc * lib/gui/: mainwin.py, pluginwin.py: 1. Copy function now copies inly selected text. 2. Paste pastes text into the search entry. 3. Some small changes. 2005-01-27 22:52 mjoc * lib/gui/mainwin.py: Some main window menu improvements. 2005-01-25 00:13 mjoc * TODO.txt: New bug entry added. 2005-01-15 01:55 mjoc * opendict.py, lib/info.py, lib/plugin.py: Minor changes. 2005-01-15 01:54 mjoc * lib/gui/helpwin.py: About window info message reniewed. 2005-01-15 01:53 mjoc * lib/gui/mainwin.py: 1. Startup help message added. 2. Separator added to Tools menu. 3. About window info message reniewed. 2005-01-14 22:53 mjoc * lib/gui/: dictconnwin.py, helpwin.py, mainwin.py: 1. Title changed to " - OpenDict" 2. Copyright year 2005 added 3. Some small improvements 2005-01-14 22:29 mjoc * pixmaps/right.png: Forward button image added (PNG) 2005-01-14 22:29 mjoc * pixmaps/left.png: Back button image added. 2005-01-14 22:16 mjoc * lib/gui/mainwin.py: o Search bitmap button replaced with text button o Back and Forward button XPM pixmaps replaced with PNG images o stopButton commented out 2005-01-14 21:39 mjoc * lib/gui/mainwin.py: When dictionary is closed or another dictionary is opened, text entry is not cleared (this was requested by users). 2005-01-14 00:45 mjoc * scripts/make_hash.py: File ./scripts/make_hash.py added 2005-01-14 00:45 mjoc * scripts/unzip.py: File ./scripts/unzip.py added 2005-01-14 00:44 mjoc * scripts/msgfmt.py: File ./scripts/msgfmt.py added 2005-01-14 00:44 mjoc * scripts/w2u.py: File ./scripts/w2u.py added 2005-01-14 00:44 mjoc * scripts/zip.py: File ./scripts/zip.py added 2005-01-14 00:44 mjoc * scripts/make_hash2.py: File ./scripts/make_hash2.py added 2005-01-14 00:43 mjoc * scripts/slowo2mova.py: File ./scripts/slowo2mova.py added 2005-01-14 00:43 mjoc * scripts/count_code.py: File ./scripts/count_code.py added 2005-01-14 00:43 mjoc * copying.txt: File ./copying.txt added 2005-01-14 00:42 mjoc * pixmaps/icon.png: File ./pixmaps/icon.png added 2005-01-14 00:42 mjoc * pixmaps/icon-old.xpm: File ./pixmaps/icon-old.xpm added 2005-01-14 00:42 mjoc * pixmaps/icon.ico: File ./pixmaps/icon.ico added 2005-01-14 00:41 mjoc * pixmaps/splash.png: File ./pixmaps/splash.png added 2005-01-14 00:41 mjoc * pixmaps/add.png: File ./pixmaps/add.png added 2005-01-14 00:39 mjoc * pixmaps/logo.xpm: File ./pixmaps/logo.xpm added 2005-01-14 00:39 mjoc * pixmaps/left.xpm: File ./pixmaps/left.xpm added 2005-01-14 00:39 mjoc * pixmaps/hide.xpm: File ./pixmaps/hide.xpm added 2005-01-14 00:39 mjoc * pixmaps/search.xpm: File ./pixmaps/search.xpm added 2005-01-14 00:38 mjoc * pixmaps/right.xpm: File ./pixmaps/right.xpm added 2005-01-14 00:38 mjoc * pixmaps/add.xpm: File ./pixmaps/add.xpm added 2005-01-14 00:38 mjoc * Makefile: File ./Makefile added 2005-01-14 00:37 mjoc * misc/opendict.desktop: File ./misc/opendict.desktop added 2005-01-14 00:36 mjoc * ChangeLog: File ./ChangeLog added 2005-01-14 00:32 mjoc * doc/OpenDict_plugin_dev.txt: File ./doc/OpenDict_plugin_dev.txt added 2005-01-14 00:31 mjoc * win32/make.py: File ./win32/make.py added 2005-01-14 00:30 mjoc * win32/setup.py: File ./win32/setup.py added 2005-01-14 00:30 mjoc * win32/install_script.iss: File ./win32/install_script.iss added 2005-01-14 00:27 mjoc * po/lt.po: File ./po/lt.po added 2005-01-14 00:27 mjoc * po/messages.pot: File ./po/messages.pot added 2005-01-14 00:26 mjoc * po/unix_proceed.sh: File ./po/unix_proceed.sh added 2005-01-14 00:26 mjoc * lib/info.py: File ./lib/info.py added 2005-01-14 00:26 mjoc * lib/history.py: File ./lib/history.py added 2005-01-14 00:25 mjoc * lib/gui/mainwin.py: File ./lib/gui/mainwin.py added 2005-01-14 00:25 mjoc * lib/gui/dictconnwin.py: File ./lib/gui/dictconnwin.py added 2005-01-14 00:24 mjoc * lib/gui/dictaddwin.py: File ./lib/gui/dictaddwin.py added 2005-01-14 00:24 mjoc * lib/gui/pluginwin.py: File ./lib/gui/pluginwin.py added 2005-01-14 00:23 mjoc * lib/gui/mywordswin.py: File ./lib/gui/mywordswin.py added 2005-01-14 00:23 mjoc * lib/gui/helpwin.py: File ./lib/gui/helpwin.py added 2005-01-14 00:22 mjoc * lib/gui/registerwin.py: File ./lib/gui/registerwin.py added 2005-01-14 00:22 mjoc * lib/gui/groupswin.py: File ./lib/gui/groupswin.py added 2005-01-14 00:21 mjoc * lib/gui/dicteditorwin.py: File ./lib/gui/dicteditorwin.py added 2005-01-14 00:21 mjoc * lib/gui/prefswin.py: File ./lib/gui/prefswin.py added 2005-01-14 00:21 mjoc * lib/gui/errorwin.py: File ./lib/gui/errorwin.py added 2005-01-14 00:20 mjoc * lib/gui/__init__.py: File ./lib/gui/__init__.py added 2005-01-14 00:20 mjoc * lib/register.py: File ./lib/register.py added 2005-01-14 00:18 mjoc * lib/mywords.py: File ./lib/mywords.py added 2005-01-14 00:18 mjoc * lib/installer.py: File ./lib/installer.py added 2005-01-14 00:17 mjoc * lib/extra/dictdlib.py: File ./lib/extra/dictdlib.py added 2005-01-14 00:16 mjoc * lib/extra/dictclient.py: File ./lib/extra/dictclient.py added 2005-01-14 00:15 mjoc * lib/extra/html2text.py: File ./lib/extra/html2text.py added 2005-01-14 00:15 mjoc * lib/extra/__init__.py: File ./lib/extra/__init__.py added 2005-01-14 00:14 mjoc * lib/misc.py: File ./lib/misc.py added 2005-01-14 00:13 mjoc * lib/plugin.py: File ./lib/plugin.py added 2005-01-14 00:13 mjoc * lib/threads.py: File ./lib/threads.py added 2005-01-14 00:12 mjoc * lib/group.py: File ./lib/group.py added 2005-01-14 00:11 mjoc * lib/parser.py: File ./lib/parser.py added 2005-01-14 00:11 mjoc * lib/config.py: File ./lib/config.py added 2005-01-14 00:10 mjoc * BUGS: File ./BUGS added 2005-01-14 00:10 mjoc * run-opendict: File ./run-opendict added 2005-01-14 00:10 mjoc * README.txt, TODO.txt, opendict.py: File ./opendict.py added 2005-01-13 23:49 mjoc * lib/: misc.py, register.py, extra/__init__.py, extra/dictclient.py, extra/dictdlib.py, extra/html2text.py, gui/__init__.py: Removed. 2005-01-13 23:47 mjoc * win32/install_script.iss: File install_script.iss removed. 2005-01-13 23:38 mjoc * po/messages.pot: File messages.pot removed. 2005-01-13 23:38 mjoc * po/lt.po: File lt.po removed. 2005-01-13 23:38 mjoc * po/lt.mo: File lt.mo removed. 2005-01-13 23:37 mjoc * pixmaps/icon.ico: File icon.ico removed. 2005-01-13 23:37 mjoc * pixmaps/icon.png: File ./icon.png removed 2005-01-13 23:37 mjoc * pixmaps/clear2.png: File ./clear2.png removed 2005-01-13 23:36 mjoc * pixmaps/clear3.png: File ./clear3.png removed 2005-01-13 23:35 mjoc * pixmaps/icon.xpm: File ./icon.xpm removed 2005-01-13 23:35 mjoc * pixmaps/stop.xpm: File ./stop.xpm removed 2005-01-13 23:35 mjoc * pixmaps/plugin.xpm: File ./plugin.xpm removed 2005-01-13 23:34 mjoc * pixmaps/clear2.xpm: File ./clear2.xpm removed 2005-01-13 23:34 mjoc * pixmaps/clear3.xpm: File ./clear3.xpm removed 2005-01-13 23:34 mjoc * pixmaps/register.xpm: File ./register.xpm removed 2005-01-13 23:33 mjoc * pixmaps/clear4.xpm: File ./clear4.xpm removed 2005-01-13 23:32 mjoc * pixmaps/logo.xpm: File ./logo.xpm removed 2005-01-13 23:32 mjoc * pixmaps/left.xpm: File ./left.xpm removed 2005-01-13 23:31 mjoc * pixmaps/hide.xpm: File ./hide.xpm removed 2005-01-13 23:31 mjoc * pixmaps/group.xpm: File ./group.xpm removed 2005-01-13 23:30 mjoc * pixmaps/clear.xpm: File ./clear.xpm removed 2005-01-13 23:30 mjoc * pixmaps/search.xpm: File ./search.xpm removed 2005-01-13 23:30 mjoc * pixmaps/right.xpm: File ./right.xpm removed 2005-01-13 23:28 mjoc * misc/opendict.desktop: File opendict.desktop removed. 2005-01-13 23:27 mjoc * README: File README removed. 2005-01-13 23:27 mjoc * Makefile: File Makefile removed. 2005-01-13 23:24 mjoc * ChangeLog: File ChangeLog removed. 2005-01-13 23:24 mjoc * AUTHORS: [no log message] 2005-01-13 23:09 mjoc * copying.txt: File ./copying.txt removed 2005-01-13 23:08 mjoc * config.txt: File ./config.txt removed 2005-01-13 23:08 mjoc * COPY_TEMP.txt: File ./COPY_TEMP.txt removed 2005-01-13 23:07 mjoc * doc/OpenDict_plugin_dev.txt: File ./doc/OpenDict_plugin_dev.txt removed 2005-01-13 23:07 mjoc * po/unix_proceed.sh: File ./po/unix_proceed.sh removed 2005-01-13 22:56 mjoc * scripts/make_hash.py: File ./scripts/make_hash.py removed 2005-01-13 22:55 mjoc * scripts/unzip.py: File ./scripts/unzip.py removed 2005-01-13 22:54 mjoc * scripts/msgfmt.py: File ./scripts/msgfmt.py removed 2005-01-13 22:54 mjoc * scripts/w2u.py: File ./scripts/w2u.py removed 2005-01-13 22:54 mjoc * scripts/zip.py: File ./scripts/zip.py removed 2005-01-13 22:53 mjoc * scripts/make_hash2.py: File ./scripts/make_hash2.py removed 2005-01-13 22:53 mjoc * scripts/slowo2mova.py: File ./scripts/slowo2mova.py removed 2005-01-13 22:52 mjoc * scripts/count_code.py: File ./scripts/count_code.py removed 2005-01-13 22:52 mjoc * win32/make.py: File ./win32/make.py removed 2005-01-13 22:52 mjoc * win32/setup.py: File ./win32/setup.py removed 2005-01-13 22:51 mjoc * lib/info.py: File ./lib/info.py removed 2005-01-13 22:51 mjoc * lib/gui/mainwin.py: File ./lib/gui/mainwin.py removed 2005-01-13 22:50 mjoc * lib/gui/dictconnwin.py: File ./lib/gui/dictconnwin.py removed 2005-01-13 22:50 mjoc * lib/gui/pluginwin.py: File ./lib/gui/pluginwin.py removed 2005-01-13 22:50 mjoc * lib/gui/helpwin.py: File ./lib/gui/helpwin.py removed 2005-01-13 22:49 mjoc * lib/gui/registerwin.py: File ./lib/gui/registerwin.py removed 2005-01-13 22:49 mjoc * lib/gui/groupswin.py: File ./lib/gui/groupswin.py removed 2005-01-13 22:48 mjoc * lib/gui/dicteditorwin.py: File ./lib/gui/dicteditorwin.py removed 2005-01-13 22:48 mjoc * lib/gui/prefswin.py: File ./lib/gui/prefswin.py removed 2005-01-13 22:47 mjoc * lib/gui/errorwin.py: File ./lib/gui/errorwin.py removed 2005-01-13 22:47 mjoc * lib/: config.py, group.py, history.py, parser.py, plugin.py, threads.py: dsfs 2005-01-13 22:13 mjoc * opendict.py: File ./opendict.py removed. 2005-01-13 22:12 mjoc * TODO.txt: Removed. 2005-01-13 21:29 mjoc * TODO: [no log message] 2005-01-13 20:53 mjoc * README.txt: ./README.txt removed 2003-12-21 22:35 mjoc * Makefile, copying.txt, README.txt, TODO.txt, opendict.py, ChangeLog, config.txt, doc/OpenDict_plugin_dev.txt, lib/config.py, lib/group.py, lib/history.py, lib/info.py, lib/misc.py, lib/parser.py, lib/plugin.py, lib/register.py, lib/threads.py, lib/extra/__init__.py, lib/extra/dictclient.py, lib/extra/dictdlib.py, lib/extra/html2text.py, lib/gui/__init__.py, lib/gui/dictconnwin.py, lib/gui/dicteditorwin.py, lib/gui/errorwin.py, lib/gui/groupswin.py, lib/gui/helpwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py, lib/gui/prefswin.py, lib/gui/registerwin.py, misc/opendict.desktop, pixmaps/clear.xpm, pixmaps/group.xpm, pixmaps/hide.xpm, pixmaps/icon.ico, pixmaps/icon.png, pixmaps/icon.xpm, pixmaps/left.xpm, pixmaps/clear2.png, pixmaps/clear2.xpm, pixmaps/clear3.png, pixmaps/clear3.xpm, pixmaps/clear4.xpm, pixmaps/logo.xpm, pixmaps/plugin.xpm, pixmaps/register.xpm, pixmaps/right.xpm, pixmaps/search.xpm, pixmaps/stop.xpm, po/lt.mo, po/lt.po, po/messages.pot, po/unix_proceed.sh, scripts/count_code.py, scripts/make_hash.py, scripts/make_hash2.py, scripts/msgfmt.py, scripts/slowo2mova.py, scripts/unzip.py, scripts/w2u.py, scripts/zip.py, win32/install_script.iss, win32/make.py, win32/setup.py: Initial import. 2003-12-21 22:35 mjoc * copying.txt, README.txt, TODO.txt, opendict.py, config.txt, doc/OpenDict_plugin_dev.txt, lib/config.py, lib/group.py, lib/history.py, lib/info.py, lib/misc.py, lib/parser.py, lib/plugin.py, lib/register.py, lib/threads.py, lib/extra/__init__.py, lib/extra/dictclient.py, lib/extra/dictdlib.py, lib/extra/html2text.py, lib/gui/__init__.py, lib/gui/dictconnwin.py, lib/gui/dicteditorwin.py, lib/gui/errorwin.py, lib/gui/groupswin.py, lib/gui/helpwin.py, lib/gui/mainwin.py, lib/gui/pluginwin.py, lib/gui/prefswin.py, lib/gui/registerwin.py, misc/opendict.desktop, pixmaps/clear.xpm, pixmaps/group.xpm, pixmaps/hide.xpm, pixmaps/icon.ico, pixmaps/icon.png, pixmaps/icon.xpm, pixmaps/left.xpm, pixmaps/clear2.png, pixmaps/clear2.xpm, pixmaps/clear3.png, pixmaps/clear3.xpm, pixmaps/clear4.xpm, pixmaps/logo.xpm, pixmaps/plugin.xpm, pixmaps/register.xpm, pixmaps/right.xpm, pixmaps/search.xpm, pixmaps/stop.xpm, po/lt.mo, po/lt.po, po/messages.pot, po/unix_proceed.sh, scripts/count_code.py, scripts/make_hash.py, scripts/make_hash2.py, scripts/msgfmt.py, scripts/slowo2mova.py, scripts/unzip.py, scripts/w2u.py, scripts/zip.py, win32/install_script.iss, win32/make.py, win32/setup.py: Initial revision 2002-12-17 02:49 nerijus * Makefile: updated to compile with wxWin 2.4 2002-12-11 01:47 nerijus * AUTHORS, COPY_TEMP.txt, ChangeLog, Makefile, README, TODO: Initial revision 2002-12-11 01:47 nerijus * AUTHORS, COPY_TEMP.txt, ChangeLog, Makefile, README, TODO: import opendict-0.1 sources to cvs opendict-0.6.8/Makefile0000664000076400007640000000460413204646653014741 0ustar nerijusnerijus# OpenDict Makefile # DESTDIR = /usr bindir = $(DESTDIR)/bin icondir = $(DESTDIR)/share/icons/hicolor opendictdir = $(DESTDIR)/share/opendict mandir = $(DESTDIR)/share/man/man1 install: mkdir -p $(opendictdir)/lib/extra mkdir -p $(opendictdir)/lib/gui cp -r lib/*.py $(opendictdir)/lib cp -r lib/extra/*.py $(opendictdir)/lib/extra cp -r lib/gui/*.py $(opendictdir)/lib/gui chmod -R a+rX $(opendictdir)/lib mkdir -p $(opendictdir)/pixmaps cp pixmaps/*.png $(opendictdir)/pixmaps chmod -R a+rX $(opendictdir)/pixmaps mkdir -p $(icondir)/24x24/apps mkdir -p $(icondir)/32x32/apps mkdir -p $(icondir)/48x48/apps mkdir -p $(icondir)/96x96/apps mkdir -p $(icondir)/scalable/apps cp pixmaps/icon-24x24.png $(icondir)/24x24/apps/opendict.png cp pixmaps/icon-32x32.png $(icondir)/32x32/apps/opendict.png cp pixmaps/icon-48x48.png $(icondir)/48x48/apps/opendict.png cp pixmaps/icon-96x96.png $(icondir)/96x96/apps/opendict.png cp pixmaps/SVG/icon-rune.svg $(icondir)/scalable/apps/opendict.svg $(MAKE) -C po install prefix=$(DESTDIR) cp opendict.py $(opendictdir) chmod a+rx $(opendictdir)/opendict.py cp copying.html $(opendictdir) chmod a+r $(opendictdir)/copying.html mkdir -p $(bindir) ln -sf $(opendictdir)/opendict.py $(bindir)/opendict mkdir -p $(DESTDIR)/share/applications cp misc/opendict.desktop $(DESTDIR)/share/applications chmod a+r $(DESTDIR)/share/applications/opendict.desktop mkdir -p $(mandir) cp opendict.1 $(mandir) uninstall: rm -f $(DESTDIR)/share/applications/opendict.desktop rm -f $(bindir)/opendict rm -f $(opendictdir)/copying.html rm -f $(opendictdir)/opendict.py $(MAKE) -C po uninstall prefix=$(DESTDIR) rm -f $(icondir)/24x24/apps/opendict.png rm -f $(icondir)/32x32/apps/opendict.png rm -f $(icondir)/48x48/apps/opendict.png rm -f $(icondir)/96x96/apps/opendict.png rm -f $(icondir)/scalable/apps/opendict.svg rm -f $(opendictdir)/pixmaps/*.png rmdir $(opendictdir)/pixmaps rm -f $(opendictdir)/lib/gui/*.py* rm -f $(opendictdir)/lib/extra/*.py* rm -f $(opendictdir)/lib/*.py* rmdir $(opendictdir)/lib/extra rmdir $(opendictdir)/lib/gui rmdir $(opendictdir)/lib rmdir $(opendictdir) rm -f $(mandir)/opendict.* clean: for f in `find . -name '*.pyc'`; do rm $$f; done for f in `find . -name '*.pyo'`; do rm $$f; done for f in `find . -name '*.py~'`; do rm $$f; done for f in `find . -name '*~'`; do rm $$f; done $(MAKE) -C po clean opendict-0.6.8/README.txt0000664000076400007640000000222213204646653014771 0ustar nerijusnerijus -------- OpenDict -------- Copyright (c) 2003-2006 Martynas Jocius Copyright (c) 2007 IDILES SYSTEMS, UAB About ~~~~~ OpenDict is free multiplatform dictionary program. It is made to be universal and easy to use for desktop users and developers. Requirements ~~~~~~~~~~~~ - Python >= 2.4 - wxPython >= 2.6 - gettext >= 0.14 Quick Installation ~~~~~~~~~~~~~~~~~~ OpenDict on UNIX systems can be installed in a quick & dirty way: # make install If you get "cp: cannot stat `messages.po': No such file or directory" you are missing "xgettext". "xgettext" in Fedora is provided by gettext package. For Microsft Windows users ~~~~~~~~~~~~~~~~~~~~~~~~~~ MS Windows users should download setup with precompiled OpenDict version. If you want to use it from sources, download and install Python and wxPython packages. Then unpack compressed OpenDict ZIP archive and click on opendict.py icon. Help ~~~~ For more information visit http://opendict.sf.net and https://github.com/nerijus/opendict. opendict-0.6.8/TODO.txt0000664000076400007640000000150213204646653014601 0ustar nerijusnerijusTODO for OpenDict Status: x -- done * -- not finished ? -- needs to be discussed [ ] Let DICT connection be handled as a dictionary and be kept in Dictionaries menu. Let it have user defined names. Make "Manage DICT Connections" for that. [ ] Ability to merge dictionaries in editor [ ] Suggestions when search is unsuccessfull. Idea: if search gives no results, drop the last letter of the world (i.e. to make prular to single); drop another one if not results and repeat this for 3-4 times. Might be enough. An option for such search should be available in prefernces dialog. This by default should be turned on. A warning about slow search also should be added. [ ] Remove option entries for saving window size and position. [ ] Remember last used dictionary and load it on startup if no default dictionary specified. opendict-0.6.8/copying.html0000664000076400007640000004473113204646653015644 0ustar nerijusnerijus

The GNU General Public License (GPL)

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.

b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

One line to give the program's name and a brief idea of what it does.
Copyright (C) <year> <name of author>

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.

signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

opendict-0.6.8/opendict.10000664000076400007640000000214113204646653015162 0ustar nerijusnerijus.TH OPENDICT 1 "2017-11-20" .\" -------------------------------------------------------- .SH NAME opendict \- computer dictionary with several dictionary format support .\" -------------------------------------------------------- .SH SYNOPSIS .B opendict .sp or select .B Dictionary OpenDict from the .B Utility submenu of the Applications menu if using Gnome Desktop Environment. .\" -------------------------------------------------------- .SH DESCRIPTION .B OpenDict is a free cross-platform dictionary program. It works with DICT, Slowo and Mova dictionaries. It also supports plug-in dictionaries that may be created for almost any data source. OpenDict is a client for DICT servers. .\" -------------------------------------------------------- .SH SEE ALSO .BR http://opendict.sf.net .BR https://github.com/nerijus/opendict .\" -------------------------------------------------------- .SH AUTHORS .B opendict was written by Martynas Jocius . .ad l This manual page was written by Kestutis Biliunas .nh , .hy for the Debian system (but may be used by others). opendict-0.6.8/opendict.py0000775000076400007640000001355713204646653015472 0ustar nerijusnerijus#!/usr/bin/env python # -*- coding: iso-8859-1 -*- # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA import sys import os import imp import traceback import string import time # main_is_frozen() returns True when running the exe, and False when # running from a script. def main_is_frozen(): return (hasattr(sys, "frozen") or # new py2exe hasattr(sys, "importers") # old py2exe or imp.is_frozen("__main__")) # tools/freeze # If application is not frozen to binary, try selecting wxPython 3.0 or 2.8 # on multiversioned wxPython installation. if not main_is_frozen(): try: import wxversion wxversion.select(["2.8-unicode", "3.0"]) except Exception, e: print "You seem to have an unsupported wxPython version: %s" \ % e try: import wx except ImportError: print >> sys.stderr, "**" print >> sys.stderr, "** Error: wxPython library not found" print >> sys.stderr, "** Please install wxPython 2.8 or later to run OpenDict" print >> sys.stderr, "**" sys.exit(1) # get_main_dir() returns the directory name of the script or the # directory name of the exe def get_main_dir(): if main_is_frozen(): return os.path.dirname(sys.executable) return os.path.dirname(os.path.realpath(__file__)) # or return os.path.dirname(sys.argv[0]) # # Initial path # sys.path.insert(0, get_main_dir()) # OpenDict Modules from lib import info from lib.gui.mainwin import MainWindow from lib.gui.errorwin import ErrorWindow from lib.config import Configuration from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR from lib import misc from lib import info from lib import newplugin from lib import plaindict from lib import util class OpenDictApp(wx.App): """Top-level class of wxWidgets application""" locale = wx.Locale() def OnInit(self): _ = wx.GetTranslation _start = time.time() wx.Version = [] try: wx.Version = wx.__version__ except Exception, e: try: wx.Version = wx.Python.__version__ except: pass if wx.Version.split('.') < ['2', '8']: from lib.gui import errorwin title = _("wxPython Version Error") msg = _("wxPython %s is installed on this system.\n\n" "OpenDict %s requires wxPython 2.8 or newer to run smoothly.\n\n" "You can find wxPython at " "http://www.wxpython.org or you can " "install it using your system package manager.") \ % (wx.Version, info.VERSION) errorwin.showErrorMessage(title, msg) return False util.makeDirectories() systemLog(DEBUG, "Unicode version: %s" % wx.USE_UNICODE) # Init gettext support wx.Locale_AddCatalogLookupPathPrefix(os.path.join(info.GLOBAL_HOME, 'po')) self.locale.Init(wx.LANGUAGE_DEFAULT) self.locale.AddCatalog('opendict') # Data cache instance self.cache = {} # Dictionaries container # Mapping: name -> object self.dictionaries = {} # Failed dictionaries. # For error message that may be shown after creating main window self.invalidDictionaries = [] self.config = Configuration() self.config.load() self.agreements = util.AgreementsManager(os.path.join(info.LOCAL_HOME, 'agreements.txt')) # Set unique ids for plugin in newplugin.loadDictionaryPlugins(self.dictionaries, self.invalidDictionaries): self.config.ids[wx.NewId()] = plugin.getName() for plain in plaindict.loadPlainDictionaries(self.dictionaries): self.config.ids[wx.NewId()] = plain.getName() for d in self.dictionaries.values(): if not self.config.activedict.init: if not self.config.activedict.enabled(d.getName()): d.setActive(active=False) else: # Fill up with names if not initialized yet self.config.activedict.add(d.getName()) windowPos = (int(self.config.get('windowPosX')), int(self.config.get('windowPosY'))) windowSize = (int(self.config.get('windowWidth')), int(self.config.get('windowHeight'))) self.window = MainWindow(None, -1, "OpenDict", windowPos, windowSize, style=wx.DEFAULT_FRAME_STYLE) try: systemLog(INFO, "OpenDict %s" % info.VERSION) systemLog(INFO, "wxPython %s" % wx.Version) systemLog(INFO, "Global home: %s:" % info.GLOBAL_HOME) systemLog(INFO, "Local home: %s" % info.LOCAL_HOME) systemLog(DEBUG, "Loaded in %f seconds" % (time.time() - _start)) except Exception, e: print "Logger Error: Unable to write to log (%s)" % e self.window.Show(True) return True if __name__ == "__main__": openDictApp = OpenDictApp(0) openDictApp.MainLoop() opendict-0.6.8/doc/0000775000076400007640000000000013204646653014042 5ustar nerijusnerijusopendict-0.6.8/doc/Plugin-HOWTO.html0000664000076400007640000003625613204646653017100 0ustar nerijusnerijus OpenDict Add-Ons Development HOWTO

OpenDict Add-Ons Development HOWTO

Introduction

OpenDict is free multiplatform dictionary. More information about it can be found on OpenDict website.

This document is written for developers who want to make easy-installable OpenDict dictionaries.

Warning: It is not necessary to make OpenDict dictionary if you have a dictionary file in Slowo, Mova or DICT format. Such dictionaries can be used right now by selecting Dictionaries -> Install Dictionary from File from OpenDict menu.

Types of OpenDict Dictionaries

OpenDict has two types of dictionaries: plain (simple) dictionaries and plugin (complex) dictionaries. Plain dictionaries consists of dictionary file (type of that dictionary must be supported by OpenDict) and description file in XML format. Plugin dictionaries consists of Python module with code that handles search process and description file in XML format; it may also have dictionary file which is processed by Python module mentioned above.

Plain dictionaries are simple and handy. It is very easy to install them using OpenDict itself. If you have dictionary file (format of that dictionary must be supported by OpenDict) and want to attach some information to it, like the name, the author, the description, you may want to make plain dictionary.

If you have more complex task, like search the web, etc, you may want to make a plugin for OpenDict. The plugin is a chunk of code written in Python programming language that OpenDict attaches to itself at runtime.

The next sections of this document will describe how to make plain dictionaries and plugins.

Plain Dictionary Example

Assume we have a small dictionary file named mydict.dwa in Slowo format:

above = ant ; virš ;
abroad = visur ; užsienyje ;
acoustic = akustinis ;
acquaint = pranešti ;

Say we want to call this dictionary "My Personal Dictionary" and attacht a description "This is my personal dictionary. It is very small, but it is not the size that matters :)" to it. Each plain dictionary must have XML description file named config.xml, otherwise it will be treated as invalid dictionary. So we write an XML file called config.xml with our favorite text or XML editor:

<?xml version='1.0' encoding='UTF-8'?>
<plain-dictionary>
  <format>slowo</format>
  <name>My Personal Dictionarys</name>
  <version>0.1</version>
  <authors>
     <author name="Your Name" email="your@email.tdl"/>
  </authors>
  <path>mydict.dwa</path>
  <md5>9c62810c32ca20fe018b79987789daef</md5>
  <encoding>UTF-8</encoding>
  <description><![CDATA[
     This is my personal dictionary. It is very small, but it is not the
     size that matters :)
  ]]>
  </description>
</plain-dictionary>

As you can see, a little more information must be added to description (i.e. configuration) file. Here is a short description of each section:

XML tag Description
format Dictionary format. OpenDict supports the following formats:
  • slowo -- Slowo format
  • mova -- Mova format
  • dict -- DICT format
TODO: describe all supported format somewhere
name Name of the dictionary. It will be shown in the Dictionaries menu in OpenDict window.
version Version value is very important. It shows the freshness of your dictionary. The more recent the dictionary, the greater version value must be set. For example: 0.1, 0.2, 0.3, etc; or 1, 2, 3, etc.
author

The author of the dictionary. Notice that author tag is inside authors tag, because there may be several authors of the dictionary. So add as may author tags as you want, but make them the childs of the authors tag.

This tag is a bit complicated, because you may not be the author of the dictionary file you are using. If so, you may treat the author tag as maintainance tag and write your as maintainer name inside it. In addition to this, you should write the name of the author in the description tag mentioned below.

path Path to the dictionary file. It may be an absolute (i.e. full) path to the dictionary file or relative path. If you write full path, dictionary would be taken from there. Buf if you write only the name of the dictionary (i.e. mydict.dwa), the dictionary will be treated to be located at $DICTDIR/file/mydict.dwa, where $DICTDIR is directory where you dictionary is located, for example /home/mjoc/.opendict/dictionaries/plain/mydict.dwa/file/mydict.dwa. If you are going to distribute dictionary file with OpenDict plain dictionary, you want to write only the file name inside path tag.
md5 This is an MD5 checksum value of the dictionary file (i.e. mydict.dwa). This MD5 code is used to determine changes of the dictionary file. That means user is able to modify dictionary file and OpenDict will recreate index table before using that dictionary next time. If you want to get MD5 checksum value of you dictionary file, execute the following command on your system (Linux, BSD) shell:
        $ md5sum myfile.dwa
	9c62810c32ca20fe018b79987789daef  myfile.dwa
    
You can see the command and the output above. Just copy that 32-chars checksum to your XML file. This is quite unfriendly, so I will think about easer ways some day. Nevertheless, we are developers today.
encoding Character encoding of the dictionary file. Examples: UTF-8, UTF-16, ISO-8859-1, ISO-8859-13, etc.
description Description of your dictionary. You should not remove that <![CDATA[ ... ]]> tag, because it lets you to write any text inside using even XML (HTML) tags like 1 + 1 < 1 or <myemail@abcdef.tdl>

The last file you need is an index file. This file contains index table of the dictionary describing in what position what letter begins. Index makes search a lot faster.

I do not recommend writing index file using your fingers and the keyboard :), so we will use OpenDict to make one for ourselves. Lets now make a directory tree containing these files and directories:

mydict.dwa/
    |
    +-- conf/
    |     |
    |     +-- config.xml
    |
    +-- data/
    |     
    |
    +-- file/
          |
          +-- mydict.dwa

As you see, the root direcory is called mydict.dwa, the same as dictionary file is called. This is the rule. Now move that directory to the directory where all the plain dictionaries are located. On my machine I would do:

    mjoc@kumo:~/tmp/dict-factory$ mv mydict.dwa/ ~/.opendict/dictionaries/plain/

After that you should start OpenDict and load the dictionary you've just made. If everything goes well, you will be informed about reindexing the dictionary. Press OK and, if everything goes well, you will have index.xml file located at data/ directory. On my machine the full path would be /home/mjoc/.opendict/dictionaries/plain/mydict.dwa/data/index.xml. Now the directory tree look in a way like that:

mydict.dwa/
    |
    +-- conf/
    |     |
    |     +-- config.xml
    |
    +-- data/
    |     |
    |     +-- index.xml
    |
    +-- file/
          |
          +-- mydict.dwa

Now we have all the files needed. They are located at $DICTDIR. The last step is to make a ZIP archive of that directory. Notice that that ZIP file must contain the dictionary directory (i.e. mydict.dwa/) itself, not only files inside it. To zip the directory, I would do:

    mjoc@kumo:~/tmp/dict-factory$ cd ~/.opendict/dictionaries/plain/
    mjoc@kumo:~/.opendict/dictionaries/plain$ zip -r MyDictionary-0.1.zip mydict.dwa/
    mjoc@kumo:~/.opendict/dictionaries/plain$ mv MyDictionary-0.1.zip ~
    mjoc@kumo:~/.opendict/dictionaries/plain$ cd

Now file MyDictionary-0.1.zip can be found at my home direcory (/home/mjoc/). That's all. Now you have made a dictionary that can be installed by everyone using OpenDict by selecting Dictionaries -> Install Dictionary from File from the menu.

Simple Plugin Example

In this section I am going to give an example of simple OpenDict plugin dictionary. Good example is a network dictionary plugin that fetches translations from the web and processed them locally.

At first we have to create file called plugin.xml. The contents of this file may be similar to this one:

<?xml version="1.0" encoding="UTF-8"?>
<plugin type="dictionary">
   <name>Network Test</name>
   <version>0.1</version>
   <authors>
      <author name="Martynas Jocius" email="mjoc@akl.lt" />
   </authors>
   <module lang="Python">mydict.py</module>
   <encoding>UTF-8</encoding>
   <uses-word-list>False</uses-word-list>
   <opendict-version>0.5.7</opendict-version>
   <python-version>2.3</python-version>
   <platforms>
      <platform name="Linux" />
      <platform name="BSD" />
      <platform name="Windows" />
   </platforms>
   <description>
   Example plugin dictioary. Does nothing.
   </description>
</plugin>

As you may already noticed, some XML tags are the same as in the previous config.xml example. There is the description of new tags, like encoding, module, etc.

XML tag Description
module Main Python module file name.
encoding Character encoding of the result string that plugin module returns (examples include UTF-8, ISO-8859-15, etc)
uses-word-list This should be set to True if dictionary needs word list to be shown, False otherwise. If dictionary uses word list, it must return a list of alternative words in addition with translation string (see below for more information)
opendict-version The lowest OpenDict version plugin requires, for example 0.5.1, 0.5.7, etc. This is important when plugin structure is different from one that old OpenDict versions provide (for example 0.5.1 and 0.5.7 plugin structure differs a lot)
python-version The lowest Python version that plugin requires.
python-version The lowest Python version that plugin requires.
platforms Parent node for platform tag.
platform This tag with attribute name value X means that this plugin is tested and works on platform X. For example, Linux, BSD, MacOS. Currently not used

Now we should write the main module in Python programming language. Module file name is mydict.py as we called it in plugin.xml. The following code might be correct OpenDict plugin:

#!/usr/bin/env python

#
# MyDict 0.1
# Copyright (c) 2005 Matynas Jocius <mjoc@akl.lt>
#
# Simple plugin dictionary for OpenDict.
#
# This code is licensed under the GNU GPL v2.
#

"""
Simple OpenDict plugin module
"""

import sys
import httplib
import urllib


def init(libraryPath):
    """Return dictionary instance"""

    sys.path.insert(0, libraryPath)

    return MyDict()



class MyDict:
    """MyDict plugin class"""
    
    def __init__(self):
        """Initialize variables"""

        # This trick is needed to have accessible modules from
        # OpenDict library
        from lib import errortype, meta

        self.errorModule = errortype
        self.metaModule = meta

        
    def search(self, word):
        """Search and return HTML code."""

        print type(word), len(word)

        result = self.metaModule.SearchResult()

        try:
            self.conn = httplib.HTTPConnection("mjoc.sig.lt")
            self.conn.request("GET", "/index.html")
            response = self.conn.getresponse()
            data = response.read()

            trans = "<html><body><h3>"

            if word in data:
                trans += "Word <i>%s</i> was found on " \
                         "http://mjoc.sig.lt/index.html" % word
            else:
                trans += "Word <i>%s</i> was not found on " \
                         "http://mjoc.sig.lt/index.html" % word

            trans += "</h3></body></html>"

            result.setTranslation(trans)

        except Exception, e:
            import traceback
            traceback.print_exc()

            result.setError(self.errorModule.INTERNAL_ERROR)

            return result

        return result

TODO: describe how to write the class and other details.

To make an installable plugin file in ZIP archive format, move plugin.xml and mydict.py into some directory (i.e. mydict-0.1) and zip that directory. After performing these actions your new OpenDict plugin will be ready to be installed.

Conclusion

TODO: This document is very short and fuzzy. It must be improved in the future.

opendict-0.6.8/lib/0000775000076400007640000000000013204646653014043 5ustar nerijusnerijusopendict-0.6.8/lib/__init__.py0000664000076400007640000000000013204646653016142 0ustar nerijusnerijusopendict-0.6.8/lib/config.py0000664000076400007640000001204013204646653015657 0ustar nerijusnerijus# OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # Module: config.py import os import string import codecs from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR from lib.misc import numVersion from lib import info from lib import util from lib import parser from lib import xmltools class ActiveDictConfig(object): """Config file manager for activated dictionaries. Operates with names of dictionaries only.""" def __init__(self): self.filePath = os.path.join(info.LOCAL_HOME, "active.conf") # If config file does not exist (this is the first time), # set special attribute init=True to notify that if not os.path.exists(self.filePath): self.init = True else: self.init = False self.dicts = [] def load(self): """Load list of active dictionaries.""" try: for line in open(self.filePath): name = line.strip() name = unicode(name, 'UTF-8') self.dicts.append(name) except IOError, e: pass def save(self): """Save list of active dictionaries.""" fd = open(self.filePath, 'w') for d in self.dicts: name = d.encode('UTF-8') print >> fd, name fd.close() def enabled(self, name): """Return True if this dictionary is enabled.""" if name in self.dicts: return True return False def add(self, name): """Add new dictionary to the list.""" if type(name) == str: name = unicode(name, 'UTF-8') if not name in self.dicts: self.dicts.append(name) def remove(self, name): """Remove dictionary from the list.""" if type(name) == str: name = unicode(name, 'UTF-8') if name in self.dicts: self.dicts.remove(name) class Configuration: """This class is used for reading and writing config file. It also takes care of installing new plugins (but shouldn't)""" def __init__(self): """Initialize default values""" self.activedict = ActiveDictConfig() self.activedict.load() self.filePath = os.path.join(info.LOCAL_HOME, "opendict.xml") self.props = {} # TODO: Should not be here after removing register part from config import wx self.app = wx.GetApp() # # Default values # self.set('saveWindowSize', 'True') self.set('saveWindowPos', 'True') self.set('saveSashPos', 'True') self.set('defaultDict', '') self.set('windowWidth', '550') self.set('windowHeight', '370') self.set('windowPosX', '-1') self.set('windowPosY', '-1') self.set('sashPos', '160') # Internal variables self.window = None self.ids = {} self.plugMenuIds = 200 self.regMenuIds = 300 self.groupMenuIds = 400 self.set('encoding', 'UTF-8') self.set('fontFace', 'Fixed') self.set('fontSize', '10') self.set('dictServer', 'dict.org') self.set('dictServerPort', '2628') self.set('dict-server-encoding', 'UTF-8') self.repository = \ 'http://opendict.sf.net/Repository/Data/opendict-add-ons.xml' def get(self, name): """Return property value""" return self.props.get(name) def set(self, name, value): """Set property""" self.props[name] = value def load(self): """Load configuration from file to memory""" try: if os.path.exists(self.filePath): self.props.update(xmltools.parseMainConfig(self.filePath)) except Exception, e: systemLog(ERROR, "Unable to read configuration file: %s" % e) # Old configurations may still keep outdated entry, rewrite it self.set('repository-list', self.repository) def save(self): """Write configuration to disk""" doc = xmltools.generateMainConfig(self.props) xmltools.writeConfig(doc, os.path.join(info.LOCAL_HOME, self.filePath)) def checkDir(self, dir): """Check if directory exists. Create one if not""" raise DeprecationWarning if not os.path.exists(os.path.join(uhome, dir)): os.mkdir(os.path.join(uhome, dir)) opendict-0.6.8/lib/dicteditor.py0000664000076400007640000001107713204646653016555 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Dictionary editor module """ class Translation: """Translation in Slowo format Keeps one original word and a dictionary of translations """ def __init__(self): """Initialize""" self.word = None self.translations = {} def setWord(self, word): """Set word""" self.word = word def getWord(self): """Return word""" return self.word def addTranslation(self, trans, comment=None): """Set translation object""" self.translations[trans] = comment def setTranslations(self, newTrans): """Set translation dictionary""" self.translations = newTrans def getTranslations(self): """Return translation object""" return self.translations class Editor: """Slowo dictionary editor""" def __init__(self, filePath=None): """Initialize variables and load dictionary if requested""" self.filePath = filePath self.units = [] self.encoding = 'UTF-8' if filePath: self.load(filePath) def load(self, filePath): """Load dictionary into memory""" self.filePath = filePath self.units = [] try: fd = open(filePath) for line in fd: try: line = unicode(line, self.encoding) except Exception, e: raise Exception, "Unable to encode text in %s" \ % self.encoding word, end = line.split('=') word = word.strip() translation = Translation() translation.setWord(word) chunks = end.split(';') for chunk in chunks: chunk = chunk.strip() if not chunk: continue try: trans, comment = chunk.split('//') except: trans = chunk comment = None trans = trans.strip() if comment: comment = comment.strip() translation.addTranslation(trans, comment) self.units.append(translation) fd.close() except Exception, e: raise Exception, "Unable to read dictionary: %s" % e def save(self, filePath=None): """Write data to disk""" if not filePath: filePath = self.filePath try: fd = open(filePath, 'w') for unit in self.getUnits(): outstr = "%s = " % unit.getWord() chunks = [] for trans, comment in unit.getTranslations().items(): if comment: chunks.append("%s // %s" % (trans, comment)) else: chunks.append(trans) outstr += u' ; '.join(chunks) + u' ;' outstr = outstr.encode(self.encoding) print >> fd, outstr except Exception, e: raise Exception, "Unable to save dictionary: %s" % e def getUnit(self, word): """Return Translation object for the word""" for unit in self.units: if unit.getWord() == word: return unit return None def addUnit(self, unit): """Adds translation unit to dictionary""" self.units.append(unit) def removeUnit(self, unit): """Removes translation unit defined by word""" self.units.remove(unit) def getUnits(self): """Return list of translation objects""" return self.units opendict-0.6.8/lib/dicttype.py0000664000076400007640000000532713204646653016251 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Dictionary types """ from lib import newplugin class DictionaryType: """Dictionary type interface""" dictClass = None fileExtentions = None name = None shortIdName = None def getClass(self): """Return dictionary class""" return self.dictClass def getFileExtentions(self): """Return file extention""" return self.fileExtentions def getName(self): """Return type name""" return self.name def getIdName(self): """Return short ID name""" return self.shortIdName class TypePlugin(DictionaryType): """Dictionary plugin""" dictClass = newplugin.DictionaryPlugin fileExtentions = ('zip',) name = "OpenDict dictionary plugin" class TypeSlowo(DictionaryType): """Slowo dictionary format""" import parser dictClass = parser.SlowoParser fileExtentions = ('dwa',) name = "Slowo dictionary" shortIdName = "slowo" class TypeMova(DictionaryType): """Mova dictionary format""" import parser dictClass = parser.MovaParser fileExtentions = ('mova',) name = "Mova dictionary" shortIdName = "mova" class TypeTMX(DictionaryType): """TMX dictionary format""" import parser dictClass = parser.TMXParser fileExtentions = ('tmx',) name = "TMX dictionary" shortIdName = "tmx" class TypeDict(DictionaryType): """DICT dictionary type""" import parser dictClass = parser.DictParser fileExtentions = ('dict', 'dz',) name = "DICT dictionary" shortIdName = "dict" # Constant instances PLUGIN = TypePlugin() SLOWO = TypeSlowo() MOVA = TypeMova() #TMX = TypeTMX() DICT = TypeDict() # Supported types tuple supportedTypes = (PLUGIN, SLOWO, MOVA, DICT) # Plain dictionary types (data file) plainTypes = (SLOWO, MOVA, DICT) # Types for which index table is made indexableTypes = (SLOWO, MOVA) opendict-0.6.8/lib/enc.py0000664000076400007640000000217513204646653015167 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Character encodings """ import wx if wx.USE_UNICODE: toWX = fromWX = lambda s: s else: import locale localeCharset = locale.getpreferredencoding() def toWX(s): return s.encode(localeCharset, 'replace') def fromWX(s): return unicode(s, localeCharset) opendict-0.6.8/lib/errortype.py0000664000076400007640000000720513204646653016454 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Error types """ import wx _ = wx.GetTranslation class ErrorType: """Error type interface""" shortMessage = None longMessage = None def getShortMessage(self): """Return short message""" return self.shortMessage def getLongMessage(self): """Return long message""" return self.longMessage def getMessage(self): """Alternative for getShortMessage()""" return self.getShortMessage() class ErrorOk(ErrorType): """No error class""" shortMessage = _("Success") longMessage = _("Search successfully finished.") class ErrorNotFound(ErrorType): """Not found error class""" shortMessage = _("Not found") longMessage = _("Word or phrase not found. Try less letters or " \ "fewer words.") class ErrorInternal(ErrorType): """Internal error class""" shortMessage = _("Internal error") longMessage = _("Internal error occured. Please send bug report to " \ "the dictionary's of current use authors. Thank you.") class ErrorNotConnected(ErrorType): """Not connected error class""" shortMessage = _("Not connected") longMessage = _("This dictionary uses Internet connection " \ "to translate words. Please connect to the Internet and " \ "try again.") class ErrorConnectionTimeout(ErrorType): """Not connected error class""" shortMessage = _("Connection Error") longMessage = _("Could not connect to host. " \ "Check your Internet connection or try later.") class ErrorInvalidEncoding(ErrorType): """Invalid encoding error class""" shortMessage = _("Invalid encoding") longMessage = _("Selected encoding is not correct for " \ "this dictionary. Please select another from Edit > " \ "Character Encoding menu") class ErrorOpenDict(ErrorType): """OpenDict bug class""" shortMessage = _("OpenDict Bug") longMessage = _("Internal error occured. Please send bug report to " \ "OpenDict authors to prevent this error in the future. " \ "Thank you!") class ErrorCustom(ErrorType): """Custom error""" shortMessage = _("Unknown Error") longMessage = _("Unknown error occured.") def setMessage(self, msg): """Set custom message""" self.shortMessage = msg def setLongMessage(self, msg): """Set custom descriptive message""" self.longMessage = msg # Error constant instances OK = ErrorOk() NOT_FOUND = ErrorNotFound() INTERNAL_ERROR = ErrorInternal() NOT_CONNECTED = ErrorNotConnected() CONNECTION_ERROR = ErrorConnectionTimeout() CONNECTION_TIMEOUT = CONNECTION_ERROR INVALID_ENCODING = ErrorInvalidEncoding() OPENDICT_BUG = ErrorOpenDict() CUSTOM_ERROR = ErrorCustom() opendict-0.6.8/lib/history.py0000664000076400007640000000320713204646653016120 0ustar nerijusnerijus# OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # Module: history class History: def __init__(self): self.pages = [] self.index = -1 def add(self, page): self.pages.append(page) self.index = len(self.pages) - 1 def clear(self): self.pages = [] self.index = -1 def back(self): if self.index > 0: self.index -= 1 page = self.pages[self.index] else: page = self.pages[self.index] return page def forward(self): if self.index < len(self.pages) - 1: self.index += 1 page = self.pages[self.index] else: page = self.pages[self.index] return page def canBack(self): return self.index > 0 def canForward(self): return self.index < len(self.pages) - 1 opendict-0.6.8/lib/info.py0000664000076400007640000000535513204646653015360 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import sys import os import imp # OpenDict version VERSION = "0.6.8" # File system objects __OPENDICT_LOCAL_DIR = ".opendict" __DICT_DIR = "dictionaries" __PLUGIN_DICT_DIR = "plugins" # plugin dictionaries __PLAIN_DICT_DIR = "plain" # used for downloaded dictionaries __PLAIN_DICT_CONFIG_DIR = "conf" __PLAIN_DICT_FILE_DIR = "file" _PLAIN_DICT_DATA_DIR = "data" LOG_DIR = 'log' PLAIN_DICT_DIR = os.path.join(__DICT_DIR, __PLAIN_DICT_DIR) PLUGIN_DICT_DIR = os.path.join(__DICT_DIR, __PLUGIN_DICT_DIR) GLOBAL_HOME = None LOCAL_HOME = None ## if sys.platform == "win32": ## import _winreg ## x = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER) ## try: ## y = _winreg.OpenKey(x, "SOFTWARE\OpenDict\Settings") ## GLOBAL_HOME = _winreg.QueryValueEx(y, "Path")[0] ## except: ## GLOBAL_HOME = "C:\\Program Files\\OpenDict" ## LOCAL_HOME = GLOBAL_HOME ## else: ## if not os.path.exists(os.path.join(os.environ.get("HOME"), ## __OPENDICT_LOCAL_DIR)): ## os.mkdir(os.path.join(os.environ.get("HOME"), __OPENDICT_LOCAL_DIR)) ## LOCAL_HOME = os.path.join(os.environ.get("HOME"), __OPENDICT_LOCAL_DIR) ## GLOBAL_HOME = "/usr/share/opendict" # main_is_frozen() returns True when running the exe, and False when # running from a script. def main_is_frozen(): return (hasattr(sys, "frozen") or # new py2exe hasattr(sys, "importers") # old py2exe or imp.is_frozen("__main__")) # tools/freeze if main_is_frozen(): GLOBAL_HOME = os.path.realpath(os.path.join(os.path.dirname(\ os.path.realpath(__file__)), '../..')) else: GLOBAL_HOME = os.path.realpath(os.path.join(os.path.dirname(\ os.path.realpath(__file__)), '..')) if sys.platform == 'win32': LOCAL_HOME = GLOBAL_HOME else: LOCAL_HOME = os.path.join(os.environ.get('HOME', GLOBAL_HOME), __OPENDICT_LOCAL_DIR) opendict-0.6.8/lib/installer.py0000664000076400007640000003432713204646653016423 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import wx import os import zipfile import shutil import traceback from lib.gui.dictaddwin import DictAddWindow from lib.gui import errorwin from lib import misc from lib import info from lib import dicttype from lib import xmltools from lib import util from lib import enc from lib import plaindict from lib import newplugin _ = wx.GetTranslation class Installer: """Default class used for installing plugins and registering dictionaries.""" def __init__(self, mainWin, config): self.mainWin = mainWin self.config = config def showGUI(self): """Show graphical window for selecting files and formats""" wildCard = "All files (*.*)|*.*|" \ "OpenDict plugins (*.zip)|*.zip|" \ "Slowo dictionaries (*.dwa)|*.dwa|" \ "Mova dictionaries (*.mova)|*.mova|" \ "DICT dictionaries (*.dz)|*.dz" fileDialog = wx.FileDialog(self.mainWin, message=_("Choose dictionary file"), wildcard=wildCard, style=wx.FD_OPEN|wx.FD_CHANGE_DIR) fileDialog.CentreOnScreen() if fileDialog.ShowModal() == wx.ID_OK: filePath = fileDialog.GetPaths()[0] else: fileDialog.Destroy() return fileName = os.path.basename(filePath) extention = os.path.splitext(fileName)[1][1:] extMapping = {} for t in dicttype.supportedTypes: for ext in t.getFileExtentions(): extMapping[ext.lower()] = t if not extention.lower() in extMapping.keys(): title = _("Recognition Error") msg = _("File %s is not supported by OpenDict") % fileName errorwin.showErrorMessage(title, msg) return else: self.install(filePath) def install(self, filePath): """Install dictionary""" extention = os.path.splitext(filePath)[1][1:] succeeded = False try: if extention.lower() in dicttype.PLUGIN.getFileExtentions(): try: directory, dtype = installPlugin(filePath) if directory: if dtype.lower() == 'plugin': dictionary = newplugin._loadDictionaryPlugin(directory) else: dictionary = plaindict._loadPlainDictionary(directory) self.mainWin.addDictionary(dictionary) succeeded = True except Exception, e: errorwin.showErrorMessage(_("Installation failed"), e.args[0] or '') self.mainWin.SetStatusText(_("Installation failed")) return else: try: directory = installPlainDictionary(filePath) if directory: dictionary = plaindict._loadPlainDictionary(directory) self.mainWin.addDictionary(dictionary) succeeded = True except Exception, e: traceback.print_exc() errorwin.showErrorMessage(_("Installation Error"), e.args[0] or '') self.mainWin.SetStatusText(_("Error: Installation failed")) return except: # Can this happen? self.mainWin.SetStatusText(_("Error: Installation failed")) traceback.print_exc() if succeeded: title = _("Dictionary installed") msg = _("Dictionary successfully installed. You can choose it " \ "from \"Dictionaries\" menu now.") errorwin.showInfoMessage(title, msg) def installPlainDictionary(filePath): """Install plain dictionary and return directory path""" if not os.path.exists(filePath): raise Exception, _("File %s does not exist") % filePath if not os.path.isfile(filePath): raise Exception, _("%s is not a file") % filePath util.makeDirectories() fileName = os.path.basename(filePath) dictionaryName = os.path.splitext(fileName)[0] dictDir = os.path.join(info.LOCAL_HOME, info.__DICT_DIR, info.__PLAIN_DICT_DIR, fileName) # Check existance if os.path.exists(dictDir): raise Exception, _("Dictionary \"%s\" is already installed") \ % dictionaryName extention = os.path.splitext(fileName)[1][1:] dictType = None # Determine type for t in dicttype.supportedTypes: for ext in t.getFileExtentions(): if ext.lower() == extention.lower(): dictType = t break if not dictType: raise Exception, "Dictionary type for '%s' still unknown! " \ "This may be internal error." % fileName # Create directories try: os.mkdir(dictDir) os.mkdir(os.path.join(dictDir, info.__PLAIN_DICT_CONFIG_DIR)) os.mkdir(os.path.join(dictDir, info.__PLAIN_DICT_FILE_DIR)) os.mkdir(os.path.join(dictDir, info._PLAIN_DICT_DATA_DIR)) except Exception, e: print "ERROR Unable to create dicrectories, aborted (%s)" % e try: shutil.rmtree(dictDir) except Exception, e: print "ERROR Unable to remove directories (%s)" % e # Determine info dictFormat = dictType.getIdName() md5sum = util.getMD5Sum(filePath) # Write configuration doc = xmltools.generatePlainDictConfig(name=dictionaryName, format=dictFormat, version=None, authors={}, path=filePath, md5=md5sum, encoding='UTF-8', description=None) xmltools.writePlainDictConfig(doc, os.path.join(dictDir, 'conf', 'config.xml')) return dictDir def installPlugin(filePath): """Install dictionary plugin and return directory path""" # Check if file exists if not os.path.exists(filePath): raise Exception, _("File %s does not exist") % filePath # Check if it is file if not os.path.isfile(filePath): raise Exception, _("%s is not a file") % filePath # Check if it is ZIP archive if os.path.splitext(filePath)[1].lower()[1:] != "zip": raise Exception, _("%s is not OpenDict dictionary plugin") % filePath util.makeDirectories() try: zipFile = zipfile.ZipFile(filePath, 'r') except Exception, e: raise Exception, _("File \"%s\" is not valid ZIP file") % \ os.path.basename(filePath) # Test CRC if zipFile.testzip(): raise Exception, _("Dictionary plugin file is corrupted") # Check if empty try: topDirectory = zipFile.namelist()[0] except Exception, e: raise Exception, _("Plugin file is empty (%s)") % e configFileExists = False pluginConfigExists = False plainConfigExists = False topLevelDirExists = False # Check for validity for fileInZip in zipFile.namelist(): dirName = os.path.dirname(fileInZip) fileName = os.path.basename(fileInZip) if fileName == "plugin.xml": pluginConfigExists = True if fileName == 'config.xml': plainConfigExists = True if len(fileName) == 0 \ and len(dirName.split('/')) == 1: topLevelDirExists = True if ((not plainConfigExists) and (not pluginConfigExists)) \ or (not topLevelDirExists): raise Exception, _("Selected file is not valid OpenDict plugin") dtype = None if plainConfigExists: directory = _installPlainPlugin(filePath) dtype = 'plain' elif pluginConfigExists: directory = _installNormalPlugin(filePath) dtype = 'plugin' return (directory, dtype) def _installNormalPlugin(filePath): """Install 'normal' OpenDict plugin""" zipFile = zipfile.ZipFile(filePath, 'r') topDirectory = zipFile.namelist()[0] pluginsPath = os.path.join(info.LOCAL_HOME, info.PLUGIN_DICT_DIR) # Check if already installed if os.path.exists(os.path.join(info.LOCAL_HOME, info.PLUGIN_DICT_DIR, topDirectory)): raise Exception, _("This dictionary already installed. " \ "If you want to upgrade it, please remove " \ "old version first.") installFile = os.path.join(topDirectory, 'install.py') if installFile in zipFile.namelist(): data = zipFile.read(installFile) try: struct = {} exec data in struct except Exception, e: title = _("Installation Error") msg = _("Installation tool for this dictionary failed to start. " \ "Please report this problem to developers.") errorwin.showErrorMessage(title, msg) return install = struct.get('install') if not install: title = _("Installation Error") msg = _("Installation tool for this dictionary failed to start. " \ "Please report this problem to developers.") errorwin.showErrorMessage(title, msg) return if not install(info.GLOBAL_HOME, info.LOCAL_HOME): title = _("Installation Aborted") msg = _("Dictionary installation has been aborted.") errorwin.showErrorMessage(title, msg) return # Install try: for fileInZip in zipFile.namelist(): dirName = os.path.dirname(fileInZip) fileName = os.path.basename(fileInZip) if len(fileName) == 0: dirToCreate = os.path.join(pluginsPath, dirName) if not os.path.exists(dirToCreate): os.mkdir(dirToCreate) else: fileToWrite = os.path.join(pluginsPath, dirName, fileName) fd = open(fileToWrite, 'wb') fd.write(zipFile.read(fileInZip)) fd.close() except Exception, e: try: shutil.rmtree(os.path.join(pluginsPath, topLevelDir)) except Exception, e: raise _("Error while removing created directories after " \ "plugin installation failure. This may be " \ "permission or disk space error.") raise _("Unable to install plugin") return os.path.join(info.LOCAL_HOME, info.PLUGIN_DICT_DIR, topDirectory) def _installPlainPlugin(filePath): """Install prepared plain dictionary and return directory path""" zipFile = zipfile.ZipFile(filePath, 'r') topDirectory = zipFile.namelist()[0] # Test CRC if zipFile.testzip(): raise Exception, _("Compressed dictionary file is corrupted") plainDictsPath = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR) # Check if already installed if os.path.exists(os.path.join(plainDictsPath, topDirectory)): raise Exception, _("This dictionary already installed. " \ "If you want to upgrade it, please remove " \ "old version first.") # Install try: for fileInZip in zipFile.namelist(): dirName = os.path.dirname(fileInZip) fileName = os.path.basename(fileInZip) if len(fileName) == 0: dirToCreate = os.path.join(plainDictsPath, dirName) if not os.path.exists(dirToCreate): os.mkdir(dirToCreate) else: fileToWrite = os.path.join(plainDictsPath, dirName, fileName) fd = open(fileToWrite, 'wb') fd.write(zipFile.read(fileInZip)) fd.close() except Exception, e: try: shutil.rmtree(os.path.join(plainDictsPath, topDirectory)) except Exception, e: raise _("Error while removing created directories after " \ "plugin installation failure. This may be " \ "permission or disk space error.") raise _("Unable to install dictionary") return os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR, topDirectory) def removePlainDictionary(dictInstance): """Remove dictionary configuration""" filePath = dictInstance.getPath() fileName = os.path.basename(filePath) dictDir = dictInstance.getConfigDir() try: shutil.rmtree(dictDir) except Exception, e: raise Exception, str(e) def removePluginDictionary(dictInstance): """Remove plugin dictionary""" filePath = dictInstance.getPath() fileName = os.path.basename(filePath) dictDir = dictInstance.getPath() try: shutil.rmtree(dictDir) except Exception, e: raise Exception, str(e) opendict-0.6.8/lib/logger.py0000664000076400007640000000407413204646653015701 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import os import time from lib import info INFO = 0 WARNING = 1 ERROR = 2 DEBUG = 3 _logDir = os.path.join(info.LOCAL_HOME, info.LOG_DIR) _systemLogFile = os.path.join(_logDir, 'system.log') _debugLogFile = os.path.join(_logDir, 'debug.log') # Enable or disable logging logging = False def systemLog(messageType, message): """Write message system log""" if not logging: return dateStr = time.strftime("%Y-%m-%d %H:%M:%S") typeStr = 'ERROR' if messageType == INFO: typeStr = 'INFO' elif messageType == WARNING: typeStr = 'WARNING' elif messageType == DEBUG: typeStr = 'DEBUG' try: fd = open(_systemLogFile, 'a+') print >> fd, dateStr, typeStr, message fd.close() except Exception, e: print "LOGGER ERROR: Unable to write message '%s'" % repr(message) def debugLog(messageType, message): """Write message system log""" if not logging: return dateStr = time.strftime("%Y-%m-%d %H:%M:%S") typeStr = 'ERROR' if messageType == INFO: typeStr = 'INFO' elif messageType == WARNING: typeStr = 'WARNING' elif messageType == DEBUG: typeStr = 'DEBUG' print dateStr, typeStr, message opendict-0.6.8/lib/meta.py0000664000076400007640000000573613204646653015356 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Metaclasses """ from lib import errortype class SearchResult: """Search result metaclass""" def __init__(self): """Set default values""" self.error = errortype.OK self.translation = "" self.words = [] def setError(self, err): """Set error object""" self.error = err def getError(self): """Get error object""" return self.error def setTranslation(self, trans): """Set translation string""" self.translation = trans def getTranslation(self): """Get translation string""" return self.translation def setWordList(self, words): """Set word list""" self.words = words def getWordList(self): """Get word list""" return self.words class Dictionary: """Dictionary interface""" active = True def start(self): """Allocate resources""" pass def stop(self): """Free resources""" pass def getType(self): """Return dictionary type""" return None def getName(self): """Return plugin name""" return None def getVersion(self): """Return version""" return None def getSize(self): """Return size in kylobites""" return None def getPath(self): """Return ditionary path""" pass def getAuthors(self): """Return list of authors""" return None def setEncoding(self, encoding): """Set encoding""" pass def getEncoding(self): """Return encoding used by dictionary""" return None def getUsesWordList(self): """Return boolean value of word list usage""" return None def getDescription(self): """Returns description text""" return None def getLicence(self): """Return licence text""" return None def getActive(self): return self.active def setActive(self, active=True): self.active = active def search(self, word): """Lookup word""" return None opendict-0.6.8/lib/misc.py0000664000076400007640000000743613204646653015362 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # Module: misc import wx from os.path import * import string import traceback import sys import os _ = wx.GetTranslation # # FIXME: Remove # errors = {1: _("Not found"), 2: _("Dictionary error, please report to its author"), 3: _("Syntax error"), 4: _("You must be connected to the internet to use this dictionary"), 5: _("Time out"), 6: _("Bad encoding is set for this dictionary, try another")} # # Character Encodings # FIXME: translations does not work, why? # encodings = {_("Unicode (UTF-8)"): "UTF-8", _("Western (ISO-8859-1)"): "ISO-8859-1", _("Central European (ISO-8859-2)"): "ISO-8859-2", _("Nordic (ISO-8859-10)"): "ISO-8859-10", _("South European (ISO-8859-3)"): "ISO-8859-3", _("Greek (ISO-8859-7)"): "ISO-8859-7", _("Baltic (ISO-8859-13)"): "ISO-8859-13", _("Cyrillic (KOI8-R)"): "KOI8-R", _("Arabic (ISO-8859-6)"): "ISO-8859-6"} # # Font faces # fontFaces = {"Fixed": "fixed", "Helvetica": "helvetica", "Courier": "courier", "Times": "Times", "Verdana": "Verdana", "Lucida": "Lucida"} def numVersion(str): """Return a float number made from x.y.z[-preV] version number""" nver = str.split('-')[0] numbers = nver.split('.') try: return (float(numbers[0]) + float(numbers[1]) * 0.1 + float(number[2]) * 0.01) except: return 0.0 def printError(): print string.join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]), "") def getTraceback(): return string.join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]), "") def getFileSize(path): """Returns the size of file in bytes""" size = -1 try: size = os.stat(path)[6] except: print "ERROR (misc.getFileSize): path '%s' does not exist" % path return size def getDirSize(start, followLinks, myDepth, maxDepth): """Return total directory size""" total = 0L try: dirList = os.listdir(start) except: if isdir(start): print 'ERROR: Cannot list directory %s' % start return 0 for item in dirList: path = '%s/%s' % (start, item) try: stats = os.stat(path) except: print 'ERROR: Cannot stat %s' % path continue total += stats[6] if isdir(path) and (followLinks or \ (not followLinks and not islink(path))): bytes = getDirSize(path, followLinks, myDepth + 1, maxDepth) total += bytes return total opendict-0.6.8/lib/newplugin.py0000664000076400007640000002536113204646653016434 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # TODO: rename to "dictplugin.py" """ New plugin module """ import os import sys import traceback import xml.dom.minidom from lib import info from lib import meta from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR from lib import util class PluginInfo: """Plugin information""" def __init__(self, xmlData): """Parse XML data and store it into class attributes""" self.name = None self.version = None self.authors = [] self.module = {} self.encoding = None self.usesWordList = None self.opendictVersion = None self.pythonVersion = None self.platforms = [] self.description = None self.licenceFile = None self.xmlData = xmlData self._parse() def _parse(self): """Parse plugin information XML data""" doc = xml.dom.minidom.parseString(self.xmlData) pluginElement = doc.getElementsByTagName('plugin')[0] pluginType = pluginElement.getAttribute('type') if pluginType != 'dictionary': raise Exception, "Plugin is not dictionary plugin" # Get name for nameElement in doc.getElementsByTagName('name'): for node in nameElement.childNodes: if node.nodeType == node.TEXT_NODE: self.name = node.data # Get version for versionElement in doc.getElementsByTagName('version'): for node in versionElement.childNodes: if node.nodeType == node.TEXT_NODE: self.version = node.data # Get authors for authorElement in doc.getElementsByTagName('author'): authorName = authorElement.getAttribute('name') authorEMail = authorElement.getAttribute('email') self.authors.append({'name': authorName, 'email': authorEMail}) # Get module for moduleElement in doc.getElementsByTagName('module'): moduleName = None for node in moduleElement.childNodes: if node.nodeType == node.TEXT_NODE: moduleName = node.data moduleLang = moduleElement.getAttribute('lang') self.module = {'name': moduleName, 'lang': moduleLang} # Get encoding for encodingElement in doc.getElementsByTagName('encoding'): for node in encodingElement.childNodes: if node.nodeType == node.TEXT_NODE: self.encoding = node.data # Get info about word list usage for wordListElement in doc.getElementsByTagName('uses-word-list'): for node in wordListElement.childNodes: if node.nodeType == node.TEXT_NODE: self.usesWordList = node.data.lower() == 'true' # Get required OpenDict version for odVersionElement in doc.getElementsByTagName('opendict-version'): for node in odVersionElement.childNodes: if node.nodeType == node.TEXT_NODE: self.opendictVersion = node.data # Get required Python version for pyVersionElement in doc.getElementsByTagName('python-version'): for node in pyVersionElement.childNodes: if node.nodeType == node.TEXT_NODE: self.pythonVersion = node.data # Get supported platforms for platformElement in doc.getElementsByTagName('platform'): platformName = platformElement.getAttribute('name') self.platforms.append({'name': platformName}) self.platforms.sort() # Get description for descElement in doc.getElementsByTagName('description'): for node in descElement.childNodes: if node.nodeType == node.TEXT_NODE: self.description = node.data # Get licence file for licenceElement in doc.getElementsByTagName('licence'): for node in licenceElement.childNodes: if node.nodeType == node.TEXT_NODE: self.licenceFile = node.data class DictionaryPlugin(meta.Dictionary): """Dictionary plugin handler""" def __init__(self, path): """Prepare plugin and plugin information objects""" self.path = path try: self.info = self._loadInfo(path) except Exception, e: raise InvalidPluginException, e try: self.dictionary = self._loadPlugin(path) except Exception, e: raise InvalidPluginException, e def getType(self): """Return dictionary type""" from lib import dicttype return dicttype.PLUGIN def getName(self): """Return plugin name""" return self.info.name def setName(self, newName): """Set plugin name""" self.info.name = newName def getPath(self): """Return plugin location""" return self.path def getVersion(self): """Return version""" return self.info.version def getAuthors(self): """Return list of authors""" return self.info.authors def getModule(self): """Return module info""" return self.info.module def getEncoding(self): """Return encoding used by dictionary""" return self.info.encoding def getUsesWordList(self): """Return boolean value of word list usage""" return self.info.usesWordList def getOpendictVersion(self): """Return required min OpenDict version""" return self.info.opendictVersion def getPythonVersion(self): """Return required min Python version""" return self.info.pythonVersion def getPlatforms(self): """Return supported platforms""" return self.info.platforms def getDescription(self): """Returns description text""" return self.info.description def getLicence(self): """Return licence text (HTML format required)""" if self.info.licenceFile: try: fd = open(os.path.join(self.getPath(), self.info.licenceFile)) data = fd.read() fd.close() except Exception, e: systemLog(ERROR, "Unable to read licence file: %s" % e) data = 'Error: Licence file not found' else: data = '' return data def search(self, word): """Lookup word""" return self.dictionary.search(word) def _loadInfo(self, path): """Load plugin information""" try: fd = open(os.path.join(path, "plugin.xml")) xmlData = fd.read() fd.close() info = PluginInfo(xmlData) return info except Exception, e: raise InvalidPluginException, \ "Unable to load plugin info (%s)" % e def _loadPlugin(self, path): """Load plugin""" moduleName = os.path.splitext(self.info.module.get('name'))[0] fullPath = os.path.join(path, moduleName) try: del sys.modules[moduleName] except: pass sys.path.insert(0, path) module = __import__(moduleName) sys.path.remove(path) instance = module.init(info.GLOBAL_HOME) return instance # Usable? def isValid(self): """Validate plugin. Validates both plugin and plugin info objects""" try: assert hasattr(self.info, "name") assert hasattr(self.info, "version") assert hasattr(self.info, "authors") assert hasattr(self.info, "module") assert hasattr(self.info, "encoding") assert hasattr(self.info, "usesWordList") assert hasattr(self.info, "opendictVersion") assert hasattr(self.info, "pythonVersion") assert hasattr(self.info, "platforms") assert hasattr(self.info, "description") assert hasattr(self.dictionary, "search") assert callable(self.dictionary.search) return True except: return False def _loadDictionaryPlugin(directory): """Load dictionary plugin""" plugin = None try: plugin = DictionaryPlugin(directory) util.correctDictName(plugin) except InvalidPluginException, e: systemLog(ERROR, "Unable to load plugin from %s (%s)" % (directory, e)) return plugin def loadDictionaryPlugins(dictionaries, invalidDictionaries): """Load plugins. Returns list of PluginHandler objects""" pluginDirs = [] globalPluginPath = os.path.join(info.GLOBAL_HOME, info.__DICT_DIR, info.__PLUGIN_DICT_DIR) localPluginPath = os.path.join(info.LOCAL_HOME, info.__DICT_DIR, info.__PLUGIN_DICT_DIR) if os.path.exists(localPluginPath): pluginDirs = [os.path.join(localPluginPath, fileName) \ for fileName in os.listdir(localPluginPath) \ if os.path.isdir(os.path.join(localPluginPath, fileName))] if os.path.exists(globalPluginPath): for fileName in os.listdir(globalPluginPath): if os.path.isdir(os.path.join(globalPluginPath, fileName)) \ and not fileName in pluginDirs: pluginDirs.append(os.path.join(globalPluginPath, fileName)) plugins = [] for dirName in pluginDirs: plugin = _loadDictionaryPlugin(dirName) if plugin: plugins.append(plugin) dictionaries[plugin.getName()] = plugin else: invalidDictionaries.append(dirName) return plugins class InvalidPluginException(Exception): """This exception should be raised if plugin has some errors""" if __name__ == "__main__": loadPlugins() opendict-0.6.8/lib/parser.py0000664000076400007640000005554213204646653015724 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import time import string import re import os import traceback import xml.parsers.expat from lib.extra import dictclient from lib.extra import dictdlib from lib import info from lib import misc from lib import errortype from lib import meta from lib import plaindict from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR WORD_BG = "#dde2f1" # Bright blue DICT_BG = "#b4bedb" class SlowoParser(plaindict.PlainDictionary): """ Built-in Slowo Parser Parses file in Slowo format. """ def __init__(self, filePath): """Initialize""" self.filePath = filePath self.needsList = True self.name = os.path.splitext(os.path.basename(filePath))[0] # Additional information self.encoding = None self.checksum = None self.index = None self.configChanged = False def start(self): """Open file handle""" debugLog(DEBUG, "Opening file %s" % self.filePath) self.fd = open(self.filePath) def stop(self): """Close file handle""" try: debugLog(DEBUG, "Closing file %s" % self.filePath) self.fd.close() except: pass def setIndex(self, index): """Set index table""" self.index = index def getPath(self): """Return full file path""" return self.filePath def setChecksum(self, newSum, first=False): """Set checksum. Used after checksum change""" if self.checksum == None: self.configChanged = True self.checksum = newSum def getChecksum(self): """Return checksum""" return self.checksum def getType(self): """Return dictionary type""" from lib import dicttype return dicttype.SLOWO def setName(self, name): """Set new name""" self.name = name def getName(self): """Return file name""" return self.name def setEncoding(self, encoding): """Set encoding""" self.encoding = encoding self.configChanged = True def getEncoding(self): """Return encoding set for that dictionary""" return self.encoding def getUsesWordList(self): """Return True if uses word list, False otherwise""" return self.needsList def _appendTranslation(self, html, orig, trans): """Appends HTML strings to list""" html.append("") html.append("" % orig) html.append("
" % WORD_BG) html.append("%s
") html.append("

%s

" % trans) html.append("
") def search(self, word): """Lookup word""" _start = time.time() word_lowered = word.lower() encodedIndex = {} for literal in self.index: encodedIndex[literal.encode(self.getEncoding())] = \ self.index.get(literal) # # Seek to the beginning of the block # position = 0L if word_lowered[:2] in encodedIndex.keys(): position = encodedIndex[word_lowered[:2]] debugLog(DEBUG, "Index: %s->%d" % (word_lowered[:2], position)) debugLog(DEBUG, "SlowoParser: Seeking to %d" % position) self.fd.seek(position) html = [] html.append("") html.append("" \ % str(self.getEncoding())) html.append("") found = False words = [] result = meta.SearchResult() # DEBUG _linesRead = 0 for line in self.fd.xreadlines(): _linesRead += 1 line = line.strip() try: orig = "" end = "" try: orig, end = line.split('=', 1) except ValueError, e: systemLog(ERROR, '%s (line %s)' % (e, line)) orig = orig.strip() chunks = end.split(';') translation = ["
    "] for chunk in chunks: comment = [] trans = chunk.split('//') if len(trans) > 1: comment = trans[1:] trans = trans[:1] trans = "".join(trans).strip() comment = "".join(comment).strip() if len(trans) and len(comment) != 0: translation.append("
  • %s (%s)
  • " \ % (trans, comment)) elif len(trans): translation.append("
  • %s
  • " % trans) translation.append("
") translation = "".join(translation) except: traceback.print_exc() continue if line.lower().startswith(word_lowered): if not orig.lower().startswith(word_lowered): break if orig.lower() == word_lowered and not found: found = True self._appendTranslation(html, orig, translation) words.append(orig) if len(words) == 1: suggestedWord = orig suggestedTrans = translation elif len(words): break debugLog(DEBUG, "%d lines scanned" % _linesRead) if not found: if words: self._appendTranslation(html, suggestedWord, suggestedTrans) else: result.setError(errortype.NOT_FOUND) html.append("") try: translation = "".join(html) except: result.setError(errortype.INVALID_ENCOFING) translation = "" result.setTranslation(translation) result.setWordList(words) debugLog(DEBUG, "SlowoParser: search took %f seconds" \ % (time.time() - _start)) return result class MovaParser(plaindict.PlainDictionary): """ Built-in Mova Parser Parses file in 'Mova' dictionary format and does the search. """ def __init__(self, filePath): """Initialize""" self.filePath = filePath self.needsList = True self.name = os.path.splitext(os.path.basename(filePath))[0] # Additional variables self.encoding = None self.checksum = None self.index = None # If this is True when closing, the new configuration will be # written to disk self.configChanged = False def start(self): """Open file handle""" debugLog(DEBUG, "Opening file %s" % self.filePath) self.fd = open(self.filePath) def stop(self): """Close file handle""" try: debugLog(DEBUG, "Closing file %s" % self.filePath) self.fd.close() except: pass def setIndex(self, index): """Set index table""" self.index = index def getPath(self): """Return full file path""" return self.filePath def setChecksum(self, newSum, first=False): """Set checksum. Used after chekcsum change""" if self.checksum == None: self.configChanged = True self.checksum = newSum # If checksum is set not for the first time, remember to # update configuration #if not first: # self.configChanged = True def getChecksum(self): """Return checksum""" return self.checksum def getType(self): """Return dictionary type""" from lib import dicttype return dicttype.MOVA def setName(self, name): """Set new name""" self.name = name def getName(self): """Return file name""" return self.name def setEncoding(self, encoding): """Set encoding""" self.encoding = encoding self.configChanged = True def getEncoding(self): """Return encoding set for this dictionary""" return self.encoding def getUsesWordList(self): """Return True if uses word list, False otherwise""" return self.needsList def _appendTranslation(self, html, orig, trans): """Appends HTML strings to list""" html.append("") html.append("" % orig) html.append("
" % WORD_BG) html.append("%s
") html.append("

%s

" % trans) html.append("
") def search(self, word): """Lookup word""" _start = time.time() word_lowered = word.lower() encodedIndex = {} for literal in self.index: encodedIndex[literal.encode(self.getEncoding())] = \ self.index.get(literal) # # Seek to the beginning of the block # position = 0L if word_lowered[:2] in encodedIndex.keys(): position = encodedIndex[word_lowered[:2]] debugLog(DEBUG, "Index: %s->%d" % (word_lowered[:2], position)) debugLog(DEBUG, "MovaParser: Seeking to %d" % position) self.fd.seek(position) html = [] html.append("") html.append("" \ % str(self.getEncoding())) html.append("") found = False words = [] result = meta.SearchResult() # DEBUG _linesRead = 0 for line in self.fd.xreadlines(): _linesRead += 1 line = line.strip() try: orig, trans = line.split(" ", 1) except: continue if line.lower().startswith(word_lowered): if not orig.lower().startswith(word_lowered): break if orig.lower() == word_lowered and not found: found = True self._appendTranslation(html, orig, trans) words.append(orig) if len(words) == 1: suggestedWord = orig suggestedTrans = trans elif len(words): break debugLog(DEBUG, "%d lines scanned" % _linesRead) if not found: if words: self._appendTranslation(html, suggestedWord, suggestedTrans) else: result.setError(errortype.NOT_FOUND) html.append("") try: translation = "".join(html) except: result.setError(errortype.INVALID_ENCOFING) translation = "" result.setTranslation(translation) result.setWordList(words) debugLog(DEBUG, "MovaParser: Search took %f seconds" \ % (time.time() - _start)) return result # FIXME: Deprecated class TMXParser(plaindict.PlainDictionary): """Built-in TMX parser. Reads TMX files and does the search. """ def __init__(self, filePath): systemLog(WARNING, "***") systemLog(WARNING, "*** WARNING:") systemLog(WARNING, "*** TMX implementation is fuzzy and should " \ "not be used yet!") systemLog(WARNING, "***") self.name = os.path.splitext(os.path.basename(filePath))[0] self.needsList = True self.encoding = None self.mapping = {} self.header = {} self.trans = [] self.inSeg = 0 self.lang = "" def start(self): """Allocate resources""" parser = xml.parsers.expat.ParserCreate() parser.StartElementHandler = self.startElement parser.EndElementHandler = self.endElement parser.CharacterDataHandler = self.charData if file != "": fd = open(file) parser.Parse(fd.read(), 1) fd.close() def getType(self): """Return dictionary type""" return dicttype.TMX def setName(self, name): """Set new name""" self.name = name def getName(self): """Return file name""" return self.name def setEncoding(self, encoding): """Set encoding""" self.encoding = encoding def getEncoding(self): """Return encoding set for that dictionary""" return wx.GetApp().config.encoding def getUsesWordList(self): """Return True if uses word list, False otherwise""" return self.needsList def startElement(self, name, attrs): """Part of SAX parsing method""" if name == "tu": self.inTu = 1 elif name == "tuv": self.inTuv = 1 self.lang = attrs["lang"] elif name == "seg": self.inSeg = 1 elif name == "header": self.header["srclang"] = attrs["srclang"] self.header["creationtool"] = attrs["creationtool"] self.header["creationtoolversion"] = attrs["creationtoolversion"] self.header["o-tmf"] = attrs["o-tmf"] self.header["adminlang"] = attrs["adminlang"] self.header["datatype"] = attrs["datatype"] self.header["segtype"] = attrs["segtype"] def endElement(self, name): """Part of SAX parsing method""" if name == "tu": self.inTu = 0 self.mapping.setdefault(self.orig, []).extend(self.trans) self.trans = [] elif name == "tuv": self.inTuv = 0 elif name == "seg": self.inSeg = 0 def charData(self, data): """Part of SAX parsing method""" if self.inSeg: if self.lang == self.header["srclang"]: self.orig = data else: self.trans.append(data) def search(self, word): """Lookup word""" errno = 0 result = "" \ "" \ "" #"" % (self.window.encoding, # self.window.app.config.fontFace, # self.window.app.config.fontSize) keys = self.mapping.keys() avail = [] found = False word_lowered = word.lower() for key in keys: if key.lower().find(word_lowered) == 0: avail.append(key) if not found: result += "%s
" % key result += "
" result += " "*3+str("
"+" "*3).join(self.mapping[key]) result += "
" found = True result += "
" if len(avail) == 0: errno = 1 return (result, avail, errno) def makeHashTable(self): pass class DictParser(plaindict.PlainDictionary): """Built-in dictd dictionaries parser. Reads dictd dictionaries and does the search. """ def __init__(self, filePath): """Initialize""" self.filePath = filePath self.needsList = True self.name = os.path.splitext(os.path.splitext(os.path.basename(filePath))[0])[0] self.encoding = 'UTF-8' self.checksum = None self.configChanged = False self.dict = None self.definitions = None def start(self): """Allocate resources""" name = os.path.splitext(os.path.splitext(\ os.path.basename(self.filePath))[0])[0] indexFile = os.path.join(os.path.dirname(self.filePath), name) self.dict = dictdlib.DictDB(indexFile) def stop(self): """Free resources""" if self.dict: del self.dict def getPath(self): """Return full file path""" return self.filePath def getType(self): """Return dictionary type""" from lib import dicttype return dicttype.DICT def setName(self, name): """Set new name""" self.name = name def getName(self): """Return file name""" return self.name def setEncoding(self, encoding): """Set encoding""" self.encoding = encoding def getEncoding(self): """Return encoding set for that dictionary""" return self.encoding def setChecksum(self, newSum): """Set checksum. Used after chekcsum change""" if self.checksum == None: self.configChanged = True self.checksum = newSum def getUsesWordList(self): """Return True if uses word list, False otherwise""" return self.needsList def _getTranslation(self, word): """Return word and translation code without formatting full HTML document""" translations = self.dict.getdef(word) orig = None translation = None for source in translations: chunks = source.split('\n') map(string.strip, chunks) orig = chunks[0] pron = re.findall("\[(.*?)\]", orig) if len(pron) > 0: orig = "%s [%s]" % \ (orig.replace(" [%s]" % pron[0], ""), pron[0]) else: orig = "%s" % orig translation = ['
    '] for c in chunks[1:]: if len(c) > 0: translation.append("
  • %s
  • " % c) translation.append('
') translation = "".join(translation) links = re.findall("{(.*?)}", translation) for link in links: translation = translation.replace("{%s}" % link, "%s" \ % (link, link)) return (orig, translation) def search(self, word): """Lookup word""" _start = time.time() result = meta.SearchResult() word_lowered = word.lower() if self.definitions is None: self.definitions = self.dict.getdeflist() self.definitions.sort() words = [] for definition in self.definitions: if definition.lower().startswith(word_lowered): words.append(definition) html = [] html.append("") html.append("" \ % str(self.getEncoding())) html.append("") (orig, translation) = self._getTranslation(word) if not translation: if len(words): debugLog(DEBUG, "Retrying search...") _word = words[0] orig, translation = self._getTranslation(_word) if not translation: result.setError(errortype.NOT_FOUND) else: result.setError(errortype.NOT_FOUND) translation = "" html.append("") html.append("" % orig) html.append("
" % WORD_BG) html.append("%s
") html.append("

%s

" % translation) html.append("
") html.append("") result.setTranslation("".join(html)) result.setWordList(words) debugLog(DEBUG, "DictParser: Search took % f seconds" \ % (time.time() - _start)) return result # TODO: # 1. This is not a parser, move to another module # 2. Add needed methods # class DictConnection(meta.Dictionary): """Built-in DICT client Connects to a DICT server abd does the search. """ def __init__(self, server, port, db, strategy): self.server = server self.port = port self.db = db self.strategy = strategy self.encoding = "UTF-8" self.needsList = 0 self.name = 'Connection to DICT server' def getUsesWordList(self): """Return True if uses word list, False otherwise""" return self.needsList def setName(self, name): """Set new name""" self.name = name def getName(self): """Return name""" return self.name def setEncoding(self, encoding): """Set encoding""" self.encoding = encoding def getEncoding(self): """Return encoding""" return self.encoding def search(self, word): """Lookup word""" result = meta.SearchResult() try: conn = dictclient.Connection(self.server, self.port) except: result.setError(errortype.CONNECTION_ERROR) return result html = [] html.append("" \ "" \ "" % self.getEncoding()) found = False try: data = conn.define(self.db, word) except: data = [] for d in data: found = True html.append("

") html.append("" % d.getdb().getdescription()) source = d.getdefstr() source = source.replace('<', '<') source = source.replace('>', '>') orig = source.split("\n", 1)[0] pron = re.findall("\[(.*?)\]", orig) # 1st comment type pronPatt = " [%s]" if len(pron) == 0: pron = re.findall("\/(.*?)\/", orig) # 2nd comment type pronPatt = " /%s/" if len(pron) == 0: pron = re.findall(r"\\(.*?)\\", orig) # 3rd comment type pronPatt = " \\%s\\" if len(pron) > 0: orig = "%s [%s]" % \ (orig.replace(pronPatt % pron[0], ""), pron[0]) else: orig = "%s" % orig html.append("" % orig) source = source.replace('\n\n', '

') translation = ' '.join(source.split('\n')[:]) links = re.findall("{(.*?)}", translation) for link in links: translation = translation.replace("{%s}" % link, "%s" % (link, link)) html.append("" % translation) html.append("
" % DICT_BG) html.append("%s
" % WORD_BG) html.append("%s
%s

") html.append("") result.setTranslation(''.join(html)) if not found: result.setError(errortype.NOT_FOUND) return result opendict-0.6.8/lib/plaindict.py0000664000076400007640000003166413204646653016376 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Module for plain dictionaries """ import os import traceback from lib import info from lib import meta from lib import util from lib import xmltools from lib import util from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR class PlainDictInfo: """Plain dictionary configuration""" def __init__(self, directory): """Store configuration data""" raise Exception, "PlainDictInfo is deprecated" self.config = xmltools.parsePlainDictConfig(\ os.path.join(directory, info.__PLAIN_DICT_CONFIG_DIR, 'config.xml')) self.directory = directory self.name = config.get('name') self.formatString = config.get('format') self.version = config.get('version') self.author = config.get('author') self.path = config.get('path') self.checksum = config.get('md5') self.encoding = config.get('encoding') def getFormatString(self): """Return format name""" return self.formatString def getName(self): """Return name""" return self.name def getVersion(self): """Return version number""" return self.version def getAuthor(self): """Return author""" return self.author def getPath(self): """Return full file path""" return self.path def getChecksum(self): """Return checksum""" return self.checksum def getEncoding(self): """Return encoding""" return self.encoding def getLicence(self): """Return licence text""" filePath = self.licence if filePath: if not os.path.exists(filePath): filePath = os.path.join(self.directory, info._PLAIN_DICT_DATA_DIR, self.licence) if not os.path.exists(filePath): filePath = None errMsg = "Error: licence file not found" if not filePath: systemLog(ERROR, "Cannot find defined licence file for %s: %" \ % (self.getName(), e)) return errMsg try: fd = open(filePath) data = fd.read() fd.close() return data except Exception, e: systemLog(ERROR, "Unable to read licence file for %s: %" \ % (self.getName(), e)) return errMsg return None class PlainDictionary(meta.Dictionary): """Plain dictionary class""" licenceFile = None version = None authors = [] def getConfigDir(self): """Return configuration directory path""" if os.path.exists(os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR, os.path.basename(self.getPath()))): path = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR, os.path.basename(self.getPath())) else: path = os.path.join(info.GLOBAL_HOME, info.PLAIN_DICT_DIR, os.path.basename(self.getPath())) return path def setLicenceFile(self, licenceFile): """Set licence file path""" self.licenceFile = licenceFile def getLicenceFile(self): """Return licence file""" return self.licenceFile def getLicence(self): """Return licence text""" filePath = self.licenceFile if filePath: if not os.path.exists(filePath): filePath = os.path.join(self.getConfigDir(), info._PLAIN_DICT_DATA_DIR, self.licenceFile) if not os.path.exists(filePath): filePath = None errMsg = "Error: licence file not found" if not filePath: systemLog(ERROR, "Cannot find defined licence file '%s' for '%s'" \ % (self.licenceFile, self.getName())) return errMsg try: fd = open(filePath) data = fd.read() fd.close() return data except Exception, e: systemLog(ERROR, "Unable to read licence file for %s: %" \ % (self.getName(), e)) return errMsg return None def setVersion(self, version): """Set version number""" self.version = version def getVersion(self): """Return version number""" return self.version def setAuthors(self, authors): """Set author""" self.authors = authors def getAuthors(self): """Return author""" return self.authors def setDescription(self, desc): """Set description""" self.description = desc def getDescription(self): """Get description""" return self.description def _loadPlainDictionary(directory): """Load one dictionary and returns dictionary object""" from lib import dicttype dictionary = None Parser = None try: config = xmltools.parsePlainDictConfig(\ os.path.join(directory, info.__PLAIN_DICT_CONFIG_DIR, 'config.xml')) for t in dicttype.supportedTypes: if t.getIdName() == config.get('format'): Parser = t.getClass() if not Parser: raise Exception, "This is internal error and should not happen: " \ "no parser class found for dictionary in %s" % directory filePath = config.get('path') fileName = os.path.basename(filePath) home = info.LOCAL_HOME if directory.startswith(info.GLOBAL_HOME): home = info.GLOBAL_HOME if not os.path.exists(filePath): newPath = os.path.join(home, info.PLAIN_DICT_DIR, fileName, info.__PLAIN_DICT_FILE_DIR, fileName) if os.path.exists(newPath): filePath = newPath else: filePath = None if not filePath: raise Exception, "Dictionary file not found: %s" % fileName dictionary = Parser(filePath) dictionary.setEncoding(config.get('encoding')) dictionary.setName(config.get('name')) dictionary.setVersion(config.get('version')) dictionary.setAuthors(config.get('authors')) dictionary.setChecksum(config.get('md5')) dictionary.setLicenceFile(config.get('licence')) dictionary.setDescription(config.get('description')) except Exception, e: traceback.print_exc() util.correctDictName(dictionary) return dictionary def loadPlainDictionaries(dictionaries): """Load dictionaries and return a list of dictionary objects""" dirs = [] globalDictDir = os.path.join(info.GLOBAL_HOME, info.PLAIN_DICT_DIR) localDictDir = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR) if os.path.exists(globalDictDir): for directory in os.listdir(globalDictDir): if os.path.isdir(os.path.join(globalDictDir, directory)): dirs.append(os.path.join(globalDictDir, directory)) if os.path.exists(localDictDir): for directory in os.listdir(localDictDir): if os.path.isdir(os.path.join(localDictDir, directory)): dirs.append(os.path.join(localDictDir, directory)) plainDicts = [] for directory in dirs: dictionary = _loadPlainDictionary(directory) if dictionary: plainDicts.append(dictionary) dictionaries[dictionary.getName()] = dictionary return plainDicts def indexShouldBeMade(dictionary): """Check if index exists and is up to date. Return True if dictionary must be indexed. """ filePath = dictionary.getPath() fileName = os.path.basename(filePath) dictLocalHome = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR, fileName) dictGlobalHome = os.path.join(info.GLOBAL_HOME, info.PLAIN_DICT_DIR, fileName) if not os.path.exists(os.path.join(dictGlobalHome, 'data', 'index.xml')) \ and not os.path.exists(os.path.join(dictLocalHome, 'data', 'index.xml')): return True debugLog(INFO, "Old checksum: %s" % dictionary.getChecksum()) newChecksum = util.getMD5Sum(filePath) debugLog(INFO, "New checksum: %s" % newChecksum) return dictionary.getChecksum() != newChecksum def makeIndex(dictionary, currentlySetEncoding): """Index dictionary""" filePath = dictionary.getPath() fd = open(filePath) index = {} count = 0L linenum = -1 for line in fd: linenum += 1 try: literal = unicode(line.strip(), dictionary.getEncoding())[:2].lower() except: try: literal = unicode(line.strip(), currentlySetEncoding)[:2].lower() dictionary.setEncoding(currentlySetEncoding) except: raise Exception, "Unable to encode data in %s nor %s " \ "at line %d" \ % (dictionary.getEncoding(), currentlySetEncoding, linenum) # Ignore if control character found if literal and not literal in index.keys() and literal[0] > u'\x19': try: index[literal] = count except Exception, e: systemLog(ERROR, e) count += len(line) fileName = os.path.basename(filePath) dictHome = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR, fileName) toUnicode = lambda s: unicode(s, dictionary.getEncoding()) doc = xmltools.generateIndexFile(index) xmltools.writeIndexFile(doc, os.path.join(dictHome, 'data', 'index.xml')) savePlainConfiguration(dictionary) def loadIndex(dictionary): """Load index table""" dictIndex = os.path.join(dictionary.getConfigDir(), 'data', 'index.xml') index = None if os.path.exists(dictIndex): index = xmltools.parseIndexFile(dictIndex) if not index: raise Exception, "Index for %s does not exist" % dictionary.getName() return index def savePlainConfiguration(dictionary): """Write configuration to disk""" from lib import dicttype if not dictionary.getType() in dicttype.plainTypes: systemLog(ERROR, "Request to write configuration to %s of type %s" \ % (dictionary.getName(), dictionary.getType())) return md5sum = util.getMD5Sum(dictionary.getPath()) dictDir = dictionary.getConfigDir() doc = xmltools.generatePlainDictConfig(name=dictionary.getName(), format=dictionary.getType().getIdName(), version=dictionary.getVersion(), authors=dictionary.getAuthors(), path=dictionary.getPath(), md5=md5sum, encoding=dictionary.getEncoding(), description=dictionary.getDescription(), licence=dictionary.getLicenceFile()) xmltools.writePlainDictConfig(doc, os.path.join(dictDir, 'conf', 'config.xml')) opendict-0.6.8/lib/threads.py0000664000076400007640000000463413204646653016056 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # Module: threads from threading import * import sys import os import copy import traceback import string class KThread(Thread): """Thread that can be killed during its run()""" def join(self, timeout=None): """Kill it""" Thread.join(self, timeout) print "Thread killing himself" #os._exit(0) class Process: def __init__(self, func, *param): self.__done = 0 self.__result = None self.__status = "working" self.__C = Condition() # Seperate thread self.__T = Thread(target=self.Wrapper, args=(func, param)) self.__T.setName("ProcessThread") self.__T.start() def __repr__(self): return "" def __call__(self): self.__C.acquire() while self.__done == 0: self.__C.wait() self.__C.release() result = copy.copy(self.__result) return result def isDone(self): return self.__done def stop(self): # FIXME: this actually doesn't kill the running process # Needs to be done. Help? #Thread.join(self.__T, None) self.__T.join(0) def Wrapper(self, func, param): self.__C.acquire() try: self.__result = func(*param) except: self.__result = None print string.join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]), "") self.__done = 1 self.__status = "self.__result" self.__C.notify() self.__C.release() opendict-0.6.8/lib/util.py0000664000076400007640000002132613204646653015376 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Utility functions """ import wx _ = wx.GetTranslation import os import md5 import threading import time import urllib2 import traceback from lib import info from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR class UniqueIdGenerator: """Unique ID generator (using singleton design pattern)""" class _RealGenerator: """Unique ID generator""" def __init__(self, start=0): """Set starting ID value""" self.id = start def getID(self): """Return unique ID""" self.id += 1 return self.id __instance = None def __init__(self, start=0): """Create new instance if not exists yet""" if UniqueIdGenerator.__instance is None: UniqueIdGenerator.__instance = self._RealGenerator(start) def getID(self): """Return unique ID""" return self.__instance.getID() def generateUniqueID(): """Helper function for getting unique ID""" gen = UniqueIdGenerator(7000) return gen.getID() def getMD5Sum(filePath): """Return MD5 checksum for given file""" fd = open(filePath, 'rb') data = fd.read() fd.close() generator = md5.new(data) return generator.hexdigest() def makeDirectories(): """Make needed directories if not exist""" if not os.path.exists(info.LOCAL_HOME): os.mkdir(info.LOCAL_HOME) logDir = os.path.join(info.LOCAL_HOME, info.LOG_DIR) if not os.path.exists(logDir): os.mkdir(logDir) plainDir = os.path.join(info.LOCAL_HOME, info.PLAIN_DICT_DIR) pluginDir = os.path.join(info.LOCAL_HOME, info.PLUGIN_DICT_DIR) if not os.path.exists(info.LOCAL_HOME): try: systemLog(DEBUG, "%s does not exist, creating..." \ % info.LOCAL_HOME) os.mkdir(info.LOCAL_HOME) except Exception, e: systemLog(ERROR, "Unable to create %s (%s)" % (info.LOCAL_HOME, e)) if not os.path.exists(os.path.join(info.LOCAL_HOME, info.__DICT_DIR)): try: systemLog(DEBUG, "%s does not exist, creating..." \ % os.path.join(info.LOCAL_HOME, info.__DICT_DIR)) os.mkdir(os.path.join(info.LOCAL_HOME, info.__DICT_DIR)) except Exception, e: systemLog(ERROR, "Unable to create %s (%s)" \ % (os.path.join(info.LOCAL_HOME, info.__DICT_DIR), e)) if not os.path.exists(plainDir): try: systemLog(DEBUG, "%s does not exist, creating..." % plainDir) os.mkdir(plainDir) except Exception, e: systemLog(ERROR, "Unable to create %s (%s)" % (plainDir, e)) if not os.path.exists(pluginDir): try: os.mkdir(pluginDir) except Exception, e: systemLog(ERROR, "Unable to create %s (%s)" % (pluginDir, e)) class DownloadThread: """Non-blocking download thread Can be used to connect and download files from the Internet. """ def __init__(self, url): """Initialize variables""" self.url = url self.thread = threading.Thread(target=self.worker) self.thread.setDaemon(True) # Daemonize for fast exiting self.statusMessage = '' self.errorMessage = None self.percents = 0 self.stopRequested = False self.done = False self.buffer = '' def start(self): """Start thread""" self.thread.start() def stop(self): """Request thread to stop, may hang for some time""" self.stopRequested = True def getMessage(self): """Return status message""" return self.statusMessage def getErrorMessage(self): """Return error message""" return self.errorMessage def getPercentage(self): """Return percentage""" return self.percents def finished(self): """Return True if finished, False otherwise""" return self.done def getBytes(self): """Return buffered bytes and clear the buffer""" bytes = self.buffer self.buffer = '' return bytes def worker(self): """Main worker method""" try: serverName = '/'.join(self.url.split('/')[:3]) except: serverName = self.url try: self.statusMessage = _("Connecting to %s...") % serverName self.up = urllib2.urlopen(self.url) fileSize = int(self.up.info().getheader('Content-length')) except Exception, e: self.errorMessage = "Unable to connect to %s" % serverName self.done = True return count = 0 try: while not self.stopRequested and count < fileSize: bytes = self.up.read(1024) count += len(bytes) self.buffer += bytes self.percents = int(float(count) / fileSize * 100) self.statusMessage = _("Downloading... %d%%") % self.percents time.sleep(0.005) # To lower CPU usage self.up.close() self.done = True self.statusMessage = _("Done") except Exception, e: self.errorMessage = "Error while fetching data from %s: %s" \ % (self.url, e) self.done = True class AgreementsManager: """Manages information about licence agreements for dictionaries""" def __init__(self, filePath): """Initialize variables""" self.filePath = filePath self.dictPaths = [] self._load() def addAgreement(self, dictConfigPath): """Mark dictionary licence as accepted""" dictConfigPath = os.path.realpath(dictConfigPath) if not dictConfigPath in self.dictPaths: self.dictPaths.append(dictConfigPath) self._updateFile() def removeAgreement(self, dictConfigPath): """Mark dictionary licence as rejected, i.e. remove from accepted list""" dictConfigPath = os.path.realpath(dictConfigPath) if dictConfigPath in self.dictPaths: self.dictPaths.remove(dictConfigPath) self._updateFile() def getAccepted(self, dictConfigPath): """Return True if dictionary licence is marked as accepted""" dictConfigPath = os.path.realpath(dictConfigPath) if dictConfigPath in self.dictPaths: return True else: return False def _load(self): """Read data from file""" try: fd = open(self.filePath) update = False for line in fd: line = line.strip() if os.path.exists(line) and not line in self.dictPaths: self.dictPaths.append(line) else: update = True fd.close() # Rewrite contents if non-existent directories exist if update: self._updateFile() except: pass def _updateFile(self): """Write changes to file""" fd = open(self.filePath, 'w') for path in self.dictPaths: print >> fd, path fd.close() # # FIXME: doesn't work correctly # def correctDictName(dictInstance): """Set name to 'Name (X)', where X is Xth occurance of the name""" return def _nameMatches(name, nameList): matches = 0 for n in nameList: try: if n.startswith(name): matches += 1 except Exception, e: print "WARNING:", e return matches import wx dictionaries = wx.GetApp().dictionaries # Sucks! matches = _nameMatches(dictInstance.getName(), dictionaries.keys()) if matches: dictInstance.setName("%s (%d)" % (dictInstance.getName(), matches+1)) opendict-0.6.8/lib/xmltools.py0000664000076400007640000003333213204646653016302 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import xml.dom.minidom from lib import meta def _textData(element): """Return text data from given XML element""" text = '' for node in element.childNodes: text = node.data.strip() return text class RegisterConfigGenerator: """Class for generating register configuration files""" def generate(self, **args): """Generate config XML object""" doc = xml.dom.minidom.Document() registerElement = doc.createElement('plain-dictionary') doc.appendChild(registerElement) # Format element formatElement = doc.createElement('format') registerElement.appendChild(formatElement) formatElement.appendChild(doc.createTextNode(args.get('format'))) # Name element nameElement = doc.createElement('name') registerElement.appendChild(nameElement) nameElement.appendChild(doc.createTextNode(args.get('name'))) # Version element versionElement = doc.createElement('version') registerElement.appendChild(versionElement) versionElement.appendChild(doc.createTextNode(args.get('version') \ or '')) # Authors element authorsElement = doc.createElement('authors') registerElement.appendChild(authorsElement) for author in (args.get('authors') or []): authorElement = doc.createElement('author') authorsElement.appendChild(authorElement) authorElement.setAttribute('name', author.get('name')) authorElement.setAttribute('email', author.get('email')) # Path element pathElement = doc.createElement('path') registerElement.appendChild(pathElement) pathElement.appendChild(doc.createTextNode(args.get('path'))) # MD5 element md5Element = doc.createElement('md5') registerElement.appendChild(md5Element) md5Element.appendChild(doc.createTextNode(args.get('md5'))) # Encoding element encodingElement = doc.createElement('encoding') registerElement.appendChild(encodingElement) encodingElement.appendChild(doc.createTextNode(args.get('encoding'))) # Licence element licElement = doc.createElement('licence') registerElement.appendChild(licElement) licElement.appendChild(doc.createTextNode(args.get('licence') \ or '')) # Description element descElement = doc.createElement('description') registerElement.appendChild(descElement) descElement.appendChild(doc.createTextNode(args.get('description') \ or '')) return doc def generatePlainDictConfig(**args): """Generate configuration and return DOM object""" generator = RegisterConfigGenerator() doc = generator.generate(**args) return doc def writePlainDictConfig(doc, path): """Write XML file""" import codecs fd = codecs.open(path, 'w', 'utf-8') doc.writexml(fd, addindent = " ", newl = "\n", encoding = "UTF-8") fd.close() class RegisterConfigParser: """Parse register configuration""" def parse(self, xmlData): """Parse XML data""" doc = xml.dom.minidom.parseString(xmlData) name = None format = None version = None authors = [] path = None md5 = None encoding = None licence = None description = None registers = doc.getElementsByTagName('plain-dictionary') if len(registers) == 0: raise Exception("Invalid configuration") registerElement = registers[0] for nameElement in registerElement.getElementsByTagName('name'): for node in nameElement.childNodes: name = node.data.strip() for formatElement in registerElement.getElementsByTagName('format'): for node in formatElement.childNodes: format = node.data.strip() for pathElement in registerElement.getElementsByTagName('path'): for node in pathElement.childNodes: path = node.data.strip() for versionElement in registerElement.getElementsByTagName('version'): for node in versionElement.childNodes: version = node.data.strip() for authorElement in registerElement.getElementsByTagName('author'): authors.append({'name': authorElement.getAttribute('name').strip(), 'email': authorElement.getAttribute('email').strip()}) for md5Element in registerElement.getElementsByTagName('md5'): for node in md5Element.childNodes: md5 = node.data.strip() for encodingElement in \ registerElement.getElementsByTagName('encoding'): for node in encodingElement.childNodes: encoding = node.data.strip() for licenceElement in \ registerElement.getElementsByTagName('licence'): for node in licenceElement.childNodes: licence = node.data.strip() for descElement in \ registerElement.getElementsByTagName('description'): for node in descElement.childNodes: description = (description or '') + node.data.strip() result = {} result['name'] = name result['format'] = format result['version'] = version result['authors'] = authors result['path'] = path result['md5'] = md5 result['encoding'] = encoding result['licence'] = licence result['description'] = description return result def parsePlainDictConfig(configPath): """Parse configuration file and return data dictionary""" parser = RegisterConfigParser() fd = open(configPath) xmlData = fd.read() fd.close() data = parser.parse(xmlData) return data class IndexFileGenerator: """Class for generating register configuration files""" def generate(self, index): """Generate config XML object""" doc = xml.dom.minidom.Document() indexElement = doc.createElement("index") doc.appendChild(indexElement) for data, pos in index.items(): startElement = doc.createElement("element") startElement.setAttribute("literal", data) startElement.setAttribute("position", str(pos)) indexElement.appendChild(startElement) return doc def generateIndexFile(index): """Generate index data and return DOM object""" generator = IndexFileGenerator() doc = generator.generate(index) return doc def writeIndexFile(doc, path): """Write XML file""" import codecs fd = codecs.open(path, 'wb', 'utf-8') doc.writexml(fd, addindent = " ", newl = "\n", encoding = "UTF-8") fd.close() class IndexFileParser: """Parse register configuration""" def parse(self, xmlData): """Parse XML data""" doc = xml.dom.minidom.parseString(xmlData) index = {} indexElement = doc.getElementsByTagName('index')[0] for element in indexElement.getElementsByTagName('element'): index[element.getAttribute("literal")] = long(element.getAttribute("position")) return index def parseIndexFile(indexPath): """Parse configuration file and return data dictionary""" parser = IndexFileParser() fd = open(indexPath, 'rb') xmlData = fd.read() fd.close() index = parser.parse(xmlData) return index class AddOnsParser: """Parse add-ons file""" class EmptyDictionary(meta.Dictionary): """Empty dictionary for representing add-on information""" name = None version = None size = None checksum = None authors = [] location = None desc = None atype = None def setType(self, t): self.atype = t def getType(self): return self.atype def setName(self, name): self.name = name def getName(self): return self.name def setVersion(self, version): self.version = version def getVersion(self): return self.version def setSize(self, size): self.size = size def getSize(self): return self.size def setChecksum(self, checksum): self.checksum = checksum def getChecksum(self): return self.checksum def addAuthor(self, author): self.authors.append(author) def getAuthors(self): return self.authors def setLocation(self, location): self.location = location def getLocation(self): return self.location def setDescription(self, desc): self.desc = desc def getDescription(self): return self.desc def parse(self, xmlData): """Parse XML data and return name->info dictionary object""" doc = xml.dom.minidom.parseString(xmlData) addons = {} for addonElement in doc.getElementsByTagName('add-on'): name = None version = None authors = [] description = None size = None url = None checksum = None addonType = addonElement.getAttribute('type') for nameElement in addonElement.getElementsByTagName('name'): name = _textData(nameElement) for versionElement in addonElement.getElementsByTagName('version'): version = _textData(versionElement) for authorElement in addonElement.getElementsByTagName('author'): authors.append({'name': authorElement.getAttribute('name'), 'email': authorElement.getAttribute('email')}) for descElement \ in addonElement.getElementsByTagName('description'): description = _textData(descElement) for urlElement in addonElement.getElementsByTagName('url'): url = _textData(urlElement) for sizeElement in addonElement.getElementsByTagName('size'): size = long(_textData(sizeElement)) for sumElement in addonElement.getElementsByTagName('md5'): checksum = _textData(sumElement) emptyDict = self.EmptyDictionary() emptyDict.setName(name) emptyDict.setVersion(version) emptyDict.authors = [] # To forget an old reference for author in authors: emptyDict.addAuthor(author) emptyDict.setDescription(description) emptyDict.setLocation(url) emptyDict.setSize(size) emptyDict.setChecksum(checksum) addons[name] = emptyDict return addons def parseAddOns(xmlData): """Wrap add-ons data parsing""" parser = AddOnsParser() result = parser.parse(xmlData) return result class MainConfigParser: """Parse main configuration""" def parse(self, xmlData): """Parse XML data""" doc = xml.dom.minidom.parseString(xmlData) props = {} configs = doc.getElementsByTagName('main-config') if len(configs) == 0: raise Exception("Invalid configuration") configElement = configs[0] for node in configElement.childNodes: if not node.nodeType == node.ELEMENT_NODE: continue for cnode in node.childNodes: name = node.nodeName value = cnode.data.strip() props[name] = value return props def parseMainConfig(configPath): """Parse configuration file and return data dictionary""" parser = MainConfigParser() fd = open(configPath) xmlData = fd.read() fd.close() data = parser.parse(xmlData) return data class MainConfigGenerator: """Class for generating main configuration file""" def generate(self, props): """Generate config XML object""" doc = xml.dom.minidom.Document() mainElement = doc.createElement("main-config") doc.appendChild(mainElement) for key, value in props.items(): elem = doc.createElement(key) mainElement.appendChild(elem) if type(value) != unicode: value = str(value) elem.appendChild(doc.createTextNode(value)) return doc def generateMainConfig(props): """Generate configuration and return DOM object""" generator = MainConfigGenerator() doc = generator.generate(props) return doc def writeConfig(doc, path): """Write XML file""" import codecs fd = codecs.open(path, 'w', 'utf-8') doc.writexml(fd, addindent = " ", newl = "\n", encoding = "UTF-8") fd.close() opendict-0.6.8/lib/extra/0000775000076400007640000000000013204646653015166 5ustar nerijusnerijusopendict-0.6.8/lib/extra/__init__.py0000664000076400007640000000000013204646653017265 0ustar nerijusnerijusopendict-0.6.8/lib/extra/dictclient.py0000664000076400007640000003011613204646653017663 0ustar nerijusnerijus# Client for the DICT protocol (RFC2229) # # Copyright (C) 2002 John Goerzen # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import socket, re version = '1.0' def dequote(str): """Will remove single or double quotes from the start and end of a string and return the result.""" quotechars = "'\"" while len(str) and str[0] in quotechars: str = str[1:] while len(str) and str[-1] in quotechars: str = str[0:-1] return str def enquote(str): """This function will put a string in double quotes, properly escaping any existing double quotes with a backslash. It will return the result.""" return '"' + str.replace('"', "\\\"") + '"' class Connection: """This class is used to establish a connection to a database server. You will usually use this as the first call into the dictclient library. Instantiating it takes two optional arguments: a hostname (a string) and a port (an int). The hostname defaults to localhost and the port to 2628, the port specified in RFC.""" def __init__(self, hostname = 'localhost', port = 2628): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((hostname, port)) self.rfile = self.sock.makefile("rt") self.wfile = self.sock.makefile("wt", 0) self.saveconnectioninfo() def getresultcode(self): """Generic function to get a result code. It will return a list consisting of two items: the integer result code and the text following. You will not usually use this function directly.""" line = self.rfile.readline().strip() code, text = line.split(' ', 1) return [int(code), text] def get200result(self): """Used when expecting a single line of text -- a 200-class result. Returns [intcode, remaindertext]""" code, text = self.getresultcode() if code < 200 or code >= 300: raise Exception, "Got '%s' when 200-class response expected" % \ line return [code, text] def get100block(self): """Used when expecting multiple lines of text -- gets the block part only. Does not get any codes or anything! Returns a string.""" data = [] while 1: line = self.rfile.readline().strip() if line == '.': break data.append(line) return "\n".join(data) def get100result(self): """Used when expecting multiple lines of text, terminated by a period and a 200 code. Returns: [initialcode, [bodytext_1lineperentry], finalcode]""" code, text = self.getresultcode() if code < 100 or code >= 200: raise Exception, "Got '%s' when 100-class response expected" % \ code bodylines = self.get100block().split("\n") code2 = self.get200result()[0] return [code, bodylines, code2] def get100dict(self): """Used when expecting a dictionary of results. Will read from the initial 100 code, to a period and the 200 code.""" dict = {} for line in self.get100result()[1]: key, val = line.split(' ', 1) dict[key] = dequote(val) return dict def saveconnectioninfo(self): """Called by __init__ to handle the initial connection. Will save off the capabilities and messageid.""" code, string = self.get200result() assert code == 220 capstr, msgid = re.search('<(.*)> (<.*>)$', string).groups() self.capabilities = capstr.split('.') self.messageid = msgid def getcapabilities(self): """Returns a list of the capabilities advertised by the server.""" return self.capabilities def getmessageid(self): """Returns the message id, including angle brackets.""" return self.messageid def getdbdescs(self): """Gets a dict of available databases. The key is the db name and the value is the db description. This command may generate network traffic!""" if hasattr(self, 'dbdescs'): return self.dbdescs self.sendcommand("SHOW DB") self.dbdescs = self.get100dict() return self.dbdescs def getstratdescs(self): """Gets a dict of available strategies. The key is the strat name and the value is the strat description. This call may generate network traffic!""" if hasattr(self, 'stratdescs'): return self.stratdescs self.sendcommand("SHOW STRAT") self.stratdescs = self.get100dict() return self.stratdescs def getdbobj(self, dbname): """Gets a Database object corresponding to the database name passed in. This function explicitly will *not* generate network traffic. If you have not yet run getdbdescs(), it will fail.""" if not hasattr(self, 'dbobjs'): self.dbobjs = {} if self.dbobjs.has_key(dbname): return self.dbobjs[dbname] # We use self.dbdescs explicitly since we don't want to # generate net traffic with this request! if dbname != '*' and dbname != '!' and \ not dbname in self.dbdescs.keys(): raise Exception, "Invalid database name '%s'" % dbname self.dbobjs[dbname] = Database(self, dbname) return self.dbobjs[dbname] def sendcommand(self, command): """Takes a command, without a newline character, and sends it to the server.""" self.wfile.write(command + "\n") def define(self, database, word): """Returns a list of Definition objects for each matching definition. Parameters are the database name and the word to look up. This is one of the main functions you will use to interact with the server. Returns a list of Definition objects. If there are no matches, an empty list is returned. Note: database may be '*' which means to search all databases, or '!' which means to return matches from the first database that has a match.""" self.getdbdescs() # Prime the cache if database != '*' and database != '!' and \ not database in self.getdbdescs(): raise Exception, "Invalid database '%s' specified" % database self.sendcommand("DEFINE " + enquote(database) + " " + enquote(word)) code = self.getresultcode()[0] retval = [] if code == 552: # No definitions. return [] if code != 150: raise Exception, "Unknown code %d" % code while 1: code, text = self.getresultcode() if code != 151: break resultword, resultdb = re.search('^"(.+)" (\S+)', text).groups() defstr = self.get100block() retval.append(Definition(self, self.getdbobj(resultdb), resultword, defstr)) return retval def match(self, database, strategy, word): """Gets matches for a query. Arguments are database name, the strategy (see available ones in getstratdescs()), and the pattern/word to look for. Returns a list of Definition objects. If there is no match, an empty list is returned. Note: database may be '*' which means to search all databases, or '!' which means to return matches from the first database that has a match.""" self.getstratdescs() # Prime the cache self.getdbdescs() # Prime the cache if not strategy in self.getstratdescs().keys(): raise Exception, "Invalid strategy '%s'" % strategy if database != '*' and database != '!' and \ not database in self.getdbdescs().keys(): raise Exception, "Invalid database name '%s'" % database self.sendcommand("MATCH %s %s %s" % (enquote(database), enquote(strategy), enquote(word))) code = self.getresultcode()[0] if code == 552: # No Matches return [] if code != 152: raise Exception, "Unexpected code %d" % code retval = [] for matchline in self.get100block().split("\n"): matchdict, matchword = matchline.split(" ", 1) retval.append(Definition(self, self.getdbobj(matchdict), dequote(matchword))) if self.getresultcode()[0] != 250: raise Exception, "Unexpected end-of-list code %d" % code return retval class Database: """An object corresponding to a particular database in a server.""" def __init__(self, dictconn, dbname): """Initialize the object -- requires a Connection object and a database name.""" self.conn = dictconn self.name = dbname def getname(self): """Returns the short name for this database.""" return self.name def getdescription(self): if hasattr(self, 'description'): return self.description if self.getname() == '*': self.description = 'All Databases' elif self.getname() == '!': self.description = 'First matching database' else: self.description = self.conn.getdbdescs()[self.getname()] return self.description def getinfo(self): """Returns a string of info describing this database.""" if hasattr(self, 'info'): return self.info if self.getname() == '*': self.info = "This special database will search all databases on the system." elif self.getname() == '!': self.info = "This special database will return matches from the first matching database." else: self.conn.sendcommand("SHOW INFO " + self.name) self.info = "\n".join(self.conn.get100result()[1]) return self.info def define(self, word): """Get a definition from within this database. The argument, word, is the word to look up. The return value is the same as from Connection.define().""" return self.conn.define(self.getname(), word) def match(self, strategy, word): """Get a match from within this database. The argument, word, is the word to look up. The return value is the same as from Connection.define().""" return self.conn.match(self.getname(), strategy, word) class Definition: """An object corresponding to a single definition.""" def __init__(self, dictconn, db, word, defstr = None): """Instantiate the object. Requires: a Connection object, a Database object (NOT corresponding to '*' or '!' databases), a word. Optional: a definition string. If not supplied, it will be fetched if/when it is requested.""" self.conn = dictconn self.db = db self.word = word self.defstr = defstr def getdb(self): """Get the Database object corresponding to this definition.""" return self.db def getdefstr(self): """Get the definition string (the actual content) of this definition.""" if not self.defstr: self.defstr = self.conn.define(self.getdb().getname(), self.word)[0].getdefstr() return self.defstr def getword(self): """Get the word this object describes.""" return self.word opendict-0.6.8/lib/extra/dictdlib.py0000664000076400007640000003343413204646653017325 0ustar nerijusnerijus# Dictionary creation library # Copyright (C) 2002 John Goerzen # # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import sys, string, gzip, os b64_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" url_headword = "00-database-url" short_headword = "00-database-short" info_headword = "00-database-info" def b64_encode(val): """Takes as input an integer val and returns a string of it encoded with the base64 algorithm used by dict indexes.""" startfound = 0 retval = "" for i in range(5, -1, -1): thispart = (val >> (6 * i)) & ((2 ** 6) - 1) if (not startfound) and (not thispart): # Both zero -- keep going. continue startfound = 1 retval += b64_list[thispart] if len(retval): return retval else: return b64_list[0] def b64_decode(str): """Takes as input a string and returns an integer value of it decoded with the base64 algorithm used by dict indexes.""" if not len(str): return 0 retval = 0 shiftval = 0 for i in range(len(str) - 1, -1, -1): val = b64_list.index(str[i]) retval = retval | (val << shiftval) shiftval += 6 return retval validdict = {} for x in string.ascii_letters + string.digits + " \t": validdict[x] = 1 def sortnormalize(x): """Returns a value such that x is mapped to a format that sorts properly with standard comparison.""" x2 = '' for i in range(len(x)): if validdict.has_key(x[i]): x2 += x[i] return x2.upper() + "\0" + x.upper() def sortfunc(x, y): """Emulate sort -df.""" xl = x.split("\0") yl = y.split("\0") ret = cmp(xl[0], yl[0]) if ret != 0: return ret return cmp(xl[1], yl[1]) class DictDB: def __init__(self, basename, mode = 'read', quiet = 0): #, url = 'unknown', shortname = 'unknown', # longinfo = 'unknown', quiet = 0): """Initialize a DictDB object. Mode must be one of: read -- read-only access write -- write-only access, truncates existing files, does not work with .dz. dict created if nonexistant. update -- read/write access, dict created if nonexistant. Does not work with .dz. Read can read dict or dict.dz files. Write and update will NOT work with dict.dz files. If quiet is nonzero, status messages will be suppressed.""" self.mode = mode self.quiet = quiet self.indexentries = {} self.count = 0 self.basename = basename self.indexfilename = self.basename + ".index" if os.path.isfile(self.basename + ".dict.dz"): self.dictfilename = self.basename + ".dict.dz" self.usecompression = 1 else: self.dictfilename = self.basename + ".dict" self.usecompression = 0 if mode == 'read': self.indexfile = open(self.indexfilename, "rt") if self.usecompression: self.dictfile = gzip.GzipFile(self.dictfilename, "rb") else: self.dictfile = open(self.dictfilename, "rb") self._initindex() elif mode == 'write': self.indexfile = open(self.indexfilename, "wt") if self.usecompression: raise ValueError, "'write' mode incompatible with .dz files" else: self.dictfile = open(self.dictfilename, "wb") elif mode == 'update': try: self.indexfile = open(self.indexfilename, "r+b") except IOError: self.indexfile = open(self.indexfilename, "w+b") if self.usecompression: # Open it read-only since we don't support mods. self.dictfile = gzip.GzipFile(self.dictfilename, "rb") else: try: self.dictfile = open(self.dictfilename, "r+b") except IOError: self.dictfile = open(self.dictfilename, "w+b") self._initindex() else: raise ValueError, "mode must be 'read', 'write', or 'update'" #self.writeentry(url_headword + "\n " + url, [url_headword]) #self.writeentry(short_headword + "\n " + shortname, # [short_headword]) #self.writeentry(info_headword + "\n" + longinfo, [info_headword]) def _initindex(self): """Load the entire index off disk into memory.""" self.indexfile.seek(0) for line in self.indexfile.xreadlines(): splits = line.rstrip().split("\t") if not self.indexentries.has_key(splits[0]): self.indexentries[splits[0]] = [] self.indexentries[splits[0]].append([b64_decode(splits[1]), b64_decode(splits[2])]) def addindexentry(self, word, start, size): """Adds an entry to the index. word is the relevant word. start is the starting position in the dictionary and size is the size of the definition; both are integers.""" if not self.indexentries.has_key(word): self.indexentries[word] = [] self.indexentries[word].append([start, size]) def delindexentry(self, word, start = None, size = None): """Removes an entry from the index; word is the word to search for. start and size are optional. If they are specified, only index entries matching the specified values will be removed. For instance, if word is "foo" and start and size are not specified, all index entries for the word foo will be removed. If start and size are specified, only those entries matching all criteria will be removed. This function does not actually remove the data from the .dict file. Therefore, information removed by this function will still exist on-disk in the .dict file, but the dict server will just not "see" it -- there will be no way to get to it anymore. Returns a count of the deleted entries.""" if not self.indexentries.has_key(word): return 0 retval = 0 entrylist = self.indexentries[word] for i in range(len(entrylist) - 1, -1, -1): # Go backwords so the del doesn't effect the index. if (start == None or start == entrylist[i][0]) and \ (size == None or size == entrylist[i][1]): del(entrylist[i]) retval += 1 if len(entrylist) == 0: # If we emptied it, del it completely del(self.indexentries[word]) return retval def update(self, string): """Writes string out, if not quiet.""" if not self.quiet: sys.stdout.write(string) sys.stdout.flush() def seturl(self, url): """Sets the URL attribute of this database. If there was already a URL specified, we will use delindexentry() on it first.""" self.delindexentry(url_headword) self.addentry(url_headword + "\n " + url, [url_headword]) def setshortname(self, shortname): """Sets the shortname for this database. If there was already a shortname specified, we will use delindexentry() on it first.""" self.delindexentry(short_headword) self.addentry(short_headword + "\n " + shortname, [short_headword]) def setlonginfo(self, longinfo): """Sets the extended information for this database. If there was already long info specified, we will use delindexentry() on it first.""" self.delindexentry(info_headword) self.addentry(info_headword + "\n" + longinfo, [info_headword]) def addentry(self, defstr, headwords): """Writes an entry. defstr holds the content of the definition. headwords is a list specifying one or more words under which this definition should be indexed. This function always adds \\n to the end of defstr.""" self.dictfile.seek(0, 2) # Seek to end of file start = self.dictfile.tell() defstr += "\n" self.dictfile.write(defstr) for word in headwords: self.addindexentry(word, start, len(defstr)) self.count += 1 if self.count % 1000 == 0: self.update("Processed %d records\r" % self.count) def finish(self, dosort = 1): """Called to finish the writing process. **REQUIRED IF OPENED WITH 'update' OR 'write' MODES**. This will write the index and close the files. dosort is optional and defaults to true. If set to false, dictlib will not sort the index file. In this case, you MUST manually sort it through "sort -df" before it can be used.""" self.update("Processed %d records.\n" % self.count) if dosort: self.update("Sorting index: converting") indexlist = [] for word, defs in self.indexentries.items(): for thisdef in defs: indexlist.append("%s\t%s\t%s" % (word, b64_encode(thisdef[0]), b64_encode(thisdef[1]))) self.update(" mapping") sortmap = {} for entry in indexlist: norm = sortnormalize(entry) if sortmap.has_key(norm): sortmap[norm].append(entry) sortmap[norm].sort(sortfunc) else: sortmap[norm] = [entry] self.update(" listing") normalizedentries = sortmap.keys() self.update(" sorting") normalizedentries.sort() self.update(" re-mapping") indexlist = [] for normentry in normalizedentries: for entry in sortmap[normentry]: indexlist.append(entry) self.update(", done.\n") self.update("Writing index...\n") self.indexfile.seek(0) for entry in indexlist: self.indexfile.write(entry + "\n") if self.mode == 'update': # In case things were deleted self.indexfile.truncate() self.indexfile.close() self.dictfile.close() self.update("Complete.\n") def getdeflist(self): """Returns a list of strings naming all definitions contained in this dictionary.""" return self.indexentries.keys() def hasdef(self, word): return self.indexentries.has_key(word) def getdef(self, word): """Given a definition name, returns a list of strings with all matching definitions. This is an *exact* match, not a case-insensitive one. Returns [] if word is not in the dictionary.""" retval = [] if not self.hasdef(word): return retval for start, length in self.indexentries[word]: self.dictfile.seek(start) retval.append(self.dictfile.read(length)) return retval class DictReader: """This object provides compatibility with earlier versions of dictdlib. It is now deprecated.""" def __init__(self, basename): """Initialize a DictReader object. Provide it with the basename.""" self.dictdb = DictDB(basename, 'read') def getdeflist(self): """Returns a list of strings naming all definitions contained in this dictionary.""" return self.dictdb.getdeflist() def getdef(self, defname): """Given a definition name, returns a list of strings with all matching definitions.""" return self.dictdb.getdef(defname) class DictWriter: """This object provides compatibility with earlier versions of dictdlib. It is now deprecated.""" def __init__(self, basename, url = 'unknown', shortname = 'unknown', longinfo = 'unknown', quiet = 0): """Initialize a DictWriter object. Will create 'basename.dict' and 'basename.index' files. url, shortname, and longinfo specify the respective attributes of the database. If quiet is 1, status messages are not printed.""" self.dictdb = DictDB(basename, 'write', quiet) self.dictdb.seturl(url) self.dictdb.setshortname(shortname) self.dictdb.setlonginfo(longinfo) def writeentry(self, defstr, headwords): """Writes an entry. defstr holds the content of the definition. headwords is a list specifying one or more words under which this definition should be indexed. This function always adds \\n to the end of defstr.""" self.dictdb.addentry(defstr, headwords) def finish(self, dosort = 1): """Called to finish the writing process. **REQUIRED**. This will write the index and close the files. dosort is optional and defaults to true. If set to false, dictlib will not sort the index file. In this case, you MUST manually sort it through "sort -df" before it can be used.""" self.dictdb.finish(dosort) opendict-0.6.8/lib/extra/html2text.py0000664000076400007640000000776413204646653017511 0ustar nerijusnerijus""" html2text.py convert an html doc to text """ # system libraries import os, sys, string, time, getopt import re WIDTH = 80 def tag_replace (data,center,indent, use_ansi = 0): data = re.sub ("\s+", " ", data) data = re.sub ("(?s)", "", data) data = string.replace (data, "\n", " ") output = [] # modified 6/17/99 splits on all cases of "img" tags # imgs = re.split ("(?s)()", data) imgs = re.split ("(?si)()", data) for img in imgs: if string.lower(img[:4]) == "", "\n", data) data = re.sub ("(?i)]*>", "\n" + "-"*50 + "\n", data) data = re.sub ("(?i)
  • ", "\n* ", data) if use_ansi: data = re.sub ("(?i)", "\n", data) else: data = re.sub ("(?i)", "\n", data) if use_ansi: data = re.sub ("(?i)", "\n", data) else: data = re.sub ("(?i)", "\n", data) data = re.sub ("(?i)
      ", "\n
        \n", data) data = re.sub ("(?i)
      ", "\n
    \n", data) data = re.sub ("(?i)
    ", "\n
    \n", data) data = re.sub ("(?i)
    ", "\n
    \n", data) data = re.sub ("(?i)", "\n", data) if use_ansi: data = re.sub ("(?i)", "", data) data = re.sub ("(?i)", "", data) data = re.sub ("(?i)", "", data) data = re.sub ("(?i)", "", data) data = re.sub ("(?i)", "\n<CENTER>\n", data) data = re.sub ("(?i)", "\n\n", data) else: data = re.sub ("(?i)", "\n<CENTER>\n", data) data = re.sub ("(?i)", "\n\n", data) data = re.sub ("(?i)

    ", "\n", data) data = re.sub ("(?i)]*>", "\n", data) data = re.sub ("(?i)", "\n", data) data = re.sub ("(?i)]*>", "\t", data) data = re.sub ("(?i)]*>", "\t", data) data = re.sub (" *\n", "\n", data) lines = string.split (data, "\n") output = [] for line in lines: if line == "

      ": indent = indent + 1 elif line == "
    ": indent = indent - 1 if indent < 0: indent = 0 elif line == "
    ": center = center + 1 elif line == "
    ": center = center - 1 if center < 0: center = 0 else: if center: line = " "*indent + string.strip(line) nline = re.sub("\[.*?m", "", line) nline = re.sub ("<[^>]*>", "", nline) c = WIDTH/2 - (len (nline) / 2) output.append (" "*c + line) else: output.append (" "*indent + line) data = string.join (output, "\n") data = re.sub (" *\n", "\n", data) data = re.sub ("\n\n\n*", "\n\n", data) data = re.sub ("<[^>]*>", "", data) return (data, center, indent) def html2text (data, use_ansi = 0, is_latin1 = 0): pre = re.split("(?s)(
    [^<]*
    )", data) out = [] indent = 0 center = 0 for part in pre: if part[:5] != "
    ":
          (res, center, indent) = tag_replace (part,center,indent, use_ansi)
          out.append (res)
        else:
          part = re.sub("(?i)", "", part)
          out.append (part)
      data = string.join (out)
      data = re.sub (">", ">", data)
      data = re.sub ("<", "<", data)
      data = re.sub (" ", " ", data)
     
      return data
    
    
    def usage(progname):
      print "usage: %s --help " % progname
      print __doc__
    
    def main(argc, argv):
      progname = argv[0]
      alist, args = getopt.getopt(argv[1:], "", ["help"])
    
      for (field, val) in alist:
        if field == "--help":
          usage(progname)
          return
    
      if len(args):
        file = args[0]
      else:
        return
    
      progname = argv[0]
    
      fp = open (file)
      data = fp.read()
      fp.close()
    
      if data:
        print (html2text(data))
      else:
        print "Document contained no data"
    
    if __name__ == "__main__":
      main(len(sys.argv), sys.argv)
    
    
    opendict-0.6.8/lib/gui/0000775000076400007640000000000013204646653014627 5ustar  nerijusnerijusopendict-0.6.8/lib/gui/__init__.py0000664000076400007640000000000013204646653016726 0ustar  nerijusnerijusopendict-0.6.8/lib/gui/dictaddwin.py0000664000076400007640000000637513204646653017326 0ustar  nerijusnerijus# -*- coding: utf-8 -*-
    
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    # Module: gui.dictaddwin
    
    import wx
    
    from lib import misc
    
    _ = wx.GetTranslation
    
    # IDs range: 6300-6310
    class DictAddWindow(wx.Dialog):
    
        def __init__(self, parent, fname, filePath):
            wx.Dialog.__init__(self, parent, -1, 
                             _("Add new dictionary"), wx.DefaultPosition, 
                             wx.DefaultSize, wx.DEFAULT_DIALOG_STYLE)
            
            self.filePath = filePath
            vboxMain = wx.BoxSizer(wx.VERTICAL)
            
            msg1 = _("The file format of \"%s\" could not be \nrecognized by its" \
                     " extention. Please select one\nfrom the list:") % fname
            label1 = wx.StaticText(self, -1, msg1)
            vboxMain.Add(label1, 0, wx.ALL | wx.EXPAND, 5)
            
            choices = [misc.dictFormats["zip"], # OpenDict plugin
                       _("\"%s\" dictionary format") % misc.dictFormats["dwa"],
                       _("\"%s\" dictionary format") % misc.dictFormats["mova"],
                       _("\"%s\" dictionary format") % misc.dictFormats["tmx"],
                       _("\"%s\" dictionary format") % misc.dictFormats["dz"]]
            
            self.box = wx.ListBox(self, -1, wx.Point(-1, -1),
                            wx.Size(-1, -1), choices, wx.LB_SINGLE)
            
            vboxMain.Add(self.box, 1, wx.ALL | wx.EXPAND, 3)
            
            hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
            
            buttonOK = wx.Button(self, wx.ID_OK, _("OK"))
            hboxButtons.Add(buttonOK, 0, wx.ALL, 1)
            
            buttonCancel = wx.Button(self, 6302, _("Cancel"))
            hboxButtons.Add(buttonCancel, 0, wx.ALL, 1)
            
            vboxMain.Add(hboxButtons, 0, wx.ALL | wx.CENTER, 2)
            
            self.SetSizer(vboxMain)
            self.Fit()
            
            wx.EVT_BUTTON(self, wx.ID_OK, self.onOK)
            wx.EVT_BUTTON(self, 6302, self.onCancel)
        
        def onOK(self, event):
            parent = self.GetParent()
            i = self.box.GetSelection()
            ext = ""
            
            if i == 0:
                ext = "zip"
            elif i == 1:
                ext = "dwa"
            elif i == 2:
                ext = "mova"
            elif i == 3:
                ext = "tmx"
            elif i == 4:
                ext == "dz"
            
            from installer import Installer
            installer = Installer(parent, parent.app.config)
            installer.install(self.filePath, ext)
            
            self.Destroy()
        
        def onCancel(self, event):
            self.GetParent().dictType = None
            self.Destroy()
    opendict-0.6.8/lib/gui/dictconnwin.py0000664000076400007640000002506613204646653017531 0ustar  nerijusnerijus#
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    
    import wx
    from wx.lib.rcsizer import RowColSizer
    import traceback
    
    from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
    from lib.parser import DictConnection
    from lib.extra import dictclient
    from lib.threads import Process
    from lib.gui import errorwin
    from lib import misc
    
    _ = wx.GetTranslation
    
    CONNECTION_CHECK_INTERVAL = 400
    
    
    class DictConnWindow(wx.Frame):
    
       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.parent = parent
          self.app = wx.GetApp()
    
          vboxMain = wx.BoxSizer(wx.VERTICAL)
    
          hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
          hboxServer = RowColSizer()
    
          #
          # Server address row
          #
          hboxServer.Add(wx.StaticText(self, -1, _("Server: ")),
                         flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         row=0, col=0, border=1)
    
          servers = ['dict.org', 'localhost']
          self.entryServer = wx.ComboBox(self, -1,
              self.app.config.get('dictServer'), wx.Point(-1, -1),
                                  wx.Size(-1, -1), servers, wx.CB_DROPDOWN)
          hboxServer.Add(self.entryServer, flag=wx.EXPAND, row=0, col=1, border=1)
          hboxServer.Add(wx.Button(self, 1000, _("Default Server")),
                         flag=wx.EXPAND, row=0, col=2, border=5)
    
          #
          # Port entry row
          #
          hboxServer.Add(wx.StaticText(self, -1, _("Port: ")),
                         flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         row=1, col=0, border=1)
          hboxServer.Add(wx.Button(self, 1001, _("Default Port")),
                         flag=wx.EXPAND, row=1, col=2, border=5)
    
          self.entryPort = wx.TextCtrl(self, -1,
                                      self.app.config.get('dictServerPort'))
          hboxServer.Add(self.entryPort, flag=wx.EXPAND, row=1, col=1, border=1)
    
          #
          # Database selection row
          #
          hboxServer.Add(wx.StaticText(self, -1, _("Database: ")),
                         flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         row=2, col=0, border=1)
    
          self.msgSearchInAll = _("Search in all databases")
          self.choiceDB = wx.ComboBox(self, 1002, self.msgSearchInAll,
                                     choices=[self.msgSearchInAll],
                                     style=wx.TE_READONLY)
          self.choiceDB.SetInsertionPoint(0)
          hboxServer.Add(self.choiceDB, flag=wx.EXPAND, row=2, col=1, border=1)
    
          hboxServer.Add(wx.Button(self, 1003, _("Fetch List")), #size=(-1, 18)),
                         flag=wx.EXPAND, row=2, col=2, border=1)
    
          #
          # Encoding selection row
          #
          hboxServer.Add(wx.StaticText(self, -1, _("Character encoding: ")),
                         flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         row=3, col=0, border=1)
    
          self.entryEncoding = wx.ComboBox(self, 1006,
                                  misc.encodings.keys()[
                                    misc.encodings.values().index(
                                        self.app.config.get('dict-server-encoding'))],
                                  wx.Point(-1, -1),
                                  wx.Size(-1, -1), misc.encodings.keys(), 
                                  wx.CB_DROPDOWN | wx.CB_READONLY)
    
          hboxServer.Add(self.entryEncoding, flag=wx.EXPAND, row=3, col=1, border=1)
    
          #hboxServer.Add(wx.StaticText(self, -1, _("Strategy: ")),
          #               flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
          #               row=3, col=0, rowspan=1, border=1)
          #
          #self.choiceStrat = wx.ComboBox(self, 1006, #size=(-1, 20),
          #                         choices=[])
          #hboxServer.Add(self.choiceStrat, flag=wx.EXPAND, row=3, col=1,
          #               rowspan=1, border=1)
          #
          #hboxServer.Add(wx.Button(self, 1007, _("Update")), #size=(-1, 18)),
          #               flag=wx.EXPAND, row=3, col=2, border=5)
    
          hboxServer.AddGrowableCol(1)
    
          vboxMain.Add(hboxServer, 1, wx.ALL | wx.EXPAND, 4)
    
          self.buttonOK = wx.Button(self, 1004, _("Connect"))
          hboxButtons.Add(self.buttonOK, 0, wx.ALL, 1)
    
          self.buttonCancel = wx.Button(self, 1005, _("Cancel"))
          hboxButtons.Add(self.buttonCancel, 0, wx.ALL, 1)
    
          vboxMain.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_CENTER, 2)
    
          self.CreateStatusBar()
    
          self.SetSizer(vboxMain)
          self.Fit()
          self.SetSize((500, -1))
    
          self.timerUpdateDB = wx.Timer(self, 1006)
          self.timerConnect = wx.Timer(self, 1007)
    
          self.update = None
          self.connection = None
    
          wx.EVT_BUTTON(self, 1000, self.onDefaultServer)
          wx.EVT_BUTTON(self, 1001, self.onDefaultPort)
          wx.EVT_BUTTON(self, 1003, self.onUpdateDB)
          wx.EVT_BUTTON(self, 1007, self.onUpdateStrats)
          wx.EVT_BUTTON(self, 1004, self.onOK)
          wx.EVT_BUTTON(self, 1005, self.onCancel)
          wx.EVT_TIMER(self, 1006, self.onTimerUpdateDB)
          wx.EVT_TIMER(self, 1007, self.onTimerConnect)
    
    
       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 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 onTimerConnect(self, event):
          
          if self.connection != None:
             if self.connection.isDone():
                systemLog(INFO, "Connection timer stopped")
                self.timerConnect.Stop()
                self.conn = self.connection()
                
                if self.conn == None:
                    self.SetStatusText('')
                    title = _("Connection Error")
                    msg = _("Unable to connect to server")
                    errorwin.showErrorMessage(title, msg)
                else:
                    self.prepareForUsing()
                
    
       def onDefaultServer(self, event):
          
          self.entryServer.SetValue("dict.org")
    
    
       def onDefaultPort(self, event):
          
          self.entryPort.SetValue("2628")
    
    
       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()))
    
       # not used, remove
       def onUpdateStrats(self, event):
          conn = dictclient.Connection()
          strats = conn.getstratdescs()
    
          for name in strats.values():
             self.choiceStrat.Append(name)
    
    
       # Thread is not used there, because program don't hang if can't
       # connect. Otherwise, it may hang for a second depending on the
       # connection speed. TODO: better solution?
       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 prepareForUsing(self):
          """Prepare MainWindow for displaying data"""
           
          systemLog(INFO, "DictConnection: Connected, preparing main window...")
    
          db = self.choiceDB.GetValue()
          if self.choiceDB.FindString(db) == 0:
             db = "*"
             db_name = ""
          else:
             try:
                dbs = self.conn.getdbdescs()
                for d in dbs.keys():
                   if dbs[d] == db:
                      db = d
                db_name = dbs[db]
             except:
                traceback.print_exc()
                self.app.window.SetStatusText(misc.errors[4])
                return
    
          self.app.window.onCloseDict(None)
          self.app.window.activeDictionary = DictConnection(self.server,
                                                            int(self.port), 
                                                db, "")
                                                
          self.app.config.set('dict-server-encoding', self.encoding[0])
          self.parent.changeEncoding(self.encoding[1])
    
          if db_name != "":
             title = "OpenDict - %s (%s)" % (self.server, db_name)
          else:
             title = "OpenDict - %s" % self.server
          self.app.window.SetTitle(title)
    
          self.app.window.checkEncMenuItem(self.encoding[0])
    
          if not self.app.window.activeDictionary.getUsesWordList():
              self.app.window.hideWordList()
    
          self.app.window.SetStatusText("")
          self.timerUpdateDB.Stop()
          self.Destroy()
    
    
       def onCancel(self, event):
          self.timerUpdateDB.Stop()
          self.timerConnect.Stop()
          self.Destroy()
    
    
    opendict-0.6.8/lib/gui/dicteditorwin.py0000664000076400007640000005113213204646653020053 0ustar  nerijusnerijus#
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    
    # TODO: not usable yet, needs some work with encodings, gui, etc.
    
    from wx.lib.rcsizer import RowColSizer
    import wx
    import os
    import codecs
    import traceback
    
    from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
    from lib.misc import encodings, printError
    from lib.parser import TMXParser
    from lib.gui import errorwin
    from lib import info
    from lib import dicteditor
    from lib import enc
    
    _ = wx.GetTranslation
    
    
    class EditWordWindow(wx.Frame):
        """Word editor window"""
    
        def __init__(self, word, parent, id, title, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
            wx.Frame.__init__(self, parent, id, title, pos, size, style)
    
            vboxMain = wx.BoxSizer(wx.VERTICAL)
            hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
            self.boxInfo = RowColSizer()
    
    
            self.boxInfo.Add(wx.StaticText(self, -1, _("Word: "), pos=(-1, -1)),
                             flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                             row=0, col=0, border=1)
    
            self.entryWord = wx.TextCtrl(self, -1, word)
            self.entryWord.Disable()
            self.boxInfo.Add(self.entryWord, flag=wx.EXPAND,
                             row=0, col=1, border=1)
    
    
            self.transLabels = {}
            self.textEntries = {}
    
            unit = parent.editor.getUnit(word)
    
            if unit:
                translations = unit.getTranslations()
                for trans in translations:
                    comment = translations[trans]
                    if comment:
                        transcomm = u"%s // %s" % (trans, comment)
                    else:
                        transcomm = trans
                        
                    transcomm = enc.toWX(transcomm)
                    
                    self.onAddEmptyField(None)
                    entry = self.textEntries.get(max(self.textEntries.keys()))
                    if entry:
                        entry.SetValue(transcomm)
    
            self.boxInfo.AddGrowableCol(1)
            vboxMain.Add(self.boxInfo, 1, wx.ALL | wx.EXPAND, 2)
    
            idAdd = wx.NewId()
            self.buttonAdd = wx.Button(self, idAdd, _("Add translation field"))
            vboxMain.Add(self.buttonAdd, 0, wx.ALL | wx.ALIGN_RIGHT, 2)
    
            self.buttonOK = wx.Button(self, 6050, _("OK"))
            hboxButtons.Add(self.buttonOK, 0, wx.ALL, 1)
    
            self.buttonCancel = wx.Button(self, 6051, _("Cancel"))
            hboxButtons.Add(self.buttonCancel, 0, wx.ALL, 1)
    
            vboxMain.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 2)
    
            self.SetSizer(vboxMain)
            self.Fit()
            self.SetSize((500, -1))
    
            self.Bind(wx.EVT_BUTTON, self.onAddEmptyField, self.buttonAdd)
            self.Bind(wx.EVT_BUTTON, self.onSave, self.buttonOK)
            self.Bind(wx.EVT_BUTTON, self.onClose, self.buttonCancel)
    
    
        def onAddEmptyField(self, event):
            """Add empty translation field"""
    
            transLabel = wx.StaticText(self, -1, _("Translation #%d: ") \
                                                  % (len(self.textEntries)+1))
            self.transLabels[len(self.transLabels)] = transLabel
            self.boxInfo.Add(transLabel,
                             flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTRE_VERTICAL,
                             row=len(self.transLabels), col=0, border=1)
    
            text = wx.TextCtrl(self, -1,
                              "",
                              size=(100, -1))
    
            self.textEntries[len(self.textEntries)] = text
    
            self.boxInfo.Add(text, flag=wx.EXPAND,
                             row=len(self.textEntries),
                             col=1, border=1)
    
            self.Fit()
            self.SetSize((500, -1))
    
    
        def onSave(self, event):
            """Apply changes"""
    
            parent = self.GetParent()
            word = enc.fromWX(self.entryWord.GetValue())
    
            translations = []
    
            for label in self.textEntries.values():
                translations.append(enc.fromWX(label.GetValue()))
    
            transcomm = {}
    
            for translation in translations:
                if not len(translation.strip()):
                    continue
                chunks = translation.split('//', 1)
                if len(chunks) == 2:
                    t = chunks[0]
                    c = chunks[1]
                else:
                    t = chunks[0]
                    c = None
    
                transcomm[t] = c
    
            parent.editor.getUnit(word).setTranslations(transcomm)
            parent.setChanged(True)
            parent.checkAllButtons()
    
            self.Destroy()
    
    
        def onClose(self, event):
            """Close window withous saveing changes"""
    
            self.Destroy()
    
    
    
    # IDs range: 6000-6200
    class DictEditorWindow(wx.Frame):
    
        """Built-in dictionary editor. This tool lets user create and
        manage his own dictionaries in TMX format."""
    
        class AddWordWindow(EditWordWindow):
            """Window for adding new word"""
    
            def __init__(self, parent, id, title, pos=wx.DefaultPosition,
                     size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
    
                EditWordWindow.__init__(self, '', parent, id, title, pos,
                                        size, style)
                
                self.entryWord.Enable(1)
                self.onAddEmptyField(None)
    
    
            def onSave(self, event):
                """Apply changes"""
    
                parent = self.GetParent()
                word = enc.fromWX(self.entryWord.GetValue())
    
                translations = []
    
                for label in self.textEntries.values():
                    translations.append(enc.fromWX(label.GetValue()))
    
                transcomm = {}
    
                for translation in translations:
                    if not len(translation.strip()):
                        continue
                    chunks = translation.split('//', 1)
                    if len(chunks) == 2:
                        t = chunks[0]
                        c = chunks[1]
                    else:
                        t = chunks[0]
                        c = None
    
                    transcomm[t] = c
    
                unit = dicteditor.Translation()
                unit.setWord(word)
                unit.setTranslations(transcomm)
                parent.editor.addUnit(unit)
                parent.list.Append(enc.toWX(word))
                
                parent.setChanged(True)
                parent.checkAllButtons()
    
                self.Destroy()
    
    
    
        # IDs range: 6000-6003
        class ConfirmExitWindow(wx.Dialog):
            """Save confirmation dialog"""
    
            def __init__(self, parent, id, title, pos=wx.DefaultPosition,
                     size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
                
                wx.Dialog.__init__(self, parent, id, title, pos, size, style)
    
                self.parent = self.GetParent()
                
                vboxMain = wx.BoxSizer(wx.VERTICAL)
                hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
                
                labelMsg = wx.StaticText(self, -1,
                                        _("Dictionary \"%s\" has been changed") \
                                        % parent.name)
                vboxMain.Add(labelMsg, 1, wx.ALL | wx.EXPAND, 15)
                
                buttonSave = wx.Button(self, 6000, _("Save"))
                hboxButtons.Add(buttonSave, 0, wx.ALL | wx.EXPAND, 3)
                
                buttonExit = wx.Button(self, 6001, _("Do not save"))
                hboxButtons.Add(buttonExit, 0, wx.ALL | wx.EXPAND, 3)
                
                buttonCancel = wx.Button(self, 6002, _("Cancel"))
                hboxButtons.Add(buttonCancel, 0, wx.ALL | wx.EXPAND, 3)
                
                vboxMain.Add(hboxButtons, 0, wx.ALL | wx.EXPAND, 2)
                
                self.SetSizer(vboxMain)
                self.Fit()
                
                wx.EVT_BUTTON(self, 6000, self.onSave)
                wx.EVT_BUTTON(self, 6001, self.onExitParent)
                wx.EVT_BUTTON(self, 6002, self.onClose)
    
                
            def onSave(self, event):
                
                if self.parent.cAction == "save":
                    self.parent.onSave(None)
                    self.parent.Destroy()
                elif self.parent.cAction == "open":
                    self.parent.onSave(None)
                    self.Hide()
                    self.parent.open()
                elif self.parent.cAction == "close":
                    self.parent.onSave(None)
                    self.parent.Destroy()
                    
                
            def onExitParent(self, event):
                
                if self.parent.cAction == "save" or self.parent.cAction == "close":
                    self.parent.Destroy()
                elif self.parent.cAction == "open":
                    self.Hide()
                    self.parent.open()
                    self.Destroy()
    
                
            def onClose(self, event):
                
                self.Destroy()
    
    
        # -------------------------------------------------------------
        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.CreateStatusBar()
            
            self.priTitle = _("Dictionary editor")
            self.savedOnce = False
            self.changed = False
            self.editor = dicteditor.Editor()
            self.cAction = None
    
            vboxMain = wx.BoxSizer(wx.VERTICAL)
            vboxDict = wx.BoxSizer(wx.VERTICAL)
            vboxList = wx.BoxSizer(wx.VERTICAL)
            hboxDict = wx.BoxSizer(wx.HORIZONTAL)
            vboxEditButtons = wx.BoxSizer(wx.VERTICAL)
            hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
    
            # Control buttons
            self.controlButtons = []
            
            self.buttonAdd = wx.Button(self, 6000, _("Add"))
            self.buttonAdd.SetToolTipString(_("Add word"))
            self.controlButtons.append(self.buttonAdd)
            
            self.buttonEdit = wx.Button(self, 6001, _("Edit"))
            self.buttonEdit.SetToolTipString(_("Change translation"))
            self.controlButtons.append(self.buttonEdit)
    
            self.buttonRemove = wx.Button(self, 6002, _("Remove"))
            self.buttonRemove.SetToolTipString(_("Remove selected word"))
            self.controlButtons.append(self.buttonRemove)
    
            self.buttonSort = wx.Button(self, 6004, _("Sort"))
            self.buttonSort.SetToolTipString(_("Sort word list"))
            self.controlButtons.append(self.buttonSort)
    
            self.buttonSave = wx.Button(self, 6005, _("Save"))
            self.buttonSave.SetToolTipString(_("Save words to file"))
            self.controlButtons.append(self.buttonSave)
    
            self.buttonSaveAs = wx.Button(self, 6006, _("Save As..."))
            self.buttonSaveAs.SetToolTipString(_("Save with a different file name"))
            self.controlButtons.append(self.buttonSaveAs)
            
            for button in self.controlButtons:
                button.Disable()
                vboxEditButtons.Add(button, 0, wx.ALL | wx.EXPAND, 1)
            
            panelList = wx.Panel(self, -1)
            sbSizerList = wx.StaticBoxSizer(wx.StaticBox(panelList, -1, 
                                                     _("Word List")),
                                           wx.VERTICAL)
            
            self.list = wx.ListBox(panelList, 6020,
                                  wx.Point(-1, -1),
                                  wx.Size(-1, -1),
                                  [],
                                  wx.LB_SINGLE | wx.SUNKEN_BORDER)
                                  
            sbSizerList.Add(self.list, 1, wx.ALL | wx.EXPAND, 0)
            panelList.SetSizer(sbSizerList)
            panelList.SetAutoLayout(True)
            sbSizerList.Fit(panelList)
    
            hboxDict.Add(panelList, 1, wx.ALL | wx.EXPAND, 0)
            hboxDict.Add(vboxEditButtons, 0, wx.ALL | wx.EXPAND, 5)
            vboxDict.Add(hboxDict, 1, wx.ALL | wx.EXPAND, 0)
            vboxMain.Add(vboxDict, 1, wx.ALL | wx.EXPAND, 10)
    
            self.buttonNew = wx.Button(self, 6030, _("New..."))
            self.buttonNew.SetToolTipString(_("Start new dictionary"))
            hboxButtons.Add(self.buttonNew, 0, wx.ALL | wx.EXPAND, 1)
    
            self.buttonOpen = wx.Button(self, 6031, _("Open..."))
            self.buttonOpen.SetToolTipString(_("Open dictionary file"))
            hboxButtons.Add(self.buttonOpen, 0, wx.ALL | wx.EXPAND, 1)
    
            self.buttonClose = wx.Button(self, 6032, _("Close"))
            self.buttonClose.SetToolTipString(_("Close editor window"))
            hboxButtons.Add(self.buttonClose, 0, wx.ALL | wx.EXPAND, 1)
    
            vboxMain.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 2)
    
            self.SetIcon(wx.Icon(os.path.join(info.GLOBAL_HOME,
                                            "pixmaps",
                                            "icon-24x24.png"),
                                wx.BITMAP_TYPE_PNG))
    
            self.SetSizer(vboxMain)
    
            self.Bind(wx.EVT_LISTBOX, self.onWordSelected, self.list)
            self.Bind(wx.EVT_BUTTON, self.onCreate, self.buttonNew)
    
            wx.EVT_BUTTON(self, 6000, self.onAddWord)
            wx.EVT_BUTTON(self, 6001, self.onEdit)
            wx.EVT_BUTTON(self, 6002, self.onRemove)
            wx.EVT_BUTTON(self, 6003, self.onSearch)
            wx.EVT_BUTTON(self, 6004, self.onSort)
            wx.EVT_BUTTON(self, 6005, self.onSave)
            wx.EVT_BUTTON(self, 6006, self.onSaveAs)
            wx.EVT_BUTTON(self, 6031, self.onOpen)
            wx.EVT_BUTTON(self, 6032, self.onClose)
            wx.EVT_CLOSE(self, self.onClose)
    
    
        def onAddWord(self, event):
            
            self.SetStatusText("")
            
            window = self.AddWordWindow(self, -1, _("New Word"),
                                        size=(-1, -1), pos=(-1, -1),
                                        style=wx.DEFAULT_FRAME_STYLE)
            window.CentreOnScreen()
            window.Show(True)
    
    
        def onEdit(self, event):
            
            self.SetStatusText("")
            
            word = self.list.GetStringSelection()
            if word == "":
                return
    
            window = EditWordWindow(word, self, -1, _("Edit Word"),
                                    size=(-1, -1),
                                    style=wx.DEFAULT_FRAME_STYLE)
            window.CentreOnScreen()
            window.Show(True)
    
            self.checkAllButtons()
    
    
        def onRemove(self, event):
            
            self.SetStatusText("")
            word = self.list.GetStringSelection()
            if word != "":
                self.list.Delete(self.list.FindString(word))
            self.editor.removeUnit(self.editor.getUnit(word))
            self.setChanged(True)
            self.checkAllButtons()
    
    
        def onSearch(self, event):
            
            self.SetStatusText("")
    
    
        def onSort(self, event):
            
            words = []
            for unit in self.editor.getUnits():
                words.append(unit.getWord())
            
            if len(words) == 0:
                self.SetStatusText(_("List is empty"))
                return
            
            words.sort()
            self.list.Clear()
            self.list.InsertItems(words, 0)
            self.SetStatusText(_("List sorted"))
    
            self.setChanged(True)
            self.checkAllButtons()
    
    
        def onSaveAs(self, event):
    
            self.onSave(None)
    
    
        def onSave(self, event):
    
            self.SetStatusText("")
            self.cAction = "save"
    
            wildCard = "Slowo dictionaries (*.dwa)|*.dwa"
            default = 'Untitled-dictionary.dwa'
    
            if not self.savedOnce or not event:
                dialog = wx.FileDialog(self,
                                       wildcard=wildCard,
                                       defaultFile=default,
                                       message=_("Save file"),
                                       style=wx.FD_SAVE | wx.FD_CHANGE_DIR)
                if dialog.ShowModal() == wx.ID_OK:
                    self.filePath = dialog.GetPaths()[0]
                else:
                    return
    
            if os.path.isdir(self.filePath):
                if self.filePath.endswith('..'):
                    self.filePath = self.filePath[:-2]
    
                self.filePath += default
    
            if not self.filePath.endswith('.dwa'):
                self.filePath += '.dwa'
    
            self.editor.save(self.filePath)
            self.setChanged(False)
            self.name = os.path.basename(self.filePath)
            self.savedOnce = True
            self.checkAllButtons()
            self.SetStatusText(_("Dictionary saved"))
            self.SetTitle("%s - %s" % (self.priTitle, self.name))
    
    
        def onCreate(self, event):
    
            self.editor = dicteditor.Editor()
            self.list.Clear()
            self.checkAllButtons()
            self.savedOnce = False
            self.name = _("Untitled")
            self.SetStatusText("")
            self.SetTitle("%s - %s" % (self.priTitle, self.name))
    
    
        def checkAddButton(self):
            """Check for add button visibility"""
    
            if not hasattr(self, 'editor'):
                self.buttonAdd.Disable()
            else:
                self.buttonAdd.Enable(1)
    
    
        def checkEditButton(self):
            """Check for edit button visibility"""
    
            if self.list.GetSelection() == -1:
                self.buttonEdit.Disable()
            else:
                self.buttonEdit.Enable(1)
    
    
        def checkRemoveButton(self):
            """Check for remove button visibility"""
    
            if self.list.GetSelection() == -1:
                self.buttonRemove.Disable()
            else:
                self.buttonRemove.Enable(1)
    
    
        def checkSortButton(self):
            """Check for sort button visibility"""
    
            if not hasattr(self, 'editor'):
                self.buttonSort.Disable()
            elif len(self.editor.getUnits()) < 2:
                self.buttonSort.Disable()
            else:
                self.buttonSort.Enable(1)
    
    
        def checkSaveButton(self):
            """Check for save button visibility"""
    
            if not hasattr(self, 'editor'):
                self.buttonSave.Disable()
            elif not self.changed:
                self.buttonSave.Disable()
            else:
                self.buttonSave.Enable(1)
    
    
        def checkAllButtons(self):
            """Check all buttons for visibility changes"""
    
            self.checkAddButton()
            self.checkEditButton()
            self.checkRemoveButton()
            self.checkSortButton()
            self.checkSaveButton()
    
            self.buttonSaveAs.Enable(True)
            
    
        def onOpen(self, event):
            
            if self.editor and self.changed:
                    window = self.ConfirmExitWindow(self,
                                                    -1,
                                                    _("Exit confirmation"))
                    self.cAction = "open"
                    window.CentreOnScreen()
                    window.Show(True)
            else:
                self.open()
                self.savedOnce = True # no need to specify file name
    
            
        def open(self):
            wildCard = "Slowo dictionaries (*.dwa)|*.dwa"
            
            dialog = wx.FileDialog(self, message=_("Choose dictionary file"),
                                  wildcard=wildCard, style=wx.FD_OPEN|wx.FD_MULTIPLE)
            if dialog.ShowModal() == wx.ID_OK:
                name = os.path.split(dialog.GetPaths()[0])[1]
                self.filePath = dialog.GetPaths()[0]
                self.name = os.path.split(self.filePath)[1]
    
                wx.BeginBusyCursor()
                
                try:
                    self.editor.load(self.filePath)
                except Exception, e:
                    wx.EndBusyCursor()
                    traceback.print_exc()
                    title = _("Open Failed")
                    msg = _("Unable to open dictionary (got message: %s)") % e
                    errorwin.showErrorMessage(title, msg)
                    
                    return
                
                self.SetTitle("%s - %s" % (self.priTitle, self.name))
                
                self.list.Clear()
                words = []
                for unit in self.editor.getUnits():
                    words.append(enc.toWX(unit.getWord()))
                words.sort()
    
                self.list.InsertItems(words, 0)
                self.checkAllButtons()
                self.SetStatusText(_("Dictionary loaded"))
    
                wx.EndBusyCursor()
    
    
        def onWordSelected(self, event):
            """This method is invoked when list item is selected"""
    
            self.checkAllButtons()
    
                
        def onClose(self, event):
            
            if self.changed:
                self.cAction = "close"
                window = self.ConfirmExitWindow(self, -1, _("Exit confirmation"))
                window.CentreOnScreen()
                window.Show(True)
            else:
                self.Destroy()
    
    
        def setChanged(self, value):
            """Set changed=value"""
            
            self.changed = value
    
    
        def getChanged(self):
            """Get if changed"""
    
            return self.changed
    opendict-0.6.8/lib/gui/errorwin.py0000664000076400007640000000507313204646653017055 0ustar  nerijusnerijus#
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    # Module: gui.errorwin
    
    import wx
    import sys
    import os
    import traceback
    
    _ = wx.GetTranslation
    
    
    from lib import info
    
    
    def showErrorMessage(title, msg):
       """Show error message dialog"""
       
       window = wx.MessageDialog(None,
                                msg, 
                                title, 
                                wx.OK | wx.ICON_ERROR)
       window.CenterOnScreen()
       window.ShowModal()
       window.Destroy()
    
    
    def showInfoMessage(title, msg):
       """Show info message dialog"""
       
       window = wx.MessageDialog(None,
                                msg, 
                                title, 
                                wx.OK | wx.ICON_INFORMATION)
       window.CenterOnScreen()
       window.ShowModal()
       window.Destroy()
       
       
    
    class ErrorWindow(wx.Frame):
    
       """This window is shown when OpenDict can't start because
          of some error."""
    
       def __init__(self, parent, id, title, error, pos=wx.DefaultPosition,
                    size=wx.DefaultSize, style=wx.CENTRE):
          wx.Frame.__init__(self, parent, id, title, pos, size, style)
    
          raise DeprecationWarning
    
          vbox = wx.BoxSizer(wx.VERTICAL)
    
          vbox.Add(wx.StaticText(self, -1, _("An error occured:")), 0,
                   wx.ALL | wx.EXPAND, 5)
    
          errMsg = wx.TextCtrl(self, -1, size=(-1, 200),
                           style=wx.TE_MULTILINE | wx.TE_READONLY)
          errMsg.WriteText(error)
          vbox.Add(errMsg, 1,
                   wx.ALL | wx.EXPAND, 10)
    
          vbox.Add(wx.StaticText(self, -1, msg), 0,
                   wx.ALL | wx.EXPAND, 5)
    
          self.buttonClose = wx.Button(self, 200, _("Close"))
          vbox.Add(self.buttonClose, 0, wx.ALL | wx.CENTRE, 2)
    
    
          self.SetSizer(vbox)
          self.Fit()
    
          wx.EVT_CLOSE(self, self.onCloseWindow)
          wx.EVT_BUTTON(self, 200, self.onExit)
    opendict-0.6.8/lib/gui/helpwin.py0000664000076400007640000002032613204646653016652 0ustar  nerijusnerijus# -*- coding: UTF-8 -*-
    
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    # Module: gui.helpwin
    
    #from wx import *
    #from wx.html import *
    import wx
    import os
    import sys
    
    from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
    from lib import enc
    from lib import info
    
    _ = wx.GetTranslation
    
    
    class LicenseWindow(wx.Frame):
       """Licence window class"""
    
       def __init__(self, parent, id, title, pos=wx.DefaultPosition,
                    size=wx.DefaultSize, style=wx.CENTRE):
          wx.Frame.__init__(self, parent, id, title, pos, size, style)
    
          vbox = wx.BoxSizer(wx.VERTICAL)
    
          #
          # Read licence file
          #
          try:
             fd = open(os.path.join(info.GLOBAL_HOME, 'copying.html'))
             data = fd.read()
             fd.close()
          except Exception, e:
             systemLog(ERROR, "Unable to read licence file: %s" % e)
             data = "Error: licence file not found"
    
          scWinAbout = wx.ScrolledWindow(self, -1, wx.DefaultPosition,
                                        wx.Size(-1, -1))
    
          htmlWin = wx.html.HtmlWindow(scWinAbout, -1, style=wx.SUNKEN_BORDER)
          htmlWin.SetFonts('Helvetica', 'Fixed', [10]*5)
          htmlWin.SetPage(data)
          
          scBox = wx.BoxSizer(wx.VERTICAL)
          scBox.Add(htmlWin, 1, wx.ALL | wx.EXPAND, 1)
          scWinAbout.SetSizer(scBox)
          vbox.Add(scWinAbout, 1, wx.ALL | wx.EXPAND, 5)
    
          self.buttonClose = wx.Button(self, 2002, _("&Close"))
          vbox.Add(self.buttonClose, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
    
          self.SetSizer(vbox)
    
          wx.EVT_BUTTON(self, 2002, self.onClose)
    
    
       def onClose(self, event):
          """This method is invoked when Close button is clicked"""
          
          self.Destroy()
          
    
    class CreditsWindow(wx.Dialog):
       """Credits window class"""
       
       def __init__(self, parent, id, title, pos=wx.DefaultPosition,
                    size=wx.DefaultSize):
          wx.Dialog.__init__(self, parent, id, title, pos, size)
          
          vbox = wx.BoxSizer(wx.VERTICAL)
          
          nb = wx.Notebook(self, -1)
          
          # "Written by" panel
          writePanel = wx.Panel(nb, -1)
          vboxWrite = wx.BoxSizer(wx.VERTICAL)
          writtenString = unicode("Martynas Jocius \n"
                                  "Nerijus Baliūnas \n"
                                  "Mantas Kriaučiūnas ",
                                  "UTF-8")
          written = enc.toWX(writtenString)
          labelWrite = wx.StaticText(writePanel, -1, written)
          vboxWrite.Add(labelWrite, 0, wx.ALL, 10)
          writePanel.SetSizer(vboxWrite)
          writePanel.SetFocus()
          
          nb.AddPage(writePanel, _("Written By"))
          
          # "Translations" panel
          tPanel = wx.Panel(nb, -1)
          vboxTP = wx.BoxSizer(wx.VERTICAL)
          transString = unicode("Martynas Jocius ",
                                "UTF-8")
          trans = enc.toWX(transString)
          labelTP = wx.StaticText(tPanel, -1, trans)
          vboxTP.Add(labelTP, 0, wx.ALL, 10)
          tPanel.SetSizer(vboxTP)
          
          nb.AddPage(tPanel, _("Translated By"))
    
          # "Thanks" panel
          thPanel = wx.Panel(nb, -1)
          vboxThP = wx.BoxSizer(wx.VERTICAL)
          thanksString = _("Ports:\n\n") + u"Debian/Ubuntu:\n    Kęstutis Biliūnas \n\nMacOS X:\n    Linas Valiukas "
          thanks = enc.toWX(thanksString)
          labelThP = wx.StaticText(thPanel, -1, thanks)
          vboxThP.Add(labelThP, 0, wx.ALL, 10)
          thPanel.SetSizer(vboxThP)
          nb.AddPage(thPanel, _("Thanks To"))
    
    
          # "Sponsor" panel
          sponsorPanel = wx.Panel(nb, -1)
          vboxSP = wx.BoxSizer(wx.VERTICAL)
          sponsorString = _("OpenDict project was sponsored by IDILES.\n"
            "Visit company's website at http://www.idiles.com.")
          sponsor = enc.toWX(sponsorString)
          labelSP = wx.StaticText(sponsorPanel, -1, sponsor)
          vboxSP.Add(labelSP, 0, wx.ALL, 10)
          sponsorPanel.SetSizer(vboxSP)
          nb.AddPage(sponsorPanel, _("Sponsors"))
          
          vbox.Add(nb, 1, wx.ALL | wx.EXPAND, 3)
          
          buttonClose = wx.Button(self, 2005, _("&Close"))
          vbox.Add(buttonClose, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
          
          self.SetSizer(vbox)
          
          wx.EVT_BUTTON(self, 2005, self.onClose)
    
          
       def onClose(self, event):
          """This method is invoked when Close button is clicked"""
          
          self.Destroy()
          
    
    class AboutWindow(wx.Dialog):
       """Information window about OpenDict"""
    
       def __init__(self, parent, id, title, pos=wx.DefaultPosition,
                    size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
          wx.Dialog.__init__(self, parent, id, title, pos, size, style)
    
          hboxButtons = wx.BoxSizer(wx.HORIZONTAL)
          vbox = wx.BoxSizer(wx.VERTICAL)
    
          bmp = wx.Bitmap(os.path.join(info.GLOBAL_HOME,
                                      "pixmaps", "icon-96x96.png"),
                         wx.BITMAP_TYPE_PNG)
          vbox.Add(wx.StaticBitmap(self, -1, bmp, wx.Point(-1, -1)), 0, wx.ALL |
          wx.CENTRE, 5)
    
          title = "OpenDict %s" % info.VERSION
          copy = "Copyright %(c)s 2003-2006 Martynas Jocius \n" \
                "Copyright %(c)s 2007-2008 Idiles Systems Ltd " \
                 % {'c': unicode("\302\251", "UTF-8")}
          desc = _("OpenDict is a multiplatform dictionary.")
          page = "http://opendict.sf.net\nhttps://github.com/nerijus/opendict"
    
          titleLabel = wx.StaticText(self, -1, title,
                                    style=wx.ALIGN_CENTER)
          titleLabel.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
          vbox.Add(titleLabel, 1, wx.ALL | wx.ALIGN_CENTER, 5)
    
          copyLabel = wx.StaticText(self, -1, copy, style=wx.ALIGN_CENTER)
          copyLabel.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))
          vbox.Add(copyLabel, 1, wx.ALL | wx.ALIGN_CENTER, 5)
    
          descLabel = wx.StaticText(self, -1,
            _("OpenDict is a multiplatform dictionary."), style=wx.ALIGN_CENTER)
          descLabel.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
          vbox.Add(descLabel, 1, wx.ALL | wx.ALIGN_CENTER, 5)
    
          pageLabel = wx.StaticText(self, -1, page, style=wx.ALIGN_CENTER)
          pageLabel.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
          vbox.Add(pageLabel, 1, wx.ALL | wx.ALIGN_CENTER, 5)
    
          vbox.Add(wx.StaticLine(self, -1), 0, wx.ALL | wx.EXPAND, 5)
    
          self.buttonCredits = wx.Button(self, 2004, _("C&redits"))
          hboxButtons.Add(self.buttonCredits, 0, wx.ALL | wx.ALIGN_LEFT, 3)
          
          self.buttonLicence = wx.Button(self, 2006, _("&Licence"))
          hboxButtons.Add(self.buttonLicence, 0, wx.ALL | wx.ALIGN_LEFT, 3)
          
          self.buttonOK = wx.Button(self, 2003, _("&Close"))
          hboxButtons.Add(self.buttonOK, 0, wx.ALL | wx.ALIGN_RIGHT, 3)
          
          vbox.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_CENTER, 5)
    
          self.SetSizer(vbox)
          vbox.Fit(self)
    
          wx.EVT_BUTTON(self, 2003, self.onClose)
          wx.EVT_BUTTON(self, 2004, self.onCredits)
          wx.EVT_BUTTON(self, 2006, self.onLicence)
    
    
       def onClose(self, event):
          self.Destroy()
    
          
       def onCredits(self, event):
          creditsWindow = CreditsWindow(self, -1, "Credits",
                                             size=(500, 240))
          creditsWindow.CentreOnScreen()
          creditsWindow.Show()
    
          
       def onLicence(self, event):
          licenseWindow = LicenseWindow(self, -1,
                                    _("Licence"),
                                    size=(500, 400),
                                    style=wx.DEFAULT_FRAME_STYLE)
          licenseWindow.CenterOnScreen()
          licenseWindow.Show(True)
    
    
    opendict-0.6.8/lib/gui/mainwin.py0000664000076400007640000013461013204646653016650 0ustar  nerijusnerijus#
    # OpenDict
    # Copyright (c) 2003-2006 Martynas Jocius 
    # Copyright (c) 2007 IDILES SYSTEMS, UAB 
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your opinion) any later version.
    #
    # This program is distributed in the hope that will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more detals.
    #
    # You shoud have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    # 02110-1301 USA
    #
    
    """
    Main window GUI module
    """
    
    import wx
    import wx.html
    import os
    import cStringIO
    import traceback
    
    from lib import info
    from lib.gui.dictconnwin import DictConnWindow
    from lib.gui.pluginwin import PluginManagerWindow
    from lib.gui.dicteditorwin import DictEditorWindow
    from lib.gui.dictaddwin import DictAddWindow
    from lib.gui.prefswin import PrefsWindow
    from lib.gui import prefswin
    from lib.gui.helpwin import LicenseWindow, AboutWindow
    from lib.gui import errorwin
    from lib.gui import miscwin
    from lib.parser import SlowoParser
    from lib.parser import MovaParser
    from lib.parser import TMXParser
    from lib.parser import DictParser
    from lib.threads import Process
    from lib.history import History
    from lib.installer import Installer
    from lib.extra.html2text import html2text
    from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR
    from lib import misc
    from lib import info
    from lib import util
    from lib import meta
    from lib import enc
    from lib import errortype
    from lib import dicttype
    from lib import plaindict
    
    _ = wx.GetTranslation
    
    # Constants
    titleTemplate = "OpenDict - %s"
    NORMAL_FONT_SIZE = '10'
    
    # Used to remember word when searching by entering text to the entry,
    # selecting one from the list or clicking a link.
    lastLookupWord = None
    
    
    class HtmlWindow(wx.html.HtmlWindow):
    
       """Html control for showing transaltion and catching
       link-clicking"""
    
       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, 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)
    
          
    
    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.AppendMenu(2002, _("Font Size"), self.menuFontSize)
    
          # Font face
          self.menuFontFace = wx.Menu()
          i = 0
          keys = misc.fontFaces.keys()
          keys.sort()
          
          for face in keys:
             self.menuFontFace.AppendRadioItem(2500+i, face, "")
             wx.EVT_MENU(self, 2500+i, self.onDefault)
             if self.app.config.get('fontFace') == misc.fontFaces[face]:
                self.menuFontFace.FindItemById(2500+i).Check(1)
             i+=1
             
          menuView.AppendMenu(2001, _("Font Face"), self.menuFontFace)
          
    
          # Font encoding
          self.menuEncodings = wx.Menu()
          i = 0
          keys = misc.encodings.keys()
          keys.sort()
          for encoding in keys:
             self.menuEncodings.AppendRadioItem(2100+i , encoding, "")
             wx.EVT_MENU(self, 2100+i, self.onDefault)
             if self.app.config.get('encoding') == misc.encodings[encoding]:
                self.menuEncodings.FindItemById(2100+i).Check(1)
             i+=1
             
          menuView.AppendMenu(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 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 = self.app.config.ids.keys()[\
                self.app.config.ids.values().index(name)]
    
             try:
    #            item = wx.MenuItem(self.menuDict,
    #                              itemID,
    #                              encoded)
    #            self.menuDict.AppendItem(item)
                self.menuDict.AppendRadioItem(itemID, encoded, "")
                wx.EVT_MENU(self, itemID, self.onDefault)
                if self.app.config.get('defaultDict') == name:
                   self.menuDict.FindItemById(itemID).Check(1)
    		
             except Exception, 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.AppendItem(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 | wx.ALIGN_RIGHT, 5)
          
          self.entry = wx.ComboBox(self, 153, "", wx.Point(-1, -1),
                                  wx.Size(-1, -1), [], wx.CB_DROPDOWN)
          self.entry.SetToolTipString(_("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.SetToolTipString(_("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.SetToolTipString(_("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.SetToolTipString(_("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.SetToolTipString(_("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)
          self.splitter.SetSashSize(5)
    
          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
          wx.EVT_MENU(self, idPrint, self.onPrint)
          wx.EVT_MENU(self, idPreview, self.onPreview)
          wx.EVT_MENU(self, idCloseDict, self.onCloseDict)
          wx.EVT_MENU(self, idExit, self.onExit)
    
          # Edit menu events
          wx.EVT_MENU(self, idClearHistory, self.onClearHistory)
          wx.EVT_MENU(self, idCopy, self.onCopy)
          wx.EVT_MENU(self, idPaste, self.onPaste)
          wx.EVT_MENU(self, idClearEntry, self.onClean)
    
          # View menu events
          wx.EVT_MENU(self, 2007, self.onIncreaseFontSize)
          wx.EVT_MENU(self, 2008, self.onDecreaseFontSize)
          wx.EVT_MENU(self, 2009, self.onNormalFontSize)
          wx.EVT_MENU(self, idShowHide, self.onHideUnhide)
    
          # Dictionaries menu events
          wx.EVT_MENU(self, idAddDict, self.onAddDict)
    
          # Tools menu events
          wx.EVT_MENU(self, idDictServer, self.onOpenDictConn)
          wx.EVT_MENU(self, idUseScan, self.onUseScanClipboard)
          wx.EVT_MENU(self, idManageDict, self.onShowPluginManager)
          wx.EVT_MENU(self, 5002, self.onShowDictEditor)
          wx.EVT_MENU(self, idPrefs, self.onShowPrefsWindow)
          wx.EVT_MENU(self, idPron, self.onPronounce)
    
          # Help menu events
          wx.EVT_MENU(self, idAbout, self.onAbout)
    
          # Other events
          self.Bind(wx.EVT_BUTTON, self.onSearch, self.buttonSearch)
          wx.EVT_MENU(self, idFind, self.onSearch)
             
          wx.EVT_BUTTON(self, 2010, self.onBack)
          wx.EVT_BUTTON(self, 2011, self.onForward)
          wx.EVT_BUTTON(self, 155, self.onStop)
          wx.EVT_BUTTON(self, 151, self.onClean)
          wx.EVT_BUTTON(self, 152, self.onHideUnhide)
          wx.EVT_TEXT_ENTER(self, 153, self.onSearch)
          wx.EVT_LISTBOX(self, 154, self.onWordSelected)
          wx.EVT_TIMER(self, 5000, self.onTimerSearch)
          wx.EVT_TIMER(self, idClipboard, self.onTimerClipboard)
          wx.EVT_CLOSE(self, self.onCloseWindow)
    
          self.entry.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
    
          # Prepare help message
          self.htmlCode = _("""
    
    
    
    
    
    

    Welcome to OpenDict

    Short usage information:

    • To start using dictionary, select one from Dictionaries menu.
    • To install new dictionary from the Internet, select Manage Dictionaries from Tools menu and choose Available tab.
    • To install new dictionary from file, select Install Dictionary From File... from Dictionaries menu.
    """) 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 = unicode(result.translation, self.activeDictionary.getEncoding()) except Exception, 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: unicode(s, self.activeDictionary.getEncoding()) wordsInUnicode = map(toUnicode, result.words) wordsPreparedForWX = 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, 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, 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 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, 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, 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, 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 self.app.config.ids.keys(): dictionary = self.app.dictionaries.get(self.app.config.ids.get(eventID)) self.loadDictionary(dictionary) label = self.menuDict.FindItemById(eventID).GetLabel() self.app.config.set('defaultDict', label) elif 2100 <= eventID < 2500: label = self.menuEncodings.FindItemById(eventID).GetLabel() self.changeEncoding(label) elif 2500 <= eventID < 2600: label = self.menuFontFace.FindItemById(eventID).GetLabel() self.changeFontFace(label) elif 2600 <= eventID < 2700: label = self.menuFontSize.FindItemById(eventID).GetLabel() 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()) wx.EVT_MENU(self, unid, self.onDefault) #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, 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, 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, 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'))]*5) 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.SetToolTipString(_("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.SetToolTipString(_("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, 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, 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, e: systemLog(ERROR, "Unable to save configuration: %s" % e) opendict-0.6.8/lib/gui/miscwin.py0000664000076400007640000001131713204646653016655 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import wx import wx.html import shutil import traceback from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR from lib import enc from lib.gui import errorwin _ = wx.GetTranslation class PluginLicenceWindow(wx.Dialog): def __init__(self, parent, id, title, msg, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE): wx.Dialog.__init__(self, parent, id, title, pos, size, style) vbox = wx.BoxSizer(wx.VERTICAL) vboxButtons = wx.BoxSizer(wx.HORIZONTAL) htmlWin = wx.html.HtmlWindow(self, -1, style=wx.SUNKEN_BORDER) htmlWin.SetFonts('Helvetica', 'Fixed', [10]*5) error = False try: encodedText = enc.toWX(unicode(msg, 'UTF-8')) htmlWin.SetPage(encodedText) except Exception, e: systemLog(ERROR, "Unable to encode/show licence text: %s" % e) htmlWin.SetPage(_("Error: unable to show licence text")) error = True vbox.Add(htmlWin, 1, wx.ALL | wx.EXPAND, 5) if not error: self.buttonNo = wx.Button(self, wx.ID_CANCEL, _("Do not accept")) vboxButtons.Add(self.buttonNo, 0, wx.ALL, 2) self.buttonYes = wx.Button(self, wx.ID_OK, _("Accept")) vboxButtons.Add(self.buttonYes, 0, wx.ALL, 2) else: self.buttonNo = wx.Button(self, wx.ID_CANCEL, _("Close")) vboxButtons.Add(self.buttonNo, 0, wx.ALL, 2) vbox.Add(vboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 5) self.SetSizer(vbox) def showLicenceAgreement(parentWindow, licenceText): """Show licence agreement window""" dialog = PluginLicenceWindow(parentWindow, -1, _("Licence Agreement"), licenceText, size=(600, 400)) result = dialog.ShowModal() dialog.Destroy() if result == wx.ID_OK: return True return False class InvalidDictWindow(wx.Dialog): def __init__(self, parent, id, title, dicts, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE): wx.Dialog.__init__(self, parent, id, title, pos, size, style) self.dicts = {} self.buttons = {} vbox = wx.BoxSizer(wx.VERTICAL) vboxButtons = wx.BoxSizer(wx.HORIZONTAL) vboxDicts = wx.BoxSizer(wx.VERTICAL) grid = wx.FlexGridSizer(2, 2, 5, 5) msg = _("You have directories that containt invalid dictionaries " \ "and cannot be loaded. \nYou can try to remove these " \ "directories right now.") vbox.Add(wx.StaticText(self, -1, msg), 0, wx.ALL, 5) row = 0 for d in dicts: grid.Add(wx.StaticText(self, -1, d), 0, wx.ALIGN_CENTER_VERTICAL) rid = wx.NewId() self.dicts[rid] = d b = wx.Button(self, rid, _("Remove")) self.buttons[rid] = b grid.Add(b, 1, wx.ALIGN_CENTER_VERTICAL) wx.EVT_BUTTON(self, rid, self.onRemove) vbox.Add(grid, 0, wx.ALL, 10) vbox.Add(wx.StaticLine(self, -1), 1, wx.ALL | wx.EXPAND, 1) self.buttonClose = wx.Button(self, wx.ID_CANCEL, _("Close")) vboxButtons.Add(self.buttonClose, 0, wx.ALL, 5) vbox.Add(vboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 5) self.SetSizer(vbox) self.Fit() def onRemove(self, event): path = self.dicts[event.GetId()] try: shutil.rmtree(path) self.buttons[event.GetId()].Disable() except Exception, e: traceback.print_exc() title = _("Unable to remove") msg = _("Unable to remove directory \"%s\": %s") % (path, e) errorwin.showErrorMessage(title, msg) def showInvalidDicts(parentWin, invalidDicts): """Show licence agreement window""" dialog = InvalidDictWindow(None, -1, _("Invalid Dictionaries"), invalidDicts) result = dialog.ShowModal() dialog.Destroy() opendict-0.6.8/lib/gui/pluginwin.py0000664000076400007640000006123513204646653017224 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # #from wx import * #import wx.lib.mixins.listctrl as listmix import wx from shutil import rmtree import os import traceback import time from lib.gui import errorwin from lib import installer from lib import dicttype from lib import enc from lib import info from lib import misc from lib import xmltools from lib import util from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR _ = wx.GetTranslation class DictListCtrl(wx.ListCtrl): def __init__(self, parent, ID, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): wx.ListCtrl.__init__(self, parent, ID, pos, size, style) class PluginManagerWindow(wx.Frame): """Plugin Manager lets install, remove and view info about installed plugins""" 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.mainWin = parent self.currentInstalledItemSelection = -1 self.currentAvailItemSelection = -1 vboxMain = wx.BoxSizer(wx.VERTICAL) self.installedDictionaries = {} self.availDictionaries = self.app.cache.get('addons') or {} installed = True for dictName in self.app.dictionaries.keys(): self.installedDictionaries[dictName] = installed tabbedPanel = wx.Notebook(self, -1) # Add 'installed' panel panelInstalled = self._makeInstalledPanel(tabbedPanel) tabbedPanel.AddPage(panelInstalled, _("Installed")) # Add 'available' panel panelAvailable = self._makeAvailablePanel(tabbedPanel) tabbedPanel.AddPage(panelAvailable, _("Available")) vboxMain.Add(tabbedPanel, 1, wx.ALL | wx.EXPAND, 2) # Add info panel panelInfo = self._makeInfoPanel() vboxMain.Add(panelInfo, 0, wx.ALL | wx.EXPAND, 2) hboxButtons = wx.BoxSizer(wx.HORIZONTAL) self.buttonClose = wx.Button(self, 163, _("Close")) hboxButtons.Add(self.buttonClose, 0, wx.ALL | wx.ALIGN_RIGHT, 3) vboxMain.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 1) self.SetIcon(wx.Icon(os.path.join(info.GLOBAL_HOME, "pixmaps", "icon-24x24.png"), wx.BITMAP_TYPE_PNG)) self.SetSizer(vboxMain) self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged) wx.EVT_BUTTON(self, 161, self.onInstall) wx.EVT_BUTTON(self, 162, self.onRemove) wx.EVT_BUTTON(self, 163, self.onClose) self.addons = self.app.cache.get("addons", {}) def _makeInstalledPanel(self, tabbedPanel): """Creates panel with for controlling installed dictionaries""" # # Boxes # panelInstalled = wx.Panel(tabbedPanel, -1) vboxInstalled = wx.BoxSizer(wx.VERTICAL) # Help message labelHelp = wx.StaticText(panelInstalled, -1, _("Checked dictionaries are available from the " \ "menu, unchecked dictionaries \nare not available from the menu.")); vboxInstalled.Add(labelHelp, 0, wx.ALL, 3) # # Installed list # idDictList = wx.NewId() self.installedList = wx.CheckListBox(panelInstalled, idDictList, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.SUNKEN_BORDER) self.Bind(wx.EVT_CHECKLISTBOX, self.onDictionaryChecked, self.installedList) self.Bind(wx.EVT_LISTBOX, self.onInstalledSelected, self.installedList) vboxInstalled.Add(self.installedList, 1, wx.ALL | wx.EXPAND, 1) hboxButtons = wx.BoxSizer(wx.HORIZONTAL) # # "Install from file" button # idInstallFile = wx.NewId() self.buttonInstallFile = wx.Button(panelInstalled, idInstallFile, _("Install From File")) hboxButtons.Add(self.buttonInstallFile, 0, wx.ALL | wx.ALIGN_RIGHT, 2) # # "Remove" button # idRemove = wx.NewId() self.buttonRemove = wx.Button(panelInstalled, idRemove, _("Remove")) self.buttonRemove.Disable() hboxButtons.Add(self.buttonRemove, 0, wx.ALL | wx.ALIGN_RIGHT, 2) vboxInstalled.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 2) panelInstalled.SetSizer(vboxInstalled) vboxInstalled.Fit(panelInstalled) # # Make columns # dictNames = self.installedDictionaries.keys() dictNames.sort() self.setInstalledDicts(dictNames) self.Bind(wx.EVT_BUTTON, self.onRemove, self.buttonRemove) self.Bind(wx.EVT_BUTTON, self.onInstallFile, self.buttonInstallFile) return panelInstalled def _makeAvailablePanel(self, tabbedPanel): """Creates panel with for controlling installed dictionaries""" # # Boxes # panelAvailable = wx.Panel(tabbedPanel, -1) vboxAvailable = wx.BoxSizer(wx.VERTICAL) # # List of available dictionaries # idAvailList = wx.NewId() self.availableList = DictListCtrl(panelAvailable, idAvailList, style=wx.LC_REPORT | wx.LC_SINGLE_SEL #| wx.LC_NO_HEADER | wx.SUNKEN_BORDER) vboxAvailable.Add(self.availableList, 1, wx.ALL | wx.EXPAND, 1) # Horizontal box for buttons hboxButtons = wx.BoxSizer(wx.HORIZONTAL) # # "Update" button # idUpdate = wx.NewId() self.buttonUpdate = wx.Button(panelAvailable, idUpdate, _("Update List")) hboxButtons.Add(self.buttonUpdate, 0, wx.ALL | wx.ALIGN_RIGHT, 2) # # "Install" button # idInstall = wx.NewId() self.buttonInstall = wx.Button(panelAvailable, idInstall, _("Install")) self.buttonInstall.Disable() hboxButtons.Add(self.buttonInstall, 0, wx.ALL | wx.ALIGN_RIGHT, 2) vboxAvailable.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 1) panelAvailable.SetSizer(vboxAvailable) vboxAvailable.Fit(panelAvailable) # # Make columns # self.availableList.InsertColumn(0, _("Name")) self.availableList.InsertColumn(1, _("Size")) addons = self.app.cache.get('addons') if not addons: addons = {} dictNames = addons.keys() dictNames.sort() for dictionary in dictNames: index = self.availableList.InsertStringItem(0, dictionary) sizeString = "%d KB" % addons.get(dictionary).getSize() self.availableList.SetStringItem(index, 1, sizeString) self.availableList.SetItemData(index, index+1) # Keep wide if list is empty yet if addons: self.availableList.SetColumnWidth(0, wx.LIST_AUTOSIZE) self.availableList.SetColumnWidth(1, wx.LIST_AUTOSIZE) else: self.availableList.SetColumnWidth(0, 200) self.availableList.SetColumnWidth(1, 120) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onAvailableSelected, self.availableList) self.Bind(wx.EVT_BUTTON, self.onInstall, self.buttonInstall) self.Bind(wx.EVT_BUTTON, self.onUpdate, self.buttonUpdate) return panelAvailable def _makeInfoPanel(self): """Create information panel""" # # Boxes # panelInfo = wx.Panel(self, -1) vboxInfo = wx.BoxSizer(wx.VERTICAL) vboxInfoBox = wx.BoxSizer(wx.VERTICAL) sbSizerInfo = wx.StaticBoxSizer(\ wx.StaticBox(panelInfo, -1, _("Information About Dictionary")), wx.VERTICAL) grid = wx.FlexGridSizer(3, 2, 1, 1) self.labelName = wx.StaticText(panelInfo, -1, "") self.labelVersion = wx.StaticText(panelInfo, -1, "") self.labelFormat = wx.StaticText(panelInfo, -1, "") self.labelAuthor = wx.StaticText(panelInfo, -1, "") self.labelSize = wx.StaticText(panelInfo, -1, "") self.textAbout = wx.TextCtrl(panelInfo, -1, size=(-1, 100), style=wx.TE_MULTILINE | wx.TE_READONLY) self.stName = wx.StaticText(panelInfo, -1, _("Name: ")) self.stName.Disable() grid.Add(self.stName, 0, wx.ALL | wx.ALIGN_RIGHT) grid.Add(self.labelName, 0, wx.ALL) self.stVersion = wx.StaticText(panelInfo, -1, _("Version: ")) self.stVersion.Disable() grid.Add(self.stVersion, 0, wx.ALL | wx.ALIGN_RIGHT) grid.Add(self.labelVersion, 0, wx.ALL) self.stAuthor = wx.StaticText(panelInfo, -1, _("Maintainer: ")) self.stAuthor.Disable() grid.Add(self.stAuthor, 0, wx.ALL | wx.ALIGN_RIGHT) grid.Add(self.labelAuthor, 0, wx.ALL) vboxInfoBox.Add(grid, 1, wx.ALL | wx.EXPAND, 1) vboxInfoBox.Add(self.textAbout, 0, wx.ALL | wx.EXPAND, 1) sbSizerInfo.Add(vboxInfoBox, 1, wx.ALL | wx.EXPAND, 5) vboxInfo.Add(sbSizerInfo, 1, wx.ALL | wx.EXPAND, 5) panelInfo.SetSizer(vboxInfo) vboxInfo.Fit(panelInfo) return panelInfo def onDictionaryChecked(self, event, *args): index = event.GetSelection() label = self.installedList.GetString(index) if self.installedList.IsChecked(index): self._addDictToMenu(label) d = self.app.dictionaries.get(label) d.setActive() else: self._removeDictFromMenu(label) d = self.app.dictionaries.get(label) d.setActive(active=False) self.installedList.SetSelection(index) def _removeDictFromMenu(self, name): self.app.config.activedict.remove(name) self.app.config.activedict.save() self.app.window.removeDictionary(name) def _addDictToMenu(self, name): dict = None for k, v in self.app.dictionaries.items(): if k == name: dict = v if dict: self.app.config.activedict.add(name) self.app.config.activedict.save() self.app.window.addDictionary(dict) def onPageChanged(self, event): _pageInstalled = 0 _pageAvail = 1 sel = event.GetSelection() if sel == _pageInstalled: if self.currentInstalledItemSelection == -1: self.clearInfo() self.disableInfo() else: self.enableInfo() self.showInstalledInfo() elif sel == _pageAvail: if self.currentAvailItemSelection == -1: self.clearInfo() self.disableInfo() else: self.enableInfo() self.showAvailableInfo() def onInstalledSelected(self, event): """Called when list item is selected""" self.currentInstalledItemSelection = event.GetSelection() self.buttonRemove.Enable(1) self.showInstalledInfo() def showInstalledInfo(self): """Show information about selected dictionary""" dictName = self.installedList.GetString(\ self.currentInstalledItemSelection) dictInstance = self.app.dictionaries.get(dictName) self.showInfo(dictInstance) def showAvailableInfo(self): """Show information about selected dictionary""" dictName = self.availableList.GetItemText(\ self.currentAvailItemSelection) dictInstance = self.addons.get(dictName) if not dictInstance: systemLog(ERROR, "BUG: add-on '%s' not found by name" % dictName) return self.showInfo(dictInstance) def showInfo(self, dictInstance): """Show information about dictionary""" self.stName.Enable(1) self.stVersion.Enable(1) self.stAuthor.Enable(1) if dictInstance.getName(): dictName = enc.toWX(dictInstance.getName()) else: dictName = '--' self.labelName.SetLabel(dictName) if dictInstance.getVersion(): dictVersion = enc.toWX(dictInstance.getVersion()) else: dictVersion = '--' self.labelVersion.SetLabel(dictVersion) if dictInstance.getAuthors(): authors = [] for author in dictInstance.getAuthors(): if author: authors.append("%s <%s>" % (author.get('name'), author.get('email'))) dictAuthors = enc.toWX(', '.join(authors)) else: dictAuthors = '--' self.labelAuthor.SetLabel(dictAuthors) if dictInstance.getDescription(): description = enc.toWX(dictInstance.getDescription().strip()) else: description = '' self.textAbout.Clear() self.textAbout.WriteText(description) def onAvailableSelected(self, event): self.currentAvailItemSelection = event.m_itemIndex self.buttonInstall.Enable(1) self.showAvailableInfo() def clearInfo(self): """Clear info fields""" self.labelName.SetLabel('') self.labelVersion.SetLabel('') self.labelAuthor.SetLabel('') self.textAbout.Clear() def disableInfo(self): """Make info widgets inactive""" self.stName.Disable() self.stVersion.Disable() self.stAuthor.Disable() self.textAbout.Disable() def enableInfo(self): """Make info widgets active""" self.stName.Enable(1) self.stVersion.Enable(1) self.stAuthor.Enable(1) self.textAbout.Enable(1) def setInstalledDicts(self, dictNames): """Clear the list of installed dictionaries and set new items""" for i in range(self.installedList.GetCount()): self.installedList.Delete(i) dictNames.sort() i = 0 for dictionary in dictNames: index = self.installedList.Insert(dictionary, i) if self.app.dictionaries[dictionary].getActive(): self.installedList.Check(i) i += 1 def setAvailDicts(self, addons): """Clear the list of available dictionaries and set new items""" self.availableList.DeleteAllItems() names = addons.keys() names.sort() names.reverse() for name in names: addon = addons.get(name) index = self.availableList.InsertStringItem(0, addon.getName()) self.availableList.SetStringItem(index, 1, str(addon.getSize())+" KB") self.availableList.SetItemData(index, index+1) if names: self.availableList.SetColumnWidth(0, wx.LIST_AUTOSIZE) else: title = _("List updated") msg = _("All your dictionaries are up to date.") errorwin.showInfoMessage(title, msg) def onUpdate(self, event): """Update dictionaries list""" title = _("Downloading List") downloader = util.DownloadThread(self.app.config.get('repository-list')) progressDialog = wx.ProgressDialog(title, '', maximum=100, parent=self, style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL) keepGoing = True error = None try: systemLog(INFO, "Opening %s..." % \ self.app.config.get('repository-list')) downloader.start() xmlData = '' while keepGoing and not downloader.finished(): keepGoing = progressDialog.Update(downloader.getPercentage(), downloader.getMessage()) if not keepGoing: downloader.stop() break xmlData += downloader.getBytes() time.sleep(0.1) progressDialog.Destroy() xmlData += downloader.getBytes() systemLog(INFO, "Finished downloading list") except Exception, e: traceback.print_exc() progressDialog.Destroy() error = _("Unable to download list from %s: %s") \ % (self.app.config.get('repository-list'), e) if not error: error = downloader.getErrorMessage() if error: systemLog(ERROR, error) title = _("Unable to download list") errorwin.showErrorMessage(title, error) return if len(xmlData) == 0: return if hasattr(self, "addons"): del self.addons allAddons = xmltools.parseAddOns(xmlData) self.addons = {} for name, obj in allAddons.items(): if name in self.app.dictionaries.keys() \ and obj.getVersion() <= (\ self.app.dictionaries.get(name).getVersion() or ""): continue self.addons[name] = obj app = wx.GetApp() if app.cache.has_key("addons"): del app.cache["addons"] app.cache["addons"] = self.addons self.setAvailDicts(self.addons) def onInstall(self, event): """Install button pressed""" name = self.availableList.GetItemText(\ self.currentAvailItemSelection) dictInfo = self.addons.get(name) if not dictInfo: systemLog(ERROR, "Interal Error, add-on %s not found in list" \ % name) return self._fetchAddon(dictInfo) def onInstallFile(self, event): """Install dictionary from file""" inst = installer.Installer(self.mainWin, self.app.config) inst.showGUI() dictNames = [] for name in self.app.dictionaries.keys(): dictNames.append(enc.toWX(name)) self.setInstalledDicts(dictNames) def onRemove(self, event): """Remove button pressed""" systemLog(INFO, "Removing %s" % self.installedList.GetString( self.currentInstalledItemSelection)) dictName = self.installedList.GetString( self.currentInstalledItemSelection) dictInstance = self.app.dictionaries.get(dictName) try: if dictInstance.getType() == dicttype.PLUGIN: removeDictionary = installer.removePluginDictionary else: removeDictionary = installer.removePlainDictionary removeDictionary(dictInstance) except Exception, e: traceback.print_exc() title = _("Unable to remove") msg = _("Unable to remove dictionary \"%s\"") % dictName errorwin.showErrorMessage(title, msg) return self.installedList.Delete(self.currentInstalledItemSelection) idDictMenuItem = None for iid, dictionary in self.app.config.ids.items(): if dictionary == dictName: idDictMenuItem = iid if idDictMenuItem is not None: self.mainWin.menuDict.Delete(idDictMenuItem) parent = self.GetParent() if parent.activeDictionary \ and dictName == parent.activeDictionary.getName(): parent.onCloseDict(None) self.buttonRemove.Disable() del self.app.dictionaries[dictName] self.clearInfo() self.disableInfo() def onClose(self, event): """Close event occured""" self.Destroy() def _fetchAddon(self, dictInfo): """Fetch add-on using progress bar""" downloadsDir = os.path.join(info.LOCAL_HOME, 'downloads') if not os.path.exists(downloadsDir): os.mkdir(downloadsDir) localPath = os.path.join(downloadsDir, os.path.basename(dictInfo.getLocation())) title = _("Downloading %s...") % dictInfo.getName() progressDialog = wx.ProgressDialog(title, '', maximum=100, parent=self, style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL) keepGoing = True error = None downloader = util.DownloadThread(dictInfo.getLocation()) stopped = False try: fd = open(localPath, 'wb') downloader.start() while keepGoing and not downloader.finished(): keepGoing = progressDialog.Update(downloader.getPercentage(), downloader.getMessage()) if not keepGoing: stopped = True break chunk = downloader.getBytes() fd.write(chunk) time.sleep(0.1) bytes = downloader.getBytes() if len(bytes): fd.write(bytes) progressDialog.Destroy() downloader.stop() except Exception, e: traceback.print_exc() progressDialog.Destroy() error = "Unable to fetch \"%s\" from %s: %s" \ % (dictInfo.getName(), dictInfo.getLocation(), e) systemLog(ERROR, error) fd.close() if stopped: return if not error: error = downloader.getErrorMessage() if error: systemLog(ERROR, error) title = _("Unable to download") errorwin.showErrorMessage(title, error) return md5sum = util.getMD5Sum(localPath) # # Check checksum # if md5sum != dictInfo.getChecksum(): title = _("File is damaged") msg = _("Downloaded file is damaged and cannot be installed. " \ "Please try again.") errorwin.showErrorMessage(title, msg) return # # Remove old version if exists # if dictInfo.getName() in self.app.dictionaries.keys(): try: dictInstance = self.app.dictionaries.get(dictInfo.getName()) if dictInstance.getType() == dicttype.PLUGIN: installer.removePluginDictionary(dictInstance) else: installer.removePlainDictionary(dictInstance) except Exception, e: traceback.print_exc() title = _("Error") msg = _("Unable to remove old version of \"%s\". " "Error occured: \"%s\". New version " "cannot be installed without removing old one.") \ % (dictInstance.getName(), e) errorwin.showErrorMessage(title, msg) return # # Install # try: inst = installer.Installer(self.mainWin, self.app.config) inst.install(localPath) if self.installedList.FindString(dictInfo.getName()) == wx.NOT_FOUND: index = self.installedList.Insert(dictInfo.getName(), 0) self.installedList.Check(0) self.app.config.activedict.add(dictInfo.getName()) self.app.config.activedict.save() # FIXME: Code-wasting. Separated duplicated code into # functions. except Exception, e: traceback.print_exc() title = _("Unable to install") msg = _("Unable to install dictionary \"%s\".") \ % dictInfo.getName() errorwin.showErrorMessage(title, msg) return self.availableList.DeleteItem(self.currentAvailItemSelection) del self.addons[dictInfo.getName()] self.buttonInstall.Disable() self.clearInfo() self.disableInfo() opendict-0.6.8/lib/gui/prefswin.py0000664000076400007640000002242713204646653017045 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # import wx from lib.logger import systemLog, debugLog, DEBUG, INFO, WARNING, ERROR from lib.misc import encodings from lib import enc _ = wx.GetTranslation PRON_COMMAND = "echo \"(SayText \\\"%s\\\")\" | festival" class PrefsWindow(wx.Dialog): """Preferences dialog class""" def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE): """Initialize preferences dialog window""" wx.Dialog.__init__(self, parent, id, title, pos, size, style) self.app = wx.GetApp() vboxMain = wx.BoxSizer(wx.VERTICAL) hboxButtons = wx.BoxSizer(wx.HORIZONTAL) grid = wx.FlexGridSizer(4, 2, 1, 1) grid.Add(wx.StaticText(self, -1, _("Default dictionary: ")), 0, wx.ALIGN_CENTER_VERTICAL) dictNames = [] for name, d in self.app.dictionaries.items(): if d.getActive(): dictNames.append(name) dictNames.sort() dictNames.insert(0, "") try: map(enc.toWX, dictNames) except Exception, e: systemLog(ERROR, "Unable to decode titles to UTF-8 (%s)" % e) self.dictChooser = wx.ComboBox(self, 1100, enc.toWX(self.app.config.get('defaultDict')), wx.Point(-1, -1), wx.Size(-1, -1), dictNames, wx.TE_READONLY) grid.Add(self.dictChooser, 0, wx.EXPAND) grid.Add(wx.StaticText(self, -1, _("Default encoding: ")), 0, wx.ALIGN_CENTER_VERTICAL) self.encChooser = wx.ComboBox(self, 1108, encodings.keys()[encodings.values().index(self.app.config.get('encoding'))], wx.Point(-1, -1), wx.Size(-1, -1), encodings.keys(), wx.TE_READONLY) grid.Add(self.encChooser, 0, wx.EXPAND | wx.ALIGN_RIGHT) grid.AddGrowableCol(1) grid.Add(wx.StaticText(self, -1, _("Default DICT server: ")), 0, wx.ALIGN_CENTER_VERTICAL) self.serverEntry = wx.TextCtrl(self, -1, self.app.config.get('dictServer')) grid.Add(self.serverEntry, 0, wx.EXPAND) grid.Add(wx.StaticText(self, -1, _("Default DICT server port: ")), 0, wx.ALIGN_CENTER_VERTICAL) self.portEntry = wx.TextCtrl(self, -1, self.app.config.get('dictServerPort')) grid.Add(self.portEntry, 0, wx.EXPAND) vboxMain.Add(grid, 0, wx.ALL | wx.EXPAND, 4) # # Pronunciation # panelPron = wx.Panel(self, -1) sbSizerPron = wx.StaticBoxSizer(wx.StaticBox(panelPron, -1, _("Pronunciation")), wx.VERTICAL) panelPron.SetSizer(sbSizerPron) panelPron.SetAutoLayout(True) sbSizerPron.Fit(panelPron) vboxMain.Add(panelPron, 0, wx.ALL | wx.EXPAND, 5) hboxPronCmd = wx.BoxSizer(wx.HORIZONTAL) hboxPronCmd.Add(wx.StaticText(panelPron, -1, _("System Command: ")), 0, wx.ALIGN_CENTER_VERTICAL) self.entryPron = wx.TextCtrl(panelPron, -1, self.app.config.get('pronunciationCommand') or \ PRON_COMMAND) hboxPronCmd.Add(self.entryPron, 1, wx.EXPAND, 0) self.buttonDefaultPron = wx.Button(panelPron, 1106, _("Default")) hboxPronCmd.Add(self.buttonDefaultPron, 0, wx.ALL | wx.EXPAND) sbSizerPron.Add(hboxPronCmd, 0, wx.ALL | wx.EXPAND, 4) hboxPronWhat = wx.BoxSizer(wx.HORIZONTAL) self.rbPronOrig = wx.RadioButton(panelPron, -1, _("Pronounce original word")) hboxPronWhat.Add(self.rbPronOrig, 0, wx.ALL | wx.EXPAND, 3) self.rbPronTrans = wx.RadioButton(panelPron, -1, _("Pronounce translation")) if self.app.config.get('pronounceTrans') == 'True': self.rbPronTrans.SetValue(True) hboxPronWhat.Add(self.rbPronTrans, 0, wx.ALL | wx.EXPAND, 3) sbSizerPron.Add(hboxPronWhat, 0, wx.ALL | wx.EXPAND, 0) self.winSize = wx.CheckBox(self, 1101, _("Save window size on exit")) self.winSize.SetValue(self.app.config.get('saveWindowSize') == 'True') vboxMain.Add(self.winSize, 0, wx.ALL, 3) self.winPos = wx.CheckBox(self, 1102, _("Save window position on exit")) self.winPos.SetValue(self.app.config.get('saveWindowPos') == 'True') vboxMain.Add(self.winPos, 0, wx.ALL, 3) self.sashPos = wx.CheckBox(self, 1103, _("Save sash position on exit")) self.sashPos.SetValue(self.app.config.get('saveSashPos') == 'True') vboxMain.Add(self.sashPos, 0, wx.ALL, 3) self.clipboard = wx.CheckBox(self, 1103, _("Take words from the clipboard by default")) self.clipboard.SetValue(self.app.config.get('useClipboard') == 'True') vboxMain.Add(self.clipboard, 0, wx.ALL, 3) vboxMain.Add(wx.StaticLine(self, -1), 0, wx.ALL | wx.EXPAND, 5) self.buttonOK = wx.Button(self, 1104, _("OK")) hboxButtons.Add(self.buttonOK, 0, wx.ALL | wx.EXPAND, 1) self.buttonCancel = wx.Button(self, 1105, _("Cancel")) hboxButtons.Add(self.buttonCancel, 0, wx.ALL | wx.EXPAND, 1) vboxMain.Add(hboxButtons, 0, wx.ALL | wx.ALIGN_RIGHT, 4) self.SetSizer(vboxMain) self.Fit() self.SetSize((400, -1)) wx.EVT_CHECKBOX(self, 1101, self.onSaveWinSizeClicked) wx.EVT_CHECKBOX(self, 1102, self.onSaveWinPosClicked) wx.EVT_CHECKBOX(self, 1103, self.onSaveSashPosClicked) wx.EVT_BUTTON(self, 1106, self.onDefaultPron) wx.EVT_BUTTON(self, 1104, self.onOK) wx.EVT_BUTTON(self, 1105, self.onCancel) def onSaveWinSizeClicked(self, event): """This method is invoked when checkbox for window size is clicked""" if event.Checked() == 1: self.app.config.winSize = self.GetParent().GetSize() self.app.config.saveWinSize = 1 else: self.app.config.saveWinSize = 0 def onSaveWinPosClicked(self, event): """This method is invoked when checkbox for window position is clicked""" if event.Checked() == 1: self.app.config.winPos = self.GetParent().GetPosition() self.app.config.saveWinPos = 1 else: self.app.config.saveWinPos = 0 def onSaveSashPosClicked(self, event): """This method is invoked when checkbox for sash position is clicked""" if event.Checked() == 1: self.app.config.sashPos = self.GetParent().splitter.GetSashPosition() self.app.config.saveSashPos = 1 else: self.app.config.saveSashPos = 0 def onDefaultPron(self, event): """Set pronunciation command to default value""" self.entryPron.SetValue(PRON_COMMAND) def onOK(self, event): """Save configuration in the configuration object""" self.app.config.set('defaultDict', enc.fromWX(self.dictChooser.GetValue())) self.app.config.set('encoding', encodings[self.encChooser.GetValue()]) if self.app.window.activeDictionary == None: self.app.window.checkEncMenuItem(self.app.config.get('encoding')) self.app.config.set('dictServer', self.serverEntry.GetValue()) self.app.config.set('dictServerPort', self.portEntry.GetValue()) self.app.config.set('pronunciationCommand', self.entryPron.GetValue()) self.app.config.set('pronounceTrans', str(self.rbPronTrans.GetValue())) self.app.config.set('saveWindowSize', str(self.winSize.GetValue())) self.app.config.set('saveWindowPos', str(self.winPos.GetValue())) self.app.config.set('saveSashPos', str(self.sashPos.GetValue())) self.app.config.set('useClipboard', str(self.clipboard.GetValue())) frame = self.GetParent() if self.app.config.get('saveWinSize'): self.app.config.set('windowWidth', frame.GetSize()[0]) self.app.config.set('windowHeight', frame.GetSize()[1]) if self.app.config.get('saveWindowPos'): self.app.config.set('windowPosX', frame.GetPosition()[0]) self.app.config.set('windowPosY', frame.GetPosition()[1]) if self.app.config.get('saveSashPos'): if not frame.wordListHidden(): self.app.config.set('sashPos', frame.splitter.GetSashPosition()) self.app.config.save() self.Destroy() def onCancel(self, event): """Close dialog window discarding changes""" self.Destroy() opendict-0.6.8/lib/gui/registerwin.py0000664000076400007640000001245413204646653017551 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # # Module: gui.registerwin import wx import os from info import home, uhome _ = wx.GetTranslation class FileRegistryWindow(wx.Frame): 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() vboxMain = wx.BoxSizer(wx.VERTICAL) self.types = {} self.types['dwa'] = "Slowo" self.types['mova'] = "Mova" self.types['tmx'] = "TMX" self.types['dz'] = "DICT" self.fileList = wx.ListBox(self, 190, wx.Point(-1, -1), wx.Size(-1, -1), self.app.config.registers.keys(), wx.LB_SINGLE | wx.SUNKEN_BORDER) vboxMain.Add(self.fileList, 1, wx.ALL | wx.EXPAND, 1) vboxInfo = wx.BoxSizer(wx.VERTICAL) if len(self.app.config.registers.keys()) > 0: self.fileList.SetSelection(0) name = self.fileList.GetStringSelection() item = self.app.config.registers[name] else: # There's no registered dictionaries name = "" item = [] item.extend(["", "", ""]) self.labelName = wx.StaticText(self, -1, _("Name: %s") % name) vboxInfo.Add(self.labelName, 0, wx.ALL, 0) self.labelPath = wx.StaticText(self, -1, _("Path: %s") % item[0]) vboxInfo.Add(self.labelPath, 0, wx.ALL, 0) self.labelFormat = wx.StaticText(self, -1, _("Format: %s") % item[1]) vboxInfo.Add(self.labelFormat, 0, wx.ALL, 0) self.labelEnc = wx.StaticText(self, -1, _("Encoding: %s") % item[2]) vboxInfo.Add(self.labelEnc, 0, wx.ALL, 0) vboxMain.Add(vboxInfo, 0, wx.ALL | wx.EXPAND, 10) hboxButtons = wx.BoxSizer(wx.HORIZONTAL) self.buttonInstall = wx.Button(self, 191, _("Add new...")) # FIXME: Needs to be rewritten #hboxButtons.Add(self.buttonInstall, 1, wx.ALL | wx.EXPAND, 1) self.buttonRemove = wx.Button(self, 192, _("Remove selected")) hboxButtons.Add(self.buttonRemove, 1, wx.ALL | wx.EXPAND, 1) self.buttonClose = wx.Button(self, 193, _("Close")) hboxButtons.Add(self.buttonClose, 1, wx.ALL | wx.EXPAND, 1) vboxMain.Add(hboxButtons, 0, wx.ALL | wx.EXPAND, 2) self.SetSizer(vboxMain) self.Fit() wx.EVT_LISTBOX(self, 190, self.onFileSelected) wx.EVT_BUTTON(self, 191, self.onInstall) wx.EVT_BUTTON(self, 192, self.onRemove) wx.EVT_BUTTON(self, 193, self.onClose) def onFileSelected(self, event): info = self.app.config.registers[event.GetString()] self.labelName.SetLabel(_("Name: %s") % event.GetString()) self.labelPath.SetLabel(_("Path: %s") % info[0]) self.labelFormat.SetLabel(_("Format: %s") % self.types[info[1]]) self.labelEnc.SetLabel(_("Encoding: %s") % info[2]) def onInstall(self, event): self.fileList.Append(self.app.window.onAddFromFile(None)) def onRemove(self, event): self.app.window.onCloseDict(None) pos = self.fileList.GetSelection() item = self.fileList.GetStringSelection() if item == "": return self.fileList.Delete(pos) parent = self.GetParent() parent.menuDict.Delete(parent.menuDict.FindItem(item)) if self.app.config.registers[item][1] != "Dict": if os.path.exists(os.path.join(uhome, "register", item+".hash")): try: os.remove(os.path.join(uhome, "register", item+".hash")) except: self.app.window.SetStatusText(_("Error while deleting \"%s\"") \ % (item+".hash")) return elif os.path.exists(os.path.join(home, "register", item+".hash")): try: os.remove(os.path.join(home, "register", item+".hash")) except: self.app.window.SetStatusText(_("Error while deleting \"%s\"") \ % (item+".hash")) return del self.app.config.ids[item] del self.app.config.registers[item] for list in self.app.config.groups.values(): if item in list: list.remove(item) self.labelName.SetLabel(_("Name: %s") % "") self.labelPath.SetLabel(_("Path: %s") % "") self.labelFormat.SetLabel(_("Format: %s") % "") self.labelEnc.SetLabel(_("Encoding: %s") % "") def onClose(self, event): self.Destroy() opendict-0.6.8/lib/tests/0000775000076400007640000000000013204646653015205 5ustar nerijusnerijusopendict-0.6.8/lib/tests/test_editor.py0000664000076400007640000000670213204646653020111 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # Unit Test for editor.py # """ Unit tests for editor.py """ import unittest import os import sys sys.path.append('..') import dicteditor class TestTranslation(unittest.TestCase): """Translation test""" translations = dicteditor.Translation() def test_word(self): """Set/Get word should return correct value""" self.translations.setWord('test') self.assertEquals(self.translations.getWord(), 'test') def test_translation(self): """Should return correct translations""" self.translations.addTranslation('trans1') self.translations.addTranslation('trans2', 'comment2') self.translations.addTranslation('trans3') self.translations.addTranslation('trans3', 'comment3') trans = self.translations.getTranslations() self.assertEquals(trans.has_key('trans1'), True) self.assertEquals(len(trans.keys()), 3) self.assertEquals(trans['trans3'], 'comment3') trans = {'key1': 'value1', 'key2': 'value2'} self.translations.setTranslations(trans) self.assertEquals(len(self.translations.getTranslations()), 2) class TestEditor(unittest.TestCase): """Editor test""" def test_load(self): """Editor should load dictionary from file""" editor = dicteditor.Editor() self.assertEquals(len(editor.getUnits()), 0) editor.load("data/sampledict.dwa") self.assertEquals(len(editor.getUnits()), 7) def test_save(self): """Editor should correctly write dictionary to disk""" editor = dicteditor.Editor() editor.load("data/sampledict.dwa") units = editor.getUnits() editor.save("data/__output.dwa") editor.load("data/__output.dwa") self.assertEquals(len(units), len(editor.getUnits())) os.unlink("data/__output.dwa") def test_getUnit(self): """getUnit() should return desired Translation object""" editor = dicteditor.Editor() editor.load("data/sampledict.dwa") oldCount = len(editor.getUnits()) self.assert_(editor.getUnit('du') != None) def test_addUnit(self): """addUnit() should add new translation unit or update old one""" editor = dicteditor.Editor() editor.load("data/sampledict.dwa") oldCount = len(editor.getUnits()) newUnit = dicteditor.Translation() newUnit.setWord("test") newUnit.addTranslation("utiutiu") editor.addUnit(newUnit) self.assertEquals(len(editor.getUnits()), oldCount + 1) def test_removeUnit(self): """removeUnit() should add new translation unit or update old one""" editor = dicteditor.Editor() editor.load("data/sampledict.dwa") oldCount = len(editor.getUnits()) unit = editor.getUnit('vienas') editor.removeUnit(unit) self.assertEquals(len(editor.getUnits()), oldCount - 1) def test_unicode(self): """All the strings must be unicode objects""" editor = dicteditor.Editor() editor.load("data/sampledict.dwa") for unit in editor.getUnits()[:10]: for trans in unit.getTranslations().keys(): self.assertEquals(type(trans), type(u'')) if __name__ == "__main__": unittest.main() opendict-0.6.8/lib/tests/test_plugin.py0000664000076400007640000000454713204646653020126 0ustar nerijusnerijus# -*- coding: UTF-8 -*- # # OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # Unit Test for editor.py # """ Unit tests for plugin.py """ import unittest import os import sys sys.path.append('../..') from lib import newplugin class TestPluginInfo(unittest.TestCase): """PluginInfo test""" def test_getInfo(self): """PluginInfo should have correct attributes""" fd = open("data/plugin.xml") xmlData = fd.read() fd.close() info = newplugin.PluginInfo(xmlData) self.assertEquals(info.name, u"Sample plugin name ąčę") self.assertEquals(info.version, u"1.2.3") self.assertEquals(info.authors, [{"name": u"Sample author name ąčę", "email": u"sample@example.com"}]) self.assertEquals(info.module, {"name": u"mymodule.py", "lang": u"Python"}) self.assertEquals(info.encoding, u"UTF-8") self.assertEquals(info.usesWordList, True) self.assertEquals(info.opendictVersion, u"0.5.8") self.assertEquals(info.pythonVersion, u"2.3") platforms = [{"name": u"Linux"}, {"name": u"Windows"}, {"name": u"BSD"}] platforms.sort() self.assertEquals(info.platforms, platforms) self.assertEquals(info.description, u"This is short or long description ąčę.") self.assertEquals(info.xmlData, xmlData) class TestDictionaryPlugin(unittest.TestCase): """Test PluginHandler class""" def test_class(self): """__init__ should load plugin info and module""" p = newplugin.DictionaryPlugin(os.path.realpath('data/sampleplugin')) self.assertEquals(p.__class__, newplugin.DictionaryPlugin) self.assert_(p.info != None) self.assert_(p.dictionary != None) self.assert_(p.isValid() == True) self.assertEquals(p.info.__class__, newplugin.PluginInfo) self.assertEquals(len(p.dictionary.search('x').words), 20) self.assertRaises(newplugin.InvalidPluginException, newplugin.DictionaryPlugin, 'blabla') if __name__ == "__main__": unittest.main() opendict-0.6.8/lib/tests/data/0000775000076400007640000000000013204646653016116 5ustar nerijusnerijusopendict-0.6.8/lib/tests/data/plugin.xml0000664000076400007640000000121413204646653020134 0ustar nerijusnerijus Sample plugin name ąčę 1.2.3 mymodule.py UTF-8 True 0.5.8 2.3 This is short or long description ąčę. opendict-0.6.8/lib/tests/data/sampledict.dwa0000664000076400007640000000027013204646653020737 0ustar nerijusnerijusvienas = one ; du = two // two pieces ; trys = three // not 'tree' ; keturi = four // not 'for' ; žirafa = giraphe // from africa ; miškas= forest ; wood; ąžuolas=oak // oak wood; opendict-0.6.8/lib/tests/data/sampleplugin/0000775000076400007640000000000013204646653020616 5ustar nerijusnerijusopendict-0.6.8/lib/tests/data/sampleplugin/plugin.xml0000664000076400007640000000134013204646653022634 0ustar nerijusnerijus Unicode plugin (ąčęėįšųū„“\ž) 0.1 sample.py UTF-8 True 0.5.8 2.3 This plugin only demonstrates new type OpenDict plugin facilities. And Unicode support too: ąčęėįšųū„“\ž. opendict-0.6.8/lib/tests/data/sampleplugin/sample.py0000664000076400007640000000361213204646653022453 0ustar nerijusnerijus# # OpenDict # Copyright (c) 2005 Martynas Jocius # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your opinion) any later version. # # This program is distributed in the hope that will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MECHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more detals. # # You shoud have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA # """ Sample OpenDict plugin (new type) """ import string import sys def init(libraryPath): """This is required method for all plugins. The one and only parameter gives OpenDict library path for requred imports. This method returns plugin instance.""" sys.path.insert(0, libraryPath) return SampleDictionary() class SampleDictionary: """Sample dictionary""" def __init__(self): """Import and save needed modules""" from lib import errortype, meta self.errorModule = errortype self.metaModule = meta def search(self, word): """Look up word""" trans = [] words = [] trans.append("") for i in range(10): trans.append("Do you want to know what
    %s
    is žžčėčęė? So do I!" \ % word) for i in range(20): words.append("ž"+str(i)*5) trans.append("") result = self.metaModule.SearchResult() result.status = self.errorModule.OK result.translation = "".join(trans) result.words = words return result opendict-0.6.8/misc/0000775000076400007640000000000013204646653014230 5ustar nerijusnerijusopendict-0.6.8/misc/opendict.desktop0000664000076400007640000001271113204646653017432 0ustar nerijusnerijus[Desktop Entry] Name=Dictionary OpenDict Name[lt]=Žodynas „OpenDict“ Name[de]=OpenDict Wörterbuch Name[ru]=Словарь OpenDict Name[af]=OpenDict woordeboek Name[sq]=Fjalori OpenDict Name[ast]=Diccionariu OpenDict Name[bn]=OpenDict অভিধান Name[bs]=Rječnik OpenDict Name[pt_BR]=Dicionário OpenDict Name[bg]=Речник OpenDict Name[ca]=Diccionari OpenDict Name[ca@valencia]=Diccionari OpenDict Name[zh_CN]=OpenDict 词典 Name[crh]=Szölük OpenDict Name[cs]=Slovník OpenDict Name[nl]=OpenDict woordenboek Name[da]=Ordbogen OpenDict Name[fr]=Dictionnaire OpenDict Name[gl]=Dicionario OpenDict Name[el]=Λεξικό OpenDict Name[hu]=OpenDict szótár Name[it]=Dizionario OpenDict Name[ja]=OpenDict 辞書 Name[ky]=OpenDict сөздүгү Name[ms]=Kamus OpenDict Name[nb]=OpenDict ordbok Name[oc]=Diccionari OpenDict Name[pt]=Dicionário OpenDict Name[pl]=Słownik OpenDict Name[ro]=Dicționar OpenDict Name[sk]=Slovník OpenDict Name[sl]=Slovar OpenDict Name[sv]=OpenDict ordbok Name[tg]=Луғати OpenDict Name[es]=Diccionario OpenDict Name[tr]=Szölük OpenDict Name[uk]=Словник OpenDict Name[vi]=Từ điển OpenDict GenericName=Dictionary OpenDict GenericName[lt]=Žodynas „OpenDict“ GenericName[de]=OpenDict Wörterbuch GenericName[ru]=Словарь OpenDict GenericName[af]=OpenDict woordeboek GenericName[sq]=Fjalori OpenDict GenericName[ast]=Diccionariu OpenDict GenericName[bn]=OpenDict অভিধান GenericName[bs]=Rječnik OpenDict GenericName[pt_BR]=Dicionário OpenDict GenericName[bg]=Речник OpenDict GenericName[ca]=Diccionari OpenDict GenericName[ca@valencia]=Diccionari OpenDict GenericName[zh_CN]=OpenDict 词典 GenericName[crh]=Szölük OpenDict GenericName[cs]=Slovník OpenDict GenericName[nl]=OpenDict woordenboek GenericName[da]=Ordbogen OpenDict GenericName[fr]=Dictionnaire OpenDict GenericName[gl]=Dicionario OpenDict GenericName[el]=Λεξικό OpenDict GenericName[hu]=OpenDict szótár GenericName[it]=Dizionario OpenDict GenericName[ja]=OpenDict 辞書 GenericName[ky]=OpenDict сөздүгү GenericName[ms]=Kamus OpenDict GenericName[nb]=OpenDict ordbok GenericName[oc]=Diccionari OpenDict GenericName[pt]=Dicionário OpenDict GenericName[pl]=Słownik OpenDict GenericName[ro]=Dicționar OpenDict GenericName[sk]=Slovník OpenDict GenericName[sl]=Slovar OpenDict GenericName[sv]=OpenDict ordbok GenericName[tg]=Луғати OpenDict GenericName[es]=Diccionario OpenDict GenericName[tr]=Szölük OpenDict GenericName[uk]=Словник OpenDict GenericName[vi]=Từ điển OpenDict Comment=Lookup words in a local or Internet dictionary Comment[lt]=Ieškoti žodžių kompiuterio arba Interneto žodyne Comment[de]=Wörter in einem lokalen Wörterbuch oder im Internet nachschlagen Comment[ru]=Поиск слов в интернет-словаре или в локальном словаре Comment[af]=Slaan woorde na in 'n plaaslike of internasionale woordeboek Comment[sq]=Kontrollo fjalët në një fjalor lokal ose në internet Comment[ast]=Gueta pallabres nun diccionariu llocal o d'Internet Comment[bn]=স্থানীয় অথবা ইন্টারনেট অভিধানে শব্দ দেখুন Comment[bs]=Tražite riječ u u lokalnom ili mrežnom rječniku Comment[pt_BR]=Pesquisa palavras em um dicionário local ou da internet Comment[bg]=Търсене на думи в локален или Интернет речник Comment[ca]=Cerqueu paraules en un diccionari local o d'Internet Comment[ca@valencia]=Cerqueu paraules en un diccionari local o d'Internet Comment[zh_CN]=在本地或互联网词典中查找词语 Comment[crh]=Bir yerel ya da internet sözlüğünde kelimeleri ara Comment[cs]=Vyhledávání slov v místním nebo online slovníku Comment[da]=Slå ord op i en lokal ordbog eller på nettet Comment[nl]=Woorden in een lokaal woordenboek of over het internet Comment[fi]=Etsi sanoja paikallisesta tai verkossa sijaitsevasta sanakirjasta Comment[fr]=Chercher des mots sur un dictionnaire local ou en ligne Comment[gl]=Busque palabras nun dicionario local ou da Internet Comment[el]=Αναζητήστε λέξεις σε τοπικά ή διαδικτυακά λεξικά Comment[hu]=Szavak keresése helyi vagy internetes szótárban Comment[it]=Cerca parole in un dizionario locale o su Internet Comment[ja]=ローカルまたはインターネット上の辞書を使って単語を検索します Comment[ky]=Сөздөрдү сөздүктөн же интернетен издөө Comment[ms]=Cari perkataan didalam kamus setempat atau Internet Comment[nb]=Slå opp ord i en lokal eller nettbasert ordbok Comment[oc]=Cercar de mots sus un diccionari local o en linha Comment[pl]=Wyszukuje tłumaczeń w słowniku lokalnym oraz internetowym Comment[pt]=Procurar palavras num dicionário local ou online Comment[ro]=Căutați cuvinte într-un dicționar local sau de pe Internet Comment[sk]=Vyhľadávanie slov v lokálnom alebo internetovom slovníku Comment[sl]=Poiščite besede v krajevnem ali medmrežnem slovarju Comment[es]=Busca palabras en un diccionario local o de Internet Comment[sv]=Slå upp ord i en ordbok lokalt eller på internet Comment[tr]=Bir yerel ya da internet sözlüğünde kelimeleri ara Comment[uk]=Пошук слів у локальному або інтернет-словниках Comment[vi]=Tra cứu từ với từ điển ở máy hoặc trên Internet Exec=opendict Icon=opendict StartupNotify=true Terminal=false Type=Application Categories=GTK;Utility;Dictionary; Keywords=Dictonary;Words; opendict-0.6.8/misc/repository/0000775000076400007640000000000013204646653016447 5ustar nerijusnerijusopendict-0.6.8/misc/repository/Makefile0000664000076400007640000000013413204646653020105 0ustar nerijusnerijusall: python make-addons-list.py Dictionaries http://db.opendict.idiles.com mv *.xml Data/ opendict-0.6.8/misc/repository/README.txt0000664000076400007640000000020213204646653020137 0ustar nerijusnerijusFiles here are used on the repository server to generate dictionary lists to be installed. OpenDict end-users should ignore them.opendict-0.6.8/misc/repository/make-addons-list.py0000775000076400007640000002007013204646653022157 0ustar nerijusnerijus#!/usr/bin/env python import sys import os import zipfile import md5 import xml.dom.minidom # # Add-ons description file generator for OpenDict # Copyright (c) 2003-2006 Martynas Jocius # Copyright (c) 2007 IDILES SYSTEMS, UAB # # Fast & dirty code # def parsePluginConfig(xmlData): """Parse plugin configuration""" doc = xml.dom.minidom.parseString(xmlData) name = None version = None authors = [] description = None pluginElement = doc.getElementsByTagName('plugin')[0] pluginType = pluginElement.getAttribute('type') if pluginType != 'dictionary': raise Exception, "Plugin is not dictionary plugin" # Get name for nameElement in doc.getElementsByTagName('name'): for node in nameElement.childNodes: if node.nodeType == node.TEXT_NODE: name = node.data # Get version for versionElement in doc.getElementsByTagName('version'): for node in versionElement.childNodes: if node.nodeType == node.TEXT_NODE: version = node.data # Get authors for authorElement in doc.getElementsByTagName('author'): authorName = authorElement.getAttribute('name') authorEMail = authorElement.getAttribute('email') authors.append({'name': authorName, 'email': authorEMail}) # Get description for descElement in doc.getElementsByTagName('description'): for node in descElement.childNodes: if node.nodeType == node.TEXT_NODE: description = node.data result = {} result['name'] = name result['version'] = version result['authors'] = authors result['description'] = description return result def parsePlainConfig(xmlData): """Parse plain dict configuration""" doc = xml.dom.minidom.parseString(xmlData) name = None version = None authors = [] description = None registers = doc.getElementsByTagName('plain-dictionary') if len(registers) == 0: raise "Invalid configuration" registerElement = registers[0] for nameElement in registerElement.getElementsByTagName('name'): for node in nameElement.childNodes: name = node.data for versionElement in registerElement.getElementsByTagName('version'): for node in versionElement.childNodes: version = node.data.strip() for authorElement in registerElement.getElementsByTagName('author'): authors.append({'name': authorElement.getAttribute('name'), 'email': authorElement.getAttribute('email')}) for descElement in \ registerElement.getElementsByTagName('description'): for node in descElement.childNodes: description = (description or '') + node.data.strip() result = {} result['name'] = name result['version'] = version result['authors'] = authors result['description'] = description return result def generateElement(**args): """Generate add-on XML DOM elemente""" doc = xml.dom.minidom.Document() addonElement = doc.createElement('add-on') addonElement.setAttribute('type', args.get('type')) # Name element nameElement = doc.createElement('name') addonElement.appendChild(nameElement) nameElement.appendChild(doc.createTextNode(args.get('name'))) # Version element versionElement = doc.createElement('version') addonElement.appendChild(versionElement) versionElement.appendChild(doc.createTextNode(args.get('version'))) # Authors element authorsElement = doc.createElement('authors') addonElement.appendChild(authorsElement) for author in (args.get('authors') or []): authorElement = doc.createElement('author') authorsElement.appendChild(authorElement) authorElement.setAttribute('name', author.get('name')) authorElement.setAttribute('email', author.get('email')) # Description element descElement = doc.createElement('description') addonElement.appendChild(descElement) descElement.appendChild(doc.createTextNode(args.get('description') \ or None)) # MD5 element md5Element = doc.createElement('md5') addonElement.appendChild(md5Element) md5Element.appendChild(doc.createTextNode(args.get('md5sum'))) # URL element urlElement = doc.createElement('url') addonElement.appendChild(urlElement) urlElement.appendChild(doc.createTextNode(args.get('url'))) # Size element sizeElement = doc.createElement('size') addonElement.appendChild(sizeElement) sizeElement.appendChild(doc.createTextNode(str(args.get('size')))) return addonElement def listFiles(start, followLinks, myDepth, maxDepth): """Return file list""" files = [] try: dirList = os.listdir(start) except: if os.path.isdir(start): print 'ERROR: Cannot list directory %s' % start return files for item in dirList: path = os.path.join(start, item) if os.path.isdir(path) and (followLinks or \ (not followLinks and not islink(path))): files.extend(listFiles(path, followLinks, myDepth + 1, maxDepth)) else: files.append(path) return files def makeDocument(addons): """Connect add-on elements to one XML document""" doc = xml.dom.minidom.Document() addonsElement = doc.createElement('opendict-add-ons') doc.appendChild(addonsElement) for addon in addons: addonsElement.appendChild(addon) return doc def main(): """Main procedure""" if len(sys.argv) < 3: print "Usage: %s " % sys.argv[0] print "(Example: '%s . http://xxx.yyy.net/dicts')" % sys.argv[0] sys.exit(1) d = sys.argv[1] baseURL = sys.argv[2] xmlElements = [] for filePath in listFiles(d, True, 0, None): try: zipFile = zipfile.ZipFile(filePath, 'r') except Exception, e: print "ERROR: %s: %s" % (filePath, e) continue # Test CRC if zipFile.testzip(): raise Exception, _("Dictionary plugin file is corrupted") # Check if empty try: topDirectory = zipFile.namelist()[0] except Exception, e: raise Exception, _("Plugin file is empty (%s)" % e) # Check for validity for fileInZip in zipFile.namelist(): dirName = os.path.dirname(fileInZip) fileName = os.path.basename(fileInZip) topDir = zipFile.namelist()[0] plainConfigPath = os.path.join(topDir, 'conf', 'config.xml') pluginConfigPath = os.path.join(topDir, 'plugin.xml') info = {} if plainConfigPath in zipFile.namelist(): info.update(parsePlainConfig(zipFile.read(plainConfigPath))) info['type'] = 'plain-dictionary' elif pluginConfigPath in zipFile.namelist(): info.update(parsePluginConfig(zipFile.read(pluginConfigPath))) info['type'] = 'plugin-dictionary' sz = os.stat(filePath)[6] / 1000 fd = open(filePath) m = md5.new(fd.read()) fd.close() checksum = m.hexdigest() location = baseURL + '/' + filePath xmlElements.append(generateElement(type=info.get('type'), name=info.get('name'), version=info.get('version'), authors=info.get('authors'), description=info.get('description'), url=location, md5sum=checksum, size=sz)) print "* %s" % filePath doc = makeDocument(xmlElements) fd = open('opendict-add-ons.xml', 'w') fd.write(doc.toxml()) fd.close() if __name__ == "__main__": main() opendict-0.6.8/pixmaps/0000775000076400007640000000000013204646653014756 5ustar nerijusnerijusopendict-0.6.8/pixmaps/hide.png0000664000076400007640000000107413204646653016377 0ustar nerijusnerijusPNG  IHDRw=gAMA abKGDC pHYs  ~tIME; ¯lIDATx핱nPcF:VRROE KZZfDyb` PD1Ƈ!AŎc&=wc3r70ԀY1㏪jvݳY]yokcMd(9(*Ov ÐZN_p;+S\j ι\Ǐen/Xg3wwxfs`>(}E=`@b &&ׁ/~^PJ74\d9HsppH9zJD YApjSՍ4c9k7WՍm{j79`<ߛnY$4`X~fyIiTS"JU۲+nmGg> dM+PuUy{?&a)IENDB`opendict-0.6.8/pixmaps/icon-24x24.png0000664000076400007640000000226413204646653017201 0ustar nerijusnerijusPNG  IHDRw=bKGD pHYs  tIME).DmSAIDATHǭmlSU޶ڮ0P$JD#,Ejcb"!!~BL !@  DdemҮ޶mv$U.몫F2 ֲHqĐuII}̙Ӗ̘`YyyH$pD]0OKyhwCP\Gj؜ٸ.uheSBFD \`ݲ8cg%~P7{]p:K!Gd$d$h/`.ze !Pvs:u_Y_kǩS&4ǩ(VO)f_@+]M;{?L2^b =vˉ[J N"f)LxbvXRix}oEyzݳIUN_7H94og,%5E:^Jwx"AMXd$l[-M-& 744J^|ɒGJyw@m'qqT9 ә@Y2%fh̨u0Aˆeފx_ HK(%ԘTi<9`s`e4rJjC` 6AyX_il㕙,QH}&[BY1)X^^AP#8Pb%7R(=} e 9(Q!]m8Q ʊ@8mhlԍihjVORT`S>)Ŗс[RL e\H}ekWӉ+eŚ7+GgkT8TvҐfwwkSҪr;j55"IL13H`XPO\K^':rJ S/rLӹ@{L!!9s+xC,'u;E"ߕd4&OϽ }Tc8}x?5XS(.s94W}^ϥO۸c׾5yT<*3+\vfK>],9GIENDB`opendict-0.6.8/pixmaps/icon-32x32.png0000664000076400007640000000331613204646653017176 0ustar nerijusnerijusPNG  IHDR szzbKGD pHYs  tIME)<[IDATXŗml[gϽ~i^9M&M4kY(h-ec0 IiZm-Ӵ& (*kچMbdIql'~휦a둥>>}2-򈔲S@D_(/=R_nZJáHr"J|:tp={2սz}JUł(L躁X4F @'GbDGZ7\@ `FK[ ohfbPU‚%ǃha$v`pǧi^??8i\@kq:0u^qа^> ϲeNbpdP(J<$0:a0FCȍd*&q3xm%]āXr94))qvD@MKa&cZ cHu^y;^,@NQJgSygbݦؿ5kjI&5\7, IVTWa^t]P BM"%HCPk :Ӵ/f=m46' Oqj'PSSMӖFI1B@7u.C ſ/;Ynwx>託*'vm^- eoa ٺFw71Ή^7 6Ҳm[7(g<0DyK$3s2,ev?+`G=ǩ!\.7yVKd@Jc.{S!:4>O.c' PPص{Ĺz{IiܹԀTJyAkWXyx[zZ ͹VEJ̸c_ߙPa&:cpH`0 s\ 2N@) ~t*r<9kbQ/ 6!Px| 'C$<'3Y.3hPy4A-@gK ̕[̒`=UZi4ERc(\@tZ)vdZuv0,]F_3*7irGv -y.菬3+S5qh>T9lҜ))@yHWkiJo+ԻSZޑpDF'.eR7pOxu$=ʢwo|X{կ<Z\Spj#5,# 9 <nL%.j~p2_/tǥ T^=XC0j=14Bkm^yފm+q{Ssl? 7AY̕L'ҟ?Smy h.OMP Ee- K>!eƈD4#ӇGCGtô[})e`.q_JݾA!SmلBRF Eq`RER  P(wvuH2e#|%U5T5-f#hl#p)--+db"L(AuhZUuJ$)JK #D#}sl|"yK&u4M˾8~^غJyP[X,ux u\.haX L$O*eQvH$X֯wt^u=LքiYm3* w[8H^UCc~*=U(BOO?)ziin+dll0dxM,#eN'dۅ&\҃Ѭdϵ~=iaXòN_r;В* L ۼt(3*x1KVmB2eid.'x 9ϕ2ĥ%`؂-.6,u?9I_g@˝,_ĖYj9NaJJ@˴hmmy|g$&I>{.@ ~{e[ 8z>w:  ͲFk׬zq%Zo?5od*LJO=|fst'}c 0q֭]If ` p)%s6ydhbWs~A T! R͟G-Ǒ}!~^Om|f{wR/?&E^ǞV*d:gͽ'}2\=xK q(G4"?y[ me7LI! g($E6:)|4]yqZ|'.<}!x[S!!'!笁4OɡG\(&yBJ+z5{ndrdIsl8ABԖbYTAJ`nܔIHC:"m^br6{vld[aT\wg-a:~CO^'хGuMH[Pq%?d2v)t~/rs[9729]>"< |Fm6ǭLwnwڒGɩtiYCWh<"4]ʜi|S_/姾7:1I9t}2(':vgyc5L7`_j wjO' =RbKiu]k;s7JzC֮h|@`ZoU>1sVO96vb{c'>dk6^MZOzb8{LiK5e>%f"e]v~`juȄ0nakd.}_B%Ҷm)a Cۆc{N LuS NE\CZ"KBJ=bau E~_e[~u#ǟ&f 1dq]Wé'4X$&N3'g5-6Dr0nqbT+!c~=Mm>ss{k |&둸ŅtP@PeI2*T !ohmRV5b0(blt"7M$X\UqUeKіHw,[MRlY *ʥVgRPX@<G XP˔sLDѝU-PhBb2t w:s@5 LFou*> ۷oRW[?Cee9> ' ( E p؉x<>V529BMh[ita٫|d̃A7+} wV̚T mv،fa``B @yY)55Ux}~CãQXOo dEUjeAu!֮]EQQ!hP:;{H$Mhlf=92_ػ`$@J O$pٸ݃hattz8j씔q宭t355M,gbr ÎNUNgW|::z(^UAO,X븦qۺVX,jT HГzeDyyyqٸ+wmeUuDe WS]][NTUAQd Q*xB"`hx E%jLMMpɳوDb1"=ttt3>6X"H\բb]S*%?2_ܻ`uvy14 ‘86qC+X=;8yۋ$IȊԔUUe-D9z4nM G"ِ% Y1 qԄsjp=!jL:]&J O !pܴu͔sZ4-дh\UKhZLPFjJ7$x^#_s+Hoc O f(vmafV5q{z=vY)*,308|ڷ" ލ$Tш (++AU54M!?φl"(h2 D#Ia2AwWonjZ,jF^/T`4+}(kߥ0k/ࡧcLuLD2|!P}vҼn5jٷoEu3Ajzfueٽ@8G CHl&"I`6XP2*єmh2bYA@8A$3B&l6+nۻ#誦c\UDž"m9H-$/>O_gb!Yr|Ap8hi^KCWnNb5v*:pIp6ruHRttv?XmVdY& rjt dBiɅw"qeYBד-).h22<4JNں!骦ǓKZ,1ӿR, |%cř l#Aހ m&6\U ul߾Z‘I(fݺs4txdBJٵs UUc%)0E?@4EQ֭[MaA>NwD$ ł$A0H(zɄX,@uu%x522F,ZxNW[%n6.EAbʄ"K 6 rD"/|)&:1V ii^Ú x}~=EQh!H`Zٻg;%ELNu I(--!/J0JEH$T4MK{0bwp Wq'~1/0ZJW-Y3%6x>P,2'=uN4> ',M`ֳ͛oN'^)UI%TUUܼ5Շi ֮]EWWèJ}{v`6K! F^_*LYY @x<H-&핼AuB#1 hgrr`0\uu5kZ&FG'9z)//éӝNb˳RTX07fim#-kXn/55v 8|8 6o^m ! j1L^t]G%*+ioh4ko^"`m<ĞFbTVB~a9..SӄGƉFcTWaWb^I-[ř ko2<2$UU)XEQcy k::zH$T,f7055͑NtNSXX;hiYK(fpp]1 Y@[{7E‘QO-2w^HVU*Q'OEy݃Qj-C/`tlIV266AO IQQ!F;vGOQRRJ0#=ʚ5 T+ٵs+95v5vbGfj @Cp$EtKD#h;3pLB{Rk _T>m*.ʩ^Z0V7ZIg#}Cj};Qm6mF^?Oyt]sfj sd;'Ovpxv{%7XVٽ}8t]geM=4 E&rSՒ璂fg>BJ6X&Z TܞRƒbظ Pp8Bww?ndYjҼu7:7ްm6"tA # 0:6IEy9wuB^e6FFƩ,g֍?F\)腕,@d:=Ɉnan`ؙAJ0-5#ccq"Pή^\.7u5($I:Yڄbŗφ+ٹc37x8.5U(r&ZZpDuu5<ձ`k63%$ 26bc y!;1y*\nGYXOYY 33AFFƱ+馫;nM81^;xoIttpTՕoiyE%]w3@dՅY$IfvY(Η !1d!CUU‘sdS8js hׯomh4 `uc=۶n` (LGN;I(ͺ{\aZę م0(e~{(E bjbr(.R#c:=ΝW{QUazC}6}F"(_?>J:ټipftSΕO uR0e>ƭ۬Y3^_l泠Fu/8pzԍxZsRtX5 D10LΆ+/j:@t3ݩ4Y s/N4NV]7ZkL|#hT Biye44bWRZZ4צf8_ϗnb<( N&ViI19`dZEໟ*"OӖ3j+x7rO">%kx׿=^wԀ2& f<S*C* 4"ůG/ko~rXUsI+!{<NArEx;p/nz:GT5SS Eżh폳ќE)2̧ ?W>FX?. ?~1{i)Kε# K RMtݭ&6485pnU(2T)88Lli0e8?wO\4*$uSyogWV HKZ##MFJ|=7g|&}*y0ۇ2ĝXg gn}_ܚOk]ٕ , f<9f~ _ɂN7,_hٍi Y6Z.r~ɡ 楐3kL+8 1A3F7ӹ_'oe1%~~d`!Ӝ!],+z{L>_͏`㻟)H |~|f<9OEym#`V~8uΫm|Y ?>7#,\xDnq1o=5?̋=\)eߕm?ݫϡnw| 93/ayM%I\: .^nf8_ϭn;VK >9fz8in7۩(ax+d/N 8fzV=xr}?_MEA&/wL7A+HZPn"35SS("xٌ K,\HBZ9覀3ܺ fеILpvg})sG%jts|wPkyxP=eT#lo.nLI%̢0_mfgo.o(HˣY&ƝWG쌛hB7gu|Ϟ+W[JLKY .8??y%},|ReUK}ERsF)-I"|9yx'lq߇+-6dl͹~A-ҎuY Νn+_NW(|eܾimYt3c"oq+Ӓ<:|5ue\[ XDˤ,L})L2"0Lym )+lo4SlSU;)RW"W;'ɢs+ԕ2+tzO͜[% .Xu:YF37g* >Qza/Xiqh u3W? 3<и B1Νn" s1&V+&.n,Qwؽ& _8ѵeٌGH!Zե'j7/]EQ?n4 xY&dAC"rF.Ў̿{xXMft LML[t3jgoH'z&)kt:S3oHg[EԛF)i:|tOKe<"1]BԸW8>qx'njK߲ɹ|Ҍ1O>4'd-K7̟۾2^hɒķﬦ*)V{Cf2I;ɢ8"ikq>xjD;F_SzNdݟ[,0Jl^t3N4)I92߽ӑs+OOrd$C`w,_3 8oz:'c6Mr5k- <:X DrlvȾ1c)-m1qa0&]N{J; OШ}bac'u]ʝ[35*K_<󥴟$ILMs#QwW+[EOwDgZ*_Ԍrǖ" I}U7o:Ηo%gx]엜%H$$our:kӗ~0x/lRP=;~[K[[0)ĤGӠ*8/Ig ?|Kw~S{f,躮uT/ ԥI͏,;>=WnZW]ߞ)V\T"%Za3d@hK%psҥޅNOLbv 9n{/"T O Kjs'Fgq"_q?ؐv7 Uԁl#fx|IAUqW_|Mv_p{kР(KBurI,k"#]k.Jp*: G40JX塀lRy #[68O7ND_zCã|Mw.FҔ',WYZ" vSQQ`H}>OP7t]*sRCt1Mg}} ӧUs%,޸>T!b+=>840}1OVoHJ7)*l/3UoFk & y7VƜ3@@B1%@I]pd6F_= a!6v&$?mݗ+IENDB`opendict-0.6.8/pixmaps/left.png0000664000076400007640000000110713204646653016415 0ustar nerijusnerijusPNG  IHDRw=gAMA abKGD pHYs  d_tIME lyIDATx.,AU]Z X]٘x  biMIn2M,g 1L`L]fLwPI%ݧίΩ:D։ v`wv`7n@G;GyLĶЯMo*}ŚDieH RJDAZ}_ PJs~xuHWЅ"b#5Rku"mN'uc"3h4J*T2|(։5]\Zs ;uR c#R.gjӃ‡5%)Ex7WEyXt( Uf@9 O۴Rhx|x6;,M*!cO.^Zs$ir yƁZEDmuä2!KזaOo)IENDB`opendict-0.6.8/pixmaps/opendict-logo.png0000664000076400007640000001017013204646653020226 0ustar nerijusnerijusPNG  IHDR2[( pHYs  tIME  ];7tEXtCommentCreated with The GIMPd%nIDATxyTTwWjdP6)ˆKAMA&6ILƘN9ڜxV!4&-uD% -D4F.(j{7TZ`hq??P[/=LA_ՙ5|>.֭:^3SSn* qeo7 XrV}FG,?{FYtui@iL\c0466L&8C!zM3 SS[|ׂٳgS睡NW cuSp/MҸNegZ!֩RJZjof6[ڂ::c%%f< x@ bul6mrDayyKNֳv-,",rz˒_s1E啫/N:=!>S, -DJcBq㛛[un>שPvv*DbH2nX-Ztԩ^/...+++..5kD:uj̙!ٜQZZgiiis} ;> #47| &Drsy]ak?n7*O_^ 1cj,0 RiG7ϝ7.\lZQ$ (Z~׃domvvv]]===555<}Y]bEUU՘1c^[kK& k$a0ba1bT)oJ4lӵMM?#e \nsKQ>?2&>>&r\39?~%S__ou}jkkRiaa[޾bŊǴ*K'n;ĵ%B#L$"MVM_cDpL75RXSIIY^?㥪 1cưбn޼5R*:ABZutt O>d;hI":f5&,& B,0pvdЅζֶM-.^:e$Y|\lt֎҅m!wt/"--m%'aEKTD F$`""dLc꟦wdM)oܬtg*v} Ξ=KZy7˅ Qśotɺ:GϽ,5J=x"Ƃ/hKm.5Mc﫱jϳ,he˗/X,+h4}<3YL[`PrfFɢ*^B%c)7S|^1m*VO~T 7nٲ/A$,m w~|p)j" &8" 30Prrrf͚p¡\X#K1"ܷBym- xn >Bx4M>YDXLN|Y6--mx78}tg)ʕ+p(= lzcd0IQZd(6>M;Q r\3gEpJrٲesŐz,B.lY= c~C{IxbFN=du]|N\xqÆ -G@Dtɶl_B9G4߯" F&1!lz@?m۶9rdђ=61#z%Ws()Y94bR6ӓXP;4ڰaCfffo^Z.,=Zߧ1kK0blJhwy[DwLBA,gff;w% w'WaaaR4 ã%aޒO(=EKw 9\sBlW'?ɋg*ZhE&%%jL߿OeeAD,FT(vߪ 2V}[rRRR6o[`ώ}Rb+"Vz=VOԴcj-Adk]>)T8 x/^ vxpNd[̆oEUzPL/gi㄄u^{KD8sD~~ɓr9bȒFri6MKs𿤏˾<$qhҺ$9wiii& 12֖#[ţM*X~UZlw3-x}L6-''0֖b"B(DhXkBm_=),C|}ݥKFLBŞoy +r:`qL8ҜaEEp#|FΓ[oQf"Eѣy P%β!>%k{`9h¸=,|>{e`[["EwZ&\27NAFB':jv5⸼ ssSfX'O޶mې.;x,\_~; ~y&xmf_Vo ,"{$oEr !r?Ed;.e_5:[_9ca|jgwWMhhFs^ "P0{4=,ZSxٵߞ3gS߽{l_H<;wJn݅^;x,ڵ[e*vM0pv2t[aRe}JQ6xΝfx·'Nlܸ1,,lD{@MEEEׯ;vЯ<覧zk}8)**:^X>kftҼ$®KZ__d MM-7kfέq1!4_f H` p.\~o _9RݺlP1}/D{AB2{W$O wК>эGщn{D~֐!d4Z]ƙ3g#.C(\W^nqe2?i|)BHS"񞖲` <6rx{{]vFQg{67 SFB,Rj֚䃁H-k~CEm5hvB=HZ 5Y+,J(Q@T119XIl/ Yf`Sե:ef_6 /Vv=5["aS7vܦ-k`ch:@x"8J5ȗAkT3eہOBFG8*,@7o:W<ϲφ1n"#2 <ScIENDB`opendict-0.6.8/pixmaps/stop.png0000664000076400007640000000254313204646653016455 0ustar nerijusnerijusPNG  IHDRw=bKGDIDATxڍ[lUE}vϥ^(X(\,FhVL%Q /j"yИ/hLx( +D4 QPZ.=Z=3ˇ[[NVg2̚_R y#s< 4&Tѓ &Tx.Z\c@W]7;z`N Sgߌ3+qw_ħg+Jujc|e{~]#6?LeS*Z!tBhba{]CEˣ@n||`Ը:ɷ.s ǦO`'?V#gyBQqyT_~0)| @)(lXOz0\fFo[.\ {trrT)кj颥@bFJ~fbxSٓ5fc5Ha_cs;uߜ uKG^\uBiiKw"h:^lo~v}{}+;֒jj᷃_bDqgX~KWB_/ (]O# 8ly}h+G%;Uǯ]=,yY̙@1C`#x(x >j+(Ş7_c]`mdOVʈH>hi 4^cc!0Zł?76]9iFN@T:}Tl88' ρ^2ue-k"{RqŒ պu:ݻ', .Z+g`@n Gv6LPzes}=d`P)QZr09r)Dq4f_[zo ;)I"B%# :Xo:˄R뮝6 '\ GtU:6"tg r J?@! 2' ]™.7<:/@"t " ®tYٱȏ:'Jxws ;-hE+KbP x8I? @0p8)ĕk+Д#hM"%G첶D2ֶǭšIENDB`opendict-0.6.8/pixmaps/unhide.png0000664000076400007640000000077613204646653016752 0ustar nerijusnerijusPNG  IHDRw=gAMA abKGDC pHYs  ~tIME!3{IDATx1OQy]7X,&l!kХЍZjDkh $;LƂ`kk(gkdf$Ӽ9;}p I ~; <S@[BTNJ `w~a@)]9Gݮc67J!ii=yn49W "(s>~k6PAUQQr 0iC jVW`}98/d5@Qkyl\BDQvK㘇#`#^=*B=baq)~ecӴ0@ALTh6x{]~9lvuQamǜzl"u'0g_}b?u/ IENDB`opendict-0.6.8/pixmaps/SVG/0000775000076400007640000000000013204646653015415 5ustar nerijusnerijusopendict-0.6.8/pixmaps/SVG/icon.svg0000664000076400007640000001571513204646653017077 0ustar nerijusnerijus AŽ opendict-0.6.8/pixmaps/SVG/icon-rune.svg0000664000076400007640000001606413204646653020044 0ustar nerijusnerijus opendict-0.6.8/po/0000775000076400007640000000000013204646653013713 5ustar nerijusnerijusopendict-0.6.8/po/Makefile0000664000076400007640000000175713204646653015365 0ustar nerijusnerijusPOFILES=$(wildcard *.po) MOFILES=$(POFILES:.po=.mo) all: opendict.pot $(MOFILES) install: all for file in $(MOFILES); do \ lang=`echo $$file | sed 's/\.mo//'`; \ install -d $(prefix)/share/locale/$$lang/LC_MESSAGES/; \ install -m 0644 $$file $(prefix)/share/locale/$$lang/LC_MESSAGES/opendict.mo; \ done opendict.pot: @echo "Rebuilding the pot file" rm -f *.pot test -f /usr/bin/xgettext && /usr/bin/xgettext ../opendict.py ../lib/*.py ../lib/gui/*.py || echo cp messages.po opendict.pot rm -f messages.po %.mo: %.po msgfmt --verbose --check -o $@ $< %.po: opendict.pot @echo -n "Merging opendict.pot and $@" @msgmerge $@ opendict.pot -o $@.new @if [ "`diff $@ $@.new | grep '[<>]' | wc -l`" -ne 2 ]; then \ mv -f $@.new $@; \ else \ rm -f $@.new; \ fi @msgfmt --statistics $@ clean: rm -f $(MOFILES) messages messages.mo uninstall: for file in $(MOFILES); do \ lang=`echo $$file | sed 's/\.mo//'`; \ rm -f $(prefix)/share/locale/$$lang/LC_MESSAGES/opendict.mo; \ done opendict-0.6.8/po/fr.po0000664000076400007640000010021113204646653014655 0ustar nerijusnerijus# msgid "" msgstr "" "Project-Id-Version: OpenDict 0.6.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-08-29 11:55+EEST\n" "PO-Revision-Date: 2007-08-29 11:43+0300\n" "Last-Translator: MILLE.ca \n" "Language-Team: Francais \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-13\n" "Content-Transfer-Encoding: 8bit\n" #: ../lib/errortype.py:57 msgid "Success" msgstr "Succes" #: ../lib/errortype.py:58 msgid "Search successfully finished." msgstr "Recherche terminee avec succes" #: ../lib/errortype.py:65 ../lib/misc.py:36 msgid "Not found" msgstr "Non trouve" #: ../lib/errortype.py:66 msgid "Word or phrase not found. Try less letters or fewer words." msgstr "Mot ou phrase non trouve. Essayez moins de lettres ou moins de mots." #: ../lib/errortype.py:74 msgid "Internal error" msgstr "Erreur interne" #: ../lib/errortype.py:75 msgid "" "Internal error occured. Please send bug report to the dictionary's of " "current use authors. Thank you." msgstr "" "Une erreur interne est survenue. S.V.P envoyer le rapport d'erreur aux " "auteurs du present dictionnaire. Merci." #: ../lib/errortype.py:83 msgid "Not connected" msgstr "Pas connecte" #: ../lib/errortype.py:84 msgid "" "This dictionary uses Internet connection to translate words. Please connect " "to the Internet and try again." msgstr "" "Ce dictionnaire utilise une connexion Internet pour traduire les mots.S.V.P " "vous connecter a Internet et essayez a nouveau" #: ../lib/errortype.py:93 ../lib/gui/dictconnwin.py:183 #: ../lib/gui/dictconnwin.py:199 msgid "Connection Error" msgstr "Erreur de connexion" #: ../lib/errortype.py:94 msgid "Could not connect to host. Check your Internet connection or try later." msgstr "" "Ne peut se connecter a l'hote. Verifier votre conexion Internet ou essayez " "plus tard." #: ../lib/errortype.py:102 msgid "Invalid encoding" msgstr "Codage invalide" #: ../lib/errortype.py:103 msgid "" "Selected encoding is not correct for this dictionary. Please select another " "from Edit > Character Encoding menu" msgstr "" "Le codage selectionne n'est pas correct pour ce dictionnaire. S.V.P " "selectionnez-en a partir de Editer menu codage de caractere" #: ../lib/errortype.py:112 msgid "OpenDict Bug" msgstr "Erreur de OpenDict" #: ../lib/errortype.py:113 msgid "" "Internal error occured. Please send bug report to OpenDict authors to " "prevent this error in the future. Thank you!" msgstr "" "Une erreur interne est survenue. S.V.P envoyez le rapport d'erreur aux " "auteurs de OpenDict afin de prevenir cette erreur dans le futur. Merci!" #: ../lib/errortype.py:121 msgid "Unknown Error" msgstr "Erreur inconnue" #: ../lib/errortype.py:122 msgid "Unknown error occured." msgstr "Une erreur inconnue est survenue." #: ../lib/gui/dictaddwin.py:35 msgid "Add new dictionary" msgstr "Ajouter un nouveau dictionnaire" #: ../lib/gui/dictaddwin.py:41 msgid "" "The file format of \"%s\" could not be \n" "recognized by its extention. Please select one\n" "from the list:" msgstr "" "Le fichier de format \"%s\" n'a pas pu etre reconnu\n" "par son extension. S.V.P selectionnez-en un a partir de la liste " #: ../lib/gui/dictaddwin.py:47 ../lib/gui/dictaddwin.py:48 #: ../lib/gui/dictaddwin.py:49 ../lib/gui/dictaddwin.py:50 msgid "\"%s\" dictionary format" msgstr "%s format de dictionnaire" #: ../lib/gui/dictaddwin.py:59 ../lib/gui/dicteditorwin.py:91 #: ../lib/gui/prefswin.py:149 msgid "OK" msgstr "OK" #: ../lib/gui/dictaddwin.py:62 ../lib/gui/dictconnwin.py:133 #: ../lib/gui/dicteditorwin.py:94 ../lib/gui/dicteditorwin.py:255 #: ../lib/gui/prefswin.py:152 msgid "Cancel" msgstr "Annuler" #: ../lib/gui/dictconnwin.py:55 msgid "Server: " msgstr "Serveur: " #: ../lib/gui/dictconnwin.py:64 msgid "Default Server" msgstr "Serveur par defaut" #: ../lib/gui/dictconnwin.py:70 msgid "Port: " msgstr "Port: " #: ../lib/gui/dictconnwin.py:73 msgid "Default Port" msgstr "Port par defaut" #: ../lib/gui/dictconnwin.py:83 msgid "Database: " msgstr "Base de donnees: " #: ../lib/gui/dictconnwin.py:87 msgid "Search in all databases" msgstr "Chercher dans toutes les bases de donnees" #: ../lib/gui/dictconnwin.py:94 msgid "Fetch List" msgstr "Prelever la liste" #: ../lib/gui/dictconnwin.py:100 msgid "Character encoding: " msgstr "Encodage de caractere:" #: ../lib/gui/dictconnwin.py:130 msgid "Connect" msgstr "Connecter" #: ../lib/gui/dictconnwin.py:174 ../lib/gui/mainwin.py:689 ../lib/util.py:240 msgid "Done" msgstr "Termine" #: ../lib/gui/dictconnwin.py:178 msgid "Receiving database list..." msgstr "Recevoir la liste de la base de donnees..." #: ../lib/gui/dictconnwin.py:184 ../lib/gui/dictconnwin.py:200 msgid "Unable to connect to server" msgstr "Incapable de se connecter au serveur" #: ../lib/gui/dictconnwin.py:218 msgid "Connecting..." msgstr "Connexion en cours..." #: ../lib/gui/dictconnwin.py:254 ../lib/util.py:219 msgid "Connecting to %s..." msgstr "Se connecter a %s..." #: ../lib/gui/dicteditorwin.py:53 msgid "Word: " msgstr "Mot: " #: ../lib/gui/dicteditorwin.py:88 msgid "Add translation field" msgstr "Ajouter un champ de traduction" #: ../lib/gui/dicteditorwin.py:111 msgid "Translation #%d: " msgstr "Traduction #%d: " #: ../lib/gui/dicteditorwin.py:245 msgid "Dictionary \"%s\" has been changed" msgstr "Dictionnaire \"%s\" a ete change" #: ../lib/gui/dicteditorwin.py:249 ../lib/gui/dicteditorwin.py:337 msgid "Save" msgstr "Sauvegarder" #: ../lib/gui/dicteditorwin.py:252 msgid "Do not save" msgstr "Ne pas sauvegarder" #: ../lib/gui/dicteditorwin.py:305 msgid "Dictionary editor" msgstr "Editeur de dictionnaire" #: ../lib/gui/dicteditorwin.py:321 msgid "Add" msgstr "Ajouter" #: ../lib/gui/dicteditorwin.py:322 msgid "Add word" msgstr "Ajouter un mot" #: ../lib/gui/dicteditorwin.py:325 msgid "Edit" msgstr "Editer" #: ../lib/gui/dicteditorwin.py:326 msgid "Change translation" msgstr "Changer la traduction" #: ../lib/gui/dicteditorwin.py:329 ../lib/gui/miscwin.py:116 #: ../lib/gui/pluginwin.py:156 msgid "Remove" msgstr "Retirer" #: ../lib/gui/dicteditorwin.py:330 msgid "Remove selected word" msgstr "Retirer le mot selectionne" #: ../lib/gui/dicteditorwin.py:333 msgid "Sort" msgstr "Trier" #: ../lib/gui/dicteditorwin.py:334 msgid "Sort word list" msgstr "Trier la liste de mots" #: ../lib/gui/dicteditorwin.py:338 msgid "Save words to file" msgstr "Sauvegarder les mots dans un fichier" #: ../lib/gui/dicteditorwin.py:341 msgid "Save As..." msgstr "sauvegarder sous..." #: ../lib/gui/dicteditorwin.py:342 msgid "Save with a different file name" msgstr "Sauvegarder avec un nom de fichier different" #: ../lib/gui/dicteditorwin.py:351 ../lib/gui/mainwin.py:1377 msgid "Word List" msgstr "Liste de mots" #: ../lib/gui/dicteditorwin.py:370 msgid "New..." msgstr "Nouveau..." #: ../lib/gui/dicteditorwin.py:371 msgid "Start new dictionary" msgstr "Commencer un nouveau dictionnaire" #: ../lib/gui/dicteditorwin.py:374 msgid "Open..." msgstr "Ouvrir..." #: ../lib/gui/dicteditorwin.py:375 msgid "Open dictionary file" msgstr "Ouvrir le fichier du dictionnaire" #: ../lib/gui/dicteditorwin.py:378 ../lib/gui/errorwin.py:84 #: ../lib/gui/miscwin.py:65 ../lib/gui/miscwin.py:124 #: ../lib/gui/pluginwin.py:92 ../lib/gui/registerwin.py:89 msgid "Close" msgstr "Fermer" #: ../lib/gui/dicteditorwin.py:379 msgid "Close editor window" msgstr "Fermer l'editeur de la fenetre" #: ../lib/gui/dicteditorwin.py:410 msgid "New Word" msgstr "Nouveau mot" #: ../lib/gui/dicteditorwin.py:425 msgid "Edit Word" msgstr "Editer mot" #: ../lib/gui/dicteditorwin.py:457 msgid "List is empty" msgstr "La liste est vide" #: ../lib/gui/dicteditorwin.py:463 msgid "List sorted" msgstr "Liste triee" #: ../lib/gui/dicteditorwin.py:486 msgid "Save file" msgstr "Sauvegarder fichier" #: ../lib/gui/dicteditorwin.py:507 msgid "Dictionary saved" msgstr "Dictionnaire sauve" #: ../lib/gui/dicteditorwin.py:517 msgid "Untitled" msgstr "Pas de titre" #: ../lib/gui/dicteditorwin.py:588 ../lib/gui/dicteditorwin.py:645 msgid "Exit confirmation" msgstr "Quitter la confirmation" #: ../lib/gui/dicteditorwin.py:600 ../lib/gui/mainwin.py:1299 #: ../lib/installer.py:61 msgid "Choose dictionary file" msgstr "Choisir le fichier du dictionnaire" #: ../lib/gui/dicteditorwin.py:614 msgid "Open Failed" msgstr "Ouverture echouee" #: ../lib/gui/dicteditorwin.py:615 #, fuzzy msgid "Unable to open dictionary (got message: %s)" msgstr "Incapable de retirer repertoire \"%s\": %s" #: ../lib/gui/dicteditorwin.py:630 msgid "Dictionary loaded" msgstr "Dictionnaire charge" #: ../lib/gui/errorwin.py:72 msgid "An error occured:" msgstr "Une erreur est survenue:" #: ../lib/gui/helpwin.py:69 ../lib/gui/helpwin.py:146 #: ../lib/gui/helpwin.py:209 msgid "&Close" msgstr "&Fermer" #: ../lib/gui/helpwin.py:107 msgid "Written By" msgstr "Ecrit par" #: ../lib/gui/helpwin.py:119 msgid "Translated By" msgstr "Traduit par" #: ../lib/gui/helpwin.py:124 #, fuzzy msgid "" "Ports:\n" "\n" msgstr "Port: " #: ../lib/gui/helpwin.py:129 msgid "Thanks To" msgstr "Remerciments a" #: ../lib/gui/helpwin.py:135 msgid "" "OpenDict project is sponsored by IDILES.\n" "Visit company's website at http://www.idiles.com.\n" "\n" "Report problems by email address support@idiles.com." msgstr "" #: ../lib/gui/helpwin.py:142 msgid "Sponsors" msgstr "" #: ../lib/gui/helpwin.py:180 ../lib/gui/helpwin.py:193 #, fuzzy msgid "OpenDict is a multiplatform dictionary." msgstr "OpenDict est un dictionnaire multiplatforme." #: ../lib/gui/helpwin.py:203 msgid "C&redits" msgstr "&Credits" #: ../lib/gui/helpwin.py:206 msgid "&Licence" msgstr "&Licence" #: ../lib/gui/helpwin.py:235 msgid "Licence" msgstr "Licence" #: ../lib/gui/mainwin.py:92 ../lib/gui/mainwin.py:778 #: ../lib/gui/mainwin.py:816 msgid "Stopped" msgstr "Arrete" #: ../lib/gui/mainwin.py:97 ../lib/gui/mainwin.py:783 msgid "Encode Failed" msgstr "Encodage echoue" #: ../lib/gui/mainwin.py:98 #, fuzzy msgid "Unable to encode text \"%s\" in %s for \"%s\"." msgstr "Incapable de retirer repertoire \"%s\": %s" #: ../lib/gui/mainwin.py:106 ../lib/gui/mainwin.py:761 #: ../lib/gui/mainwin.py:1361 msgid "Searching..." msgstr "En cours de recherche..." #: ../lib/gui/mainwin.py:159 msgid "Look Up\tCtrl-U" msgstr "Chercher\tCtrl-U" #: ../lib/gui/mainwin.py:160 msgid "Lookup up word in the dictionary" msgstr "Chercher mot dans le dictionnaire" #: ../lib/gui/mainwin.py:165 msgid "&Close Dictionary\tCtrl-W" msgstr "&Fermer dictionnaire\tCtrl-W" #: ../lib/gui/mainwin.py:166 msgid "Close opened dicitonary" msgstr "Fermer le dictionnaire ouvert" #: ../lib/gui/mainwin.py:169 msgid "E&xit\tCtrl-Q" msgstr "Quitter\tCtrl-Q" #: ../lib/gui/mainwin.py:170 msgid "Exit program" msgstr "Quitter le programme" #: ../lib/gui/mainwin.py:172 msgid "&File" msgstr "&Fichier" #: ../lib/gui/mainwin.py:180 msgid "&Clear Search Entry\tCtrl-L" msgstr "&Effacer l'entree de recherche\tCtrl-L" #: ../lib/gui/mainwin.py:183 msgid "Clear History" msgstr "Effacer l'historique" #: ../lib/gui/mainwin.py:191 msgid "Copy\tCtrl-C" msgstr "Copier\tCtrl-C" #: ../lib/gui/mainwin.py:192 msgid "Copy selected translation text" msgstr "Copier le texte de traduction selectionne" #: ../lib/gui/mainwin.py:195 msgid "Paste\tCtrl-V" msgstr "Coller\tCtrl-V" #: ../lib/gui/mainwin.py:196 msgid "Paste clipboard text into the search entry" msgstr "Coller le texte du presse-papier dans l'entree de recherche" #: ../lib/gui/mainwin.py:201 msgid "Edit preferences" msgstr "Editer les preferences" #: ../lib/gui/mainwin.py:201 msgid "Preferences...\tCtrl-P" msgstr "Preferences...\tCtrl-N" #: ../lib/gui/mainwin.py:203 msgid "&Edit" msgstr "&Editer" #: ../lib/gui/mainwin.py:213 msgid "Increase\tCtrl-=" msgstr "Augmenter\tCtrl-=" #: ../lib/gui/mainwin.py:214 msgid "Increase text size" msgstr "Augmenter la grandeur du texte" #: ../lib/gui/mainwin.py:215 msgid "Decrease\tCtrl--" msgstr "Diminuer\tCtrl--" #: ../lib/gui/mainwin.py:216 msgid "Decrease text size" msgstr "Diminuer la grandeur du texte" #: ../lib/gui/mainwin.py:218 msgid "Normal\tCtrl-0" msgstr "Normal\tCtrl-0" #: ../lib/gui/mainwin.py:219 msgid "Set normal text size" msgstr "Initialiser la grandeur de texte normale" #: ../lib/gui/mainwin.py:220 msgid "Font Size" msgstr "Grandeur des caracteres" #: ../lib/gui/mainwin.py:235 msgid "Font Face" msgstr "Face des caracteres" #: ../lib/gui/mainwin.py:250 msgid "Character Encoding" msgstr "Encodage de caractere" #: ../lib/gui/mainwin.py:255 msgid "Show/Hide Word List...\tCtrl-H" msgstr "Afficher/Cacher la liste de mots...\tCtrl-H" #: ../lib/gui/mainwin.py:256 msgid "Show or hide word list" msgstr "Afficher ou cacher la liste de mots" #: ../lib/gui/mainwin.py:259 msgid "&View" msgstr "&Visualiser" #: ../lib/gui/mainwin.py:300 msgid "&Install Dictionary From File..." msgstr "&Installer dictionnaire a partir du fichier..." #: ../lib/gui/mainwin.py:302 msgid "&Dictionaries" msgstr "&Dictionnaires" #: ../lib/gui/mainwin.py:311 msgid "Manage Dictionaries...\tCtrl-M" msgstr "Grer dictionnaires...\tCtrl-M" #: ../lib/gui/mainwin.py:312 msgid "Install or remove dictionaries" msgstr "Installer ou retirer dictionnaires" #: ../lib/gui/mainwin.py:314 msgid "Create Dictionaries..." msgstr "creer dictionnaires..." #: ../lib/gui/mainwin.py:315 msgid "Create and edit dictionaries" msgstr "Creer et editer dictionnaires" #: ../lib/gui/mainwin.py:322 msgid "Take Words From Clipboard" msgstr "Prendre des mots a partir du presse-papier" #: ../lib/gui/mainwin.py:323 msgid "Scan the clipboard for text to translate" msgstr "Scanner le presse-papier pour le texte a traduire" #: ../lib/gui/mainwin.py:331 msgid "Connect to DICT Server..." msgstr "Se connecter au serveur du dictionnaire..." #: ../lib/gui/mainwin.py:332 msgid "Open connection to DICT server" msgstr "Ouvrir la connexion au serveur du dictionnaire" #: ../lib/gui/mainwin.py:337 msgid "Pronounce\tCtrl-E" msgstr "" #: ../lib/gui/mainwin.py:338 msgid "Pronounce word" msgstr "" #: ../lib/gui/mainwin.py:341 msgid "Tools" msgstr "Outils" #: ../lib/gui/mainwin.py:350 msgid "&About\tCtrl-A" msgstr "&A propos\tCtrl-A" #: ../lib/gui/mainwin.py:352 msgid "&Help" msgstr "&Aide" #: ../lib/gui/mainwin.py:357 msgid "Word:" msgstr "Mot: " #: ../lib/gui/mainwin.py:362 msgid "" "Enter some text and press \"Look Up\" button or [ENTER] key on your keyboard" msgstr "" "Entrez du texte et appuyer sur le bouton \"Chercher\" ou sur la cle [ENTRER]" "sur votre clavier " #: ../lib/gui/mainwin.py:368 msgid "Look Up" msgstr "Chercher" #: ../lib/gui/mainwin.py:369 msgid "Click this button to look up word in the dictionary" msgstr "Cliquez sur ce bouton afin de chercher le mot dans le dictionnaire" #: ../lib/gui/mainwin.py:380 msgid "History Back" msgstr "En arriere dans l'historique" #: ../lib/gui/mainwin.py:389 msgid "History Forward" msgstr "En avant dans l'historique" #: ../lib/gui/mainwin.py:399 msgid "Stop searching" msgstr "Arreter de chercher" #: ../lib/gui/mainwin.py:423 msgid "Translation" msgstr "Traduction" #: ../lib/gui/mainwin.py:531 msgid "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Welcome to OpenDict

    \n" "

    Short usage information:

    \n" "
      \n" "
    • To start using dictionary, select one from Dictionaries\n" " menu.\n" "
    • \n" "
    • To install new dictionary from the Internet, select\n" " Manage Dictionaries\n" " from Tools menu and choose Available tab.\n" "
    • To install new dictionary from file, select Install Dictionary " "From File...\n" " from Dictionaries menu.\n" "
    • \n" "
    \n" "\n" "\n" msgstr "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Bienvenue a OpenDict

    \n" "

    Courte information:

    \n" "
      \n" "
    • Pour dbuter l'utilisation du dictionnaire, slectionnez-en un a " "partir du Dictionaires\n" " menu.\n" "
    • \n" "
    • Pour installer un nouveau dictionnaire a partir d'Internet, " "slectionnez\n" " Grer Dictionnaires\n" " a partir de Outils menu et choisissez Disponible tab.
    • \n" "
    • Pour installer nouveau dictionnaire a partir du fichier, slectionnez " " Installer Dictionaire a partir du fichier...\n" " A partir de Dictionnaires menu.\n" "
    • \n" "
    \n" "\n" "\n" #: ../lib/gui/mainwin.py:653 #, fuzzy msgid "" "Translation cannot be displayed using selected encoding %s. Please try " "another encoding from View > Character Encoding menu." msgstr "" "Le codage selectionne n'est pas correct pour ce dictionnaire. S.V.P " "selectionnez-en a partir de Editer menu codage de caractere" #: ../lib/gui/mainwin.py:685 msgid "1 word matches" msgstr "Matches de 1 mot" #: ../lib/gui/mainwin.py:687 msgid "%d words match" msgstr "%d mots matches" #: ../lib/gui/mainwin.py:734 msgid "No dictionary activated" msgstr "Pas de dictionnaire active" #: ../lib/gui/mainwin.py:735 msgid "" "No dictionary activated. Please select one from \"Dictionaries\" menu and " "try again." msgstr "" "Pas de dictionnaire active. S.V.P selectionnez-en un a partir du menu " "\"Dictionnaires\" et essayez a nouveau." #: ../lib/gui/mainwin.py:738 msgid "No dictionaries installed" msgstr "pas de dictionnaire installe" #: ../lib/gui/mainwin.py:739 msgid "" "There is no dictionaries installed. You can install one by selecting Tools > " "Manage Dictionaries > Available" msgstr "" "IL n'y a pas de dictionnaire installe. Vous pouvez en installer un en " "slectionant Outils > Gerer Dictionnaires > Disponible" #: ../lib/gui/mainwin.py:752 msgid "Please enter some text and try again" msgstr "S.V.P entrez du texte et essayez a nouveau" #: ../lib/gui/mainwin.py:784 msgid "" "Unable to encode text \"%s\" in %s for \"%s\". That logically means the word " "definition does not exist in the dictionary." msgstr "" #: ../lib/gui/mainwin.py:872 msgid "Connect to DICT server" msgstr "Se connecter au serveur du Dictionnaire" #: ../lib/gui/mainwin.py:899 msgid "Choose a dictionary from \"Dictionaries\" menu" msgstr "Choisir un dictionnaire a partir du menu \"Dictionnaires\"" #: ../lib/gui/mainwin.py:920 msgid "Failed to copy text from the clipboard" msgstr "Echec pour copier texte a partir du presse-papier" #: ../lib/gui/mainwin.py:922 msgid "Clipboard contains no text data" msgstr "Le presse-papier ne contient pas de donnees texte" #: ../lib/gui/mainwin.py:946 ../lib/gui/mainwin.py:1142 #: ../lib/gui/pluginwin.py:772 msgid "Error" msgstr "Erreur" #: ../lib/gui/mainwin.py:955 msgid "Groups" msgstr "Groupes" #: ../lib/gui/mainwin.py:967 msgid "Manage Dictionaries" msgstr "Gerer Dictionnaires" #: ../lib/gui/mainwin.py:981 msgid "File Register" msgstr "Enregistrement de fichier" #: ../lib/gui/mainwin.py:989 msgid "Create Dictionaries" msgstr "Creer Dictionaires" #: ../lib/gui/mainwin.py:998 msgid "Preferences" msgstr "Preferences" #: ../lib/gui/mainwin.py:1088 msgid "Licence Agreement Rejected" msgstr "Accord de la licence rejete" #: ../lib/gui/mainwin.py:1089 msgid "You cannot use dictionary \"%s\" without accepting licence agreement" msgstr "" "Vous ne pouvez pas utiliser le dictionnaire \"%s\" sans accepter les termes " "de la licence" #: ../lib/gui/mainwin.py:1103 msgid "Dictionary Index" msgstr "Index Dictionnaire" #: ../lib/gui/mainwin.py:1104 msgid "" "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..." msgstr "" "Ceci est la premiere fois que vous utilisez ce dictionnaire ou ca et change " "sur disque au dernier indexing. Indexing est utilise pour faire des " "recherches plus efficaces.Le dictionnaire va etre indexe maintenant. Cela " "peut prendre quelques secondes.\n" "\n" "Appuyez sur OK pour continuer..." #: ../lib/gui/mainwin.py:1121 msgid "Index Creation Error" msgstr "Erreur de creation d'Index" #: ../lib/gui/mainwin.py:1122 #, fuzzy msgid "" "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" msgstr "" "Le codage selectionne n'est pas correct pour ce dictionnaire. S.V.P " "selectionnez-en a partir de Editer menu codage de caractere" #: ../lib/gui/mainwin.py:1143 msgid "Unable to load dictionary index table. Got error: %s" msgstr "" #: ../lib/gui/mainwin.py:1153 msgid "Dictionary \"%s\" loaded" msgstr "Dictionnaire \"%s\" charge" #: ../lib/gui/mainwin.py:1205 msgid "Error: not supported dictionary type" msgstr "Erreur: type de dictionnaire non supporte" #: ../lib/gui/mainwin.py:1310 msgid "" "Select dictionary format. If you can't find\n" "the format of your dictionary, the register\n" "system does not support it yet." msgstr "" "Selectionner le format de dictionnaire. Si vous ne pouvez trouver\n" "le format de votre dictionnaire, le systeme d'enregistrement\n" "ne le supporte pas encore." #: ../lib/gui/mainwin.py:1315 msgid "Dictionary format" msgstr "Format de dictionnaire" #: ../lib/gui/mainwin.py:1332 msgid "Choose plugin file" msgstr "Choisissez le fichier de plugin" #: ../lib/gui/mainwin.py:1348 msgid "About" msgstr "A propos" #: ../lib/gui/mainwin.py:1399 msgid "Show word list" msgstr "Afficher la liste de mot" #: ../lib/gui/mainwin.py:1416 msgid "Hide word list" msgstr "Cacher la liste de mot" #: ../lib/gui/mainwin.py:1425 msgid "Failed to print" msgstr "Echec a l'impression" #: ../lib/gui/mainwin.py:1437 msgid "Page preview failed" msgstr "Apercu de la page echoue" #: ../lib/gui/miscwin.py:53 msgid "Error: unable to show licence text" msgstr "Erreur: incapable d'afficher le texte de la licence" #: ../lib/gui/miscwin.py:59 msgid "Do not accept" msgstr "Ne pas accepter" #: ../lib/gui/miscwin.py:62 msgid "Accept" msgstr "Accepter" #: ../lib/gui/miscwin.py:76 msgid "Licence Agreement" msgstr "Acceptation de la licence" #: ../lib/gui/miscwin.py:103 msgid "" "You have directories that containt invalid dictionaries and cannot be " "loaded. \n" "You can try to remove these directories right now." msgstr "" "Vous avez des repertoires qui contiennent des dictionnaires invalides \n" "et ne peuvent pas etre charges. \n" "Vous pouvez essayer de retirer ces repertoires maintenant." #: ../lib/gui/miscwin.py:142 ../lib/gui/pluginwin.py:644 msgid "Unable to remove" msgstr "Incapable de retirer" #: ../lib/gui/miscwin.py:143 msgid "Unable to remove directory \"%s\": %s" msgstr "Incapable de retirer repertoire \"%s\": %s" #: ../lib/gui/miscwin.py:151 msgid "Invalid Dictionaries" msgstr "Dictionnaires invalides" #: ../lib/gui/pluginwin.py:78 msgid "Installed" msgstr "Installe" #: ../lib/gui/pluginwin.py:82 msgid "Available" msgstr "Disponible" #: ../lib/gui/pluginwin.py:124 msgid "" "Checked dictionaries are available from the menu, unchecked dictionaries \n" "are not available from the menu." msgstr "" #: ../lib/gui/pluginwin.py:149 msgid "Install From File" msgstr "Installer a partir du fichier..." #: ../lib/gui/pluginwin.py:208 msgid "Update List" msgstr "Mettre a jour la liste" #: ../lib/gui/pluginwin.py:215 msgid "Install" msgstr "Installer" #: ../lib/gui/pluginwin.py:227 msgid "Name" msgstr "Nom" #: ../lib/gui/pluginwin.py:228 msgid "Size" msgstr "Grandeur" #: ../lib/gui/pluginwin.py:274 msgid "Information About Dictionary" msgstr "Information a propos du dictionnaire" #: ../lib/gui/pluginwin.py:288 msgid "Name: " msgstr "Nom:" #: ../lib/gui/pluginwin.py:293 msgid "Version: " msgstr "Version:" #: ../lib/gui/pluginwin.py:298 msgid "Maintainer: " msgstr "Entretien:" #: ../lib/gui/pluginwin.py:515 msgid "List updated" msgstr "Liste mise-a-jour" #: ../lib/gui/pluginwin.py:516 msgid "All your dictionaries are up to date." msgstr "Tous vos dictionnares sont mis-a-jour." #: ../lib/gui/pluginwin.py:523 msgid "Downloading List" msgstr "Liste de telechargement" #: ../lib/gui/pluginwin.py:558 #, fuzzy msgid "Unable to download list from %s: %s" msgstr "Incapable de telecharger la liste" #: ../lib/gui/pluginwin.py:566 msgid "Unable to download list" msgstr "Incapable de telecharger la liste" #: ../lib/gui/pluginwin.py:645 #, fuzzy msgid "Unable to remove dictionary \"%s\"" msgstr "Incapable de retirer repertoire \"%s\": %s" #: ../lib/gui/pluginwin.py:686 msgid "Downloading %s..." msgstr "Telechargement %s..." #: ../lib/gui/pluginwin.py:743 msgid "Unable to download" msgstr "Incapable de telecharger" #: ../lib/gui/pluginwin.py:753 msgid "File is damaged" msgstr "Le fichier est endommage" #: ../lib/gui/pluginwin.py:754 msgid "Downloaded file is damaged and cannot be installed. Please try again." msgstr "" "Le fichier telecharge est endommage et ne peut pas etre installe. S.V.P " "essayez a nouveau." #: ../lib/gui/pluginwin.py:773 msgid "" "Unable to remove old version of \"%s\". Error occured: \"%s\". New " "version cannot be installed without removing old one." msgstr "" #: ../lib/gui/pluginwin.py:798 msgid "Unable to install" msgstr "Incapable d'installer" #: ../lib/gui/pluginwin.py:799 #, fuzzy msgid "Unable to install dictionary \"%s\"." msgstr "Incapable d'installer le dictionnaire" #: ../lib/gui/prefswin.py:48 msgid "Default dictionary: " msgstr "Dictionnaire par defaut:" #: ../lib/gui/prefswin.py:69 msgid "Default encoding: " msgstr "Encodage par defaut: " #: ../lib/gui/prefswin.py:80 msgid "Default DICT server: " msgstr "Serveur de dictionnaire par defaut:" #: ../lib/gui/prefswin.py:86 msgid "Default DICT server port: " msgstr "Port de serveur de dictionnaire par defaut:" #: ../lib/gui/prefswin.py:99 msgid "Pronunciation" msgstr "" #: ../lib/gui/prefswin.py:107 msgid "System Command: " msgstr "" #: ../lib/gui/prefswin.py:115 #, fuzzy msgid "Default" msgstr "Port par defaut" #: ../lib/gui/prefswin.py:121 msgid "Pronounce original word" msgstr "" #: ../lib/gui/prefswin.py:123 #, fuzzy msgid "Pronounce translation" msgstr "Changer la traduction" #: ../lib/gui/prefswin.py:130 msgid "Save window size on exit" msgstr "Sauvegarder la grandeur de fenetre lorsque vous quittez" #: ../lib/gui/prefswin.py:134 msgid "Save window position on exit" msgstr "Sauvegarder la position de fenetre lorsque vous quittez" #: ../lib/gui/prefswin.py:138 msgid "Save sash position on exit" msgstr "Sauvegarder la position sash lorsque vous quittez" #: ../lib/gui/prefswin.py:143 msgid "Take words from the clipboard by default" msgstr "Prendre les mots a partir du presse-papier par defaut" #: ../lib/gui/registerwin.py:66 ../lib/gui/registerwin.py:105 #: ../lib/gui/registerwin.py:148 msgid "Name: %s" msgstr "Nom: %s" #: ../lib/gui/registerwin.py:69 ../lib/gui/registerwin.py:106 #: ../lib/gui/registerwin.py:149 msgid "Path: %s" msgstr "Chemin: %s" #: ../lib/gui/registerwin.py:72 ../lib/gui/registerwin.py:107 #: ../lib/gui/registerwin.py:150 msgid "Format: %s" msgstr "Format: %s" #: ../lib/gui/registerwin.py:75 ../lib/gui/registerwin.py:108 #: ../lib/gui/registerwin.py:151 msgid "Encoding: %s" msgstr "Encodage: %s" #: ../lib/gui/registerwin.py:82 msgid "Add new..." msgstr "Ajouter nouveau..." #: ../lib/gui/registerwin.py:86 msgid "Remove selected" msgstr "Retirer l'element selectionne" #: ../lib/gui/registerwin.py:130 ../lib/gui/registerwin.py:137 msgid "Error while deleting \"%s\"" msgstr "Erreur pendant la suppression\"%s\"" #: ../lib/installer.py:81 msgid "Recognition Error" msgstr "Reconnaissance d'erreur" #: ../lib/installer.py:82 msgid "File %s is not supported by OpenDict" msgstr "Fichier %s n'est pas supporte par OpenDict" #: ../lib/installer.py:108 ../lib/installer.py:110 msgid "Installation failed" msgstr "Installation echouee" #: ../lib/installer.py:122 ../lib/installer.py:308 ../lib/installer.py:316 msgid "Installation Error" msgstr "Erreur d'installation" #: ../lib/installer.py:124 ../lib/installer.py:128 msgid "Error: Installation failed" msgstr "Erreur: Installation echouee" #: ../lib/installer.py:132 msgid "Dictionary installed" msgstr "Dictionnaire installe" #: ../lib/installer.py:133 msgid "" "Dictionary successfully installed. You can choose it from \"Dictionaries\" " "menu now." msgstr "" "Dictionnaire installe avec succes. Vous pouvez le trouver a partir du menu " "\"Dictionnaires\" maintenant." #: ../lib/installer.py:143 ../lib/installer.py:218 msgid "File %s does not exist" msgstr "Fichier %s n'existe pas" #: ../lib/installer.py:146 ../lib/installer.py:222 msgid "%s is not a file" msgstr "%s n'est pas un fichier" #: ../lib/installer.py:160 msgid "Dictionary \"%s\" is already installed" msgstr "Dictionnaire \"%s\" est deja installe" #: ../lib/installer.py:226 msgid "%s is not OpenDict dictionary plugin" msgstr "%s n'est pas le plugin du dictionnaire OpenDict" #: ../lib/installer.py:233 msgid "File \"%s\" is not valid ZIP file" msgstr "Fichier \"%s\" n'est pas un fichier ZIP valide" #: ../lib/installer.py:238 msgid "Dictionary plugin file is corrupted" msgstr "Le fichier plugin du dictionnaire est corrompu" #: ../lib/installer.py:244 msgid "Plugin file is empty (%s)" msgstr "Le fichier plugin est vide (%s)" #: ../lib/installer.py:268 msgid "Selected file is not valid OpenDict plugin" msgstr "Le fichier selectionne n'est pas un plugin OpenDict valide" #: ../lib/installer.py:295 ../lib/installer.py:377 msgid "" "This dictionary already installed. If you want to upgrade it, please remove " "old version first." msgstr "" "Ce dictionnaire est deja installe. Si vous voulez le mettre a jour, S.V.P " "retirer la vielle version tout d'abord." #: ../lib/installer.py:309 ../lib/installer.py:317 msgid "" "Installation tool for this dictionary failed to start. Please report this " "problem to developers." msgstr "" "L'outil d'installation pour ce dictionnaire a echoue a dmarrer. S.V.P " "reporter ce probleme aux developpeurs" #: ../lib/installer.py:323 msgid "Installation Aborted" msgstr "Installation avortee" #: ../lib/installer.py:324 msgid "Dictionary installation has been aborted." msgstr "L'installation du dictionnaire a ete avortee." #: ../lib/installer.py:348 ../lib/installer.py:400 msgid "" "Error while removing created directories after plugin installation failure. " "This may be permission or disk space error." msgstr "" "Erreur pendant la suppresion des repertoires crees apres l'echec de " "l'installation des plugin. Ceci pourrait etre une erreur de permission ou " "une erreur d'espace disque." #: ../lib/installer.py:352 msgid "Unable to install plugin" msgstr "Incapable d'installer les plugins " #: ../lib/installer.py:369 msgid "Compressed dictionary file is corrupted" msgstr "Le fichier compresse du dictionnaire est corrompu" #: ../lib/installer.py:404 msgid "Unable to install dictionary" msgstr "Incapable d'installer le dictionnaire" #: ../lib/misc.py:37 msgid "Dictionary error, please report to its author" msgstr "Erreur dictionnaire, S.V.P reportez-la a son auteur" #: ../lib/misc.py:38 msgid "Syntax error" msgstr "Erreur de syntaxe" #: ../lib/misc.py:39 msgid "You must be connected to the internet to use this dictionary" msgstr "Vous devez etre connecte a Internet pour utiliser ce dictionnaire" #: ../lib/misc.py:40 msgid "Time out" msgstr "Temps d'arret" #: ../lib/misc.py:41 msgid "Bad encoding is set for this dictionary, try another" msgstr "" "Un mauvais encodement est initialis pour ce dictionnaire, essayez-en un " "autre" #: ../lib/misc.py:48 msgid "Unicode (UTF-8)" msgstr "" #: ../lib/misc.py:49 msgid "Western (ISO-8859-1)" msgstr "" #: ../lib/misc.py:50 msgid "Central European (ISO-8859-2)" msgstr "" #: ../lib/misc.py:51 msgid "Nordic (ISO-8859-10)" msgstr "" #: ../lib/misc.py:52 msgid "South European (ISO-8859-3)" msgstr "" #: ../lib/misc.py:53 msgid "Greek (ISO-8859-7)" msgstr "" #: ../lib/misc.py:54 msgid "Baltic (ISO-8859-13)" msgstr "" #: ../lib/misc.py:55 msgid "Cyrillic (KOI8-R)" msgstr "" #: ../lib/misc.py:56 msgid "Arabic (ISO-8859-6)" msgstr "" #: ../lib/util.py:235 msgid "Downloading... %d%%" msgstr "Telechargement... %d%%" #: ../opendict.py:115 msgid "wxPython Version Error" msgstr "wxPython version erreur" #: ../opendict.py:116 msgid "" "wxPython %s is installed on this system.\n" "\n" "OpenDict %s requires wxPython 2.6 to run smoothly.\n" "\n" "You can find wxPython 2.6 at http://www.wxpython.org or you can install it " "using your system package manager." msgstr "" #~ msgid "&License" #~ msgstr "&Licence" #~ msgid "Edit Dictionaries" #~ msgstr "Taisyti žodynus" opendict-0.6.8/po/lt.po0000664000076400007640000010002213204646653014665 0ustar nerijusnerijus# msgid "" msgstr "" "Project-Id-Version: OpenDict 0.6.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2007-08-29 11:55+EEST\n" "PO-Revision-Date: 2008-03-03 11:11+0300\n" "Last-Translator: Martynas Jocius \n" "Language-Team: Lithuanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-13\n" "Content-Transfer-Encoding: 8bit\n" #: ../lib/errortype.py:57 msgid "Success" msgstr "Skm" #: ../lib/errortype.py:58 msgid "Search successfully finished." msgstr "Paieka skmingai baigta" #: ../lib/errortype.py:65 #: ../lib/misc.py:36 msgid "Not found" msgstr "Nerasta" #: ../lib/errortype.py:66 msgid "Word or phrase not found. Try less letters or fewer words." msgstr "odis arba fraz nebuvo rasti. Bandykite vesti maiau raidi arba odi." #: ../lib/errortype.py:74 msgid "Internal error" msgstr "Vidin klaida" #: ../lib/errortype.py:75 msgid "Internal error occured. Please send bug report to the dictionary's of current use authors. Thank you." msgstr "vyko vidin klaida. Praome isisti klaidos praneim apie aktyvuoto odyno klaid jo autoriams. Dkojame." #: ../lib/errortype.py:83 msgid "Not connected" msgstr "Nepavyko prisijungti" #: ../lib/errortype.py:84 msgid "This dictionary uses Internet connection to translate words. Please connect to the Internet and try again." msgstr "is odynas paiek atlieka Internete. Prisijunkite prie Interneto ir bandykite dar kart." #: ../lib/errortype.py:93 #: ../lib/gui/dictconnwin.py:183 #: ../lib/gui/dictconnwin.py:199 msgid "Connection Error" msgstr "Prisijungimo klaida" #: ../lib/errortype.py:94 msgid "Could not connect to host. Check your Internet connection or try later." msgstr "Nepavyko prisijungti. Patikrinkite Interneto ry arba pabandykite vliau." #: ../lib/errortype.py:102 msgid "Invalid encoding" msgstr "Netinkama koduot" #: ../lib/errortype.py:103 msgid "Selected encoding is not correct for this dictionary. Please select another from Edit > Character Encoding menu" msgstr "Pasirinkta koduot nra tinkama iam odynui. Pasirinkite kit koduot i meniu Keisti > Teksto koduot" #: ../lib/errortype.py:112 msgid "OpenDict Bug" msgstr "OpenDict klaida" #: ../lib/errortype.py:113 msgid "Internal error occured. Please send bug report to OpenDict authors to prevent this error in the future. Thank you!" msgstr "vyko vidin klaida. Kad tai nepasikartot ateityje, praome isisti praneim apie klaid OpenDict autoriams. Dkojame!" #: ../lib/errortype.py:121 msgid "Unknown Error" msgstr "Neinoma klaida" #: ../lib/errortype.py:122 msgid "Unknown error occured." msgstr "vyko neinoma klaida." #: ../lib/gui/dictaddwin.py:35 msgid "Add new dictionary" msgstr "Pridti nauj odyn" #: ../lib/gui/dictaddwin.py:41 msgid "" "The file format of \"%s\" could not be \n" "recognized by its extention. Please select one\n" "from the list:" msgstr "" "Bylos formatas %s negali bti atpaintas\n" "pagal pltin. Pasirinkite i srao: " #: ../lib/gui/dictaddwin.py:47 #: ../lib/gui/dictaddwin.py:48 #: ../lib/gui/dictaddwin.py:49 #: ../lib/gui/dictaddwin.py:50 msgid "\"%s\" dictionary format" msgstr "%s odyno formatas" #: ../lib/gui/dictaddwin.py:59 #: ../lib/gui/dicteditorwin.py:91 #: ../lib/gui/prefswin.py:149 msgid "OK" msgstr "Gerai" #: ../lib/gui/dictaddwin.py:62 #: ../lib/gui/dictconnwin.py:133 #: ../lib/gui/dicteditorwin.py:94 #: ../lib/gui/dicteditorwin.py:255 #: ../lib/gui/prefswin.py:152 msgid "Cancel" msgstr "Ataukti" #: ../lib/gui/dictconnwin.py:55 msgid "Server: " msgstr "Serveris: " #: ../lib/gui/dictconnwin.py:64 msgid "Default Server" msgstr "Numatytas serveris" #: ../lib/gui/dictconnwin.py:70 msgid "Port: " msgstr "Prievadas: " #: ../lib/gui/dictconnwin.py:73 msgid "Default Port" msgstr "Numatytas prievadas" #: ../lib/gui/dictconnwin.py:83 msgid "Database: " msgstr "Duomen baz: " #: ../lib/gui/dictconnwin.py:87 msgid "Search in all databases" msgstr "Iekoti visose duomen bazse" #: ../lib/gui/dictconnwin.py:94 msgid "Fetch List" msgstr "Parsisti sra" #: ../lib/gui/dictconnwin.py:100 msgid "Character encoding: " msgstr "Simboli koduot:" #: ../lib/gui/dictconnwin.py:130 msgid "Connect" msgstr "Prisijungti" #: ../lib/gui/dictconnwin.py:174 #: ../lib/gui/mainwin.py:689 #: ../lib/util.py:240 msgid "Done" msgstr "Atlikta" #: ../lib/gui/dictconnwin.py:178 msgid "Receiving database list..." msgstr "Siuniamas duomen bazi sraas..." #: ../lib/gui/dictconnwin.py:184 #: ../lib/gui/dictconnwin.py:200 msgid "Unable to connect to server" msgstr "Nepavyko prisijungti prie serverio" #: ../lib/gui/dictconnwin.py:218 msgid "Connecting..." msgstr "Jungiamasi..." #: ../lib/gui/dictconnwin.py:254 #: ../lib/util.py:219 msgid "Connecting to %s..." msgstr "Jungiamasi prie %s..." #: ../lib/gui/dicteditorwin.py:53 msgid "Word: " msgstr "odis: " #: ../lib/gui/dicteditorwin.py:88 msgid "Add translation field" msgstr "Pridti vertimo laukel" #: ../lib/gui/dicteditorwin.py:111 msgid "Translation #%d: " msgstr "Vertimas #%d: " #: ../lib/gui/dicteditorwin.py:245 msgid "Dictionary \"%s\" has been changed" msgstr "odynas %s buvo pakeistas" #: ../lib/gui/dicteditorwin.py:249 #: ../lib/gui/dicteditorwin.py:337 msgid "Save" msgstr "Isaugoti" #: ../lib/gui/dicteditorwin.py:252 msgid "Do not save" msgstr "Nesaugoti" #: ../lib/gui/dicteditorwin.py:305 msgid "Dictionary editor" msgstr "odyn redaktorius" #: ../lib/gui/dicteditorwin.py:321 msgid "Add" msgstr "Pridti" #: ../lib/gui/dicteditorwin.py:322 msgid "Add word" msgstr "Pridti od" #: ../lib/gui/dicteditorwin.py:325 msgid "Edit" msgstr "Keisti" #: ../lib/gui/dicteditorwin.py:326 msgid "Change translation" msgstr "Keisti vertim" #: ../lib/gui/dicteditorwin.py:329 #: ../lib/gui/miscwin.py:116 #: ../lib/gui/pluginwin.py:156 msgid "Remove" msgstr "Paalinti" #: ../lib/gui/dicteditorwin.py:330 msgid "Remove selected word" msgstr "Paalinti pasirinkt od" #: ../lib/gui/dicteditorwin.py:333 msgid "Sort" msgstr "Rikiuoti" #: ../lib/gui/dicteditorwin.py:334 msgid "Sort word list" msgstr "Rikiuoti odi sra" #: ../lib/gui/dicteditorwin.py:338 msgid "Save words to file" msgstr "Isaugoti odius byl" #: ../lib/gui/dicteditorwin.py:341 msgid "Save As..." msgstr "Isaugoti kaip..." #: ../lib/gui/dicteditorwin.py:342 msgid "Save with a different file name" msgstr "Isaugoti kitu vardu" #: ../lib/gui/dicteditorwin.py:351 #: ../lib/gui/mainwin.py:1377 msgid "Word List" msgstr "odi sraas" #: ../lib/gui/dicteditorwin.py:370 msgid "New..." msgstr "Naujas..." #: ../lib/gui/dicteditorwin.py:371 msgid "Start new dictionary" msgstr "Sukurti nauj odyn" #: ../lib/gui/dicteditorwin.py:374 msgid "Open..." msgstr "Atidaryti..." #: ../lib/gui/dicteditorwin.py:375 msgid "Open dictionary file" msgstr "Atidaryti odyno byl" #: ../lib/gui/dicteditorwin.py:378 #: ../lib/gui/errorwin.py:84 #: ../lib/gui/miscwin.py:65 #: ../lib/gui/miscwin.py:124 #: ../lib/gui/pluginwin.py:92 #: ../lib/gui/registerwin.py:89 msgid "Close" msgstr "Udaryti" #: ../lib/gui/dicteditorwin.py:379 msgid "Close editor window" msgstr "Udaryti redaktoriaus lang" #: ../lib/gui/dicteditorwin.py:410 msgid "New Word" msgstr "Naujas odis" #: ../lib/gui/dicteditorwin.py:425 msgid "Edit Word" msgstr "Taisyti od" #: ../lib/gui/dicteditorwin.py:457 msgid "List is empty" msgstr "Sraas tuias" #: ../lib/gui/dicteditorwin.py:463 msgid "List sorted" msgstr "Sraas surikiuotas" #: ../lib/gui/dicteditorwin.py:486 msgid "Save file" msgstr "Isaugoti byl" #: ../lib/gui/dicteditorwin.py:507 msgid "Dictionary saved" msgstr "odynas isaugotas" #: ../lib/gui/dicteditorwin.py:517 msgid "Untitled" msgstr "Be pavadinimo" #: ../lib/gui/dicteditorwin.py:588 #: ../lib/gui/dicteditorwin.py:645 msgid "Exit confirmation" msgstr "Ijimo patvirtinimas" #: ../lib/gui/dicteditorwin.py:600 #: ../lib/gui/mainwin.py:1299 #: ../lib/installer.py:61 msgid "Choose dictionary file" msgstr "Pasirinkite odyno byl" #: ../lib/gui/dicteditorwin.py:614 msgid "Open Failed" msgstr "Nepavyko atidaryti" #: ../lib/gui/dicteditorwin.py:615 msgid "Unable to open dictionary (got message: %s)" msgstr "Nepavyko atidaryti odyno (gautas praneimas: %s)" #: ../lib/gui/dicteditorwin.py:630 msgid "Dictionary loaded" msgstr "odynas keltas" #: ../lib/gui/errorwin.py:72 msgid "An error occured:" msgstr "vyko klaida:" #: ../lib/gui/helpwin.py:69 #: ../lib/gui/helpwin.py:146 #: ../lib/gui/helpwin.py:209 msgid "&Close" msgstr "&Udaryti" #: ../lib/gui/helpwin.py:107 msgid "Written By" msgstr "Autoriai" #: ../lib/gui/helpwin.py:119 msgid "Translated By" msgstr "Vertjai" #: ../lib/gui/helpwin.py:124 msgid "" "Ports:\n" "\n" msgstr "" "Pritaikymas sistemoms:\n" "\n" #: ../lib/gui/helpwin.py:129 msgid "Thanks To" msgstr "Dkojame" #: ../lib/gui/helpwin.py:135 msgid "" "OpenDict project is sponsored by IDILES.\n" "Visit company's website at http://www.idiles.com.\n" "\n" "Report problems by email address support@idiles.com." msgstr "" "OpenDict projekt remia IDILES.\n" "Apsilankykite bendrovs interneto svetainje adresu http://www.idiles.lt.\n" "\n" "Praome praneti apie klaidas el. pato adresu support@idiles.com." #: ../lib/gui/helpwin.py:142 msgid "Sponsors" msgstr "Rmjai" #: ../lib/gui/helpwin.py:180 #: ../lib/gui/helpwin.py:193 msgid "OpenDict is a multiplatform dictionary." msgstr "OpenDict yra daugiaplatformis odynas." #: ../lib/gui/helpwin.py:203 msgid "C&redits" msgstr "&Padkos" #: ../lib/gui/helpwin.py:206 msgid "&Licence" msgstr "&Licencija" #: ../lib/gui/helpwin.py:235 msgid "Licence" msgstr "Licencija" #: ../lib/gui/mainwin.py:92 #: ../lib/gui/mainwin.py:778 #: ../lib/gui/mainwin.py:816 msgid "Stopped" msgstr "Sustabdyta" #: ../lib/gui/mainwin.py:97 #: ../lib/gui/mainwin.py:783 msgid "Encode Failed" msgstr "Nepavyko ikoduoti" #: ../lib/gui/mainwin.py:98 msgid "Unable to encode text \"%s\" in %s for \"%s\"." msgstr "Nepavyko ukoduoti teksto %s koduote %s odynui %s." #: ../lib/gui/mainwin.py:106 #: ../lib/gui/mainwin.py:761 #: ../lib/gui/mainwin.py:1361 msgid "Searching..." msgstr "Iekoma..." #: ../lib/gui/mainwin.py:159 msgid "Look Up\tCtrl-U" msgstr "Iekoti\tCtrl-U" #: ../lib/gui/mainwin.py:160 msgid "Lookup up word in the dictionary" msgstr "Iekoti odio odyne" #: ../lib/gui/mainwin.py:165 msgid "&Close Dictionary\tCtrl-W" msgstr "&Udaryti odyn\tCtrl-W" #: ../lib/gui/mainwin.py:166 msgid "Close opened dicitonary" msgstr "Udaryti aktyv odyn" #: ../lib/gui/mainwin.py:169 msgid "E&xit\tCtrl-Q" msgstr "&Ieiti\tCtrl-Q" #: ../lib/gui/mainwin.py:170 msgid "Exit program" msgstr "Baigti darb" #: ../lib/gui/mainwin.py:172 msgid "&File" msgstr "&Byla" #: ../lib/gui/mainwin.py:180 msgid "&Clear Search Entry\tCtrl-L" msgstr "Ivalyti paiekos laukel\tCtrl-L" #: ../lib/gui/mainwin.py:183 msgid "Clear History" msgstr "Ivalyti istorij" #: ../lib/gui/mainwin.py:191 msgid "Copy\tCtrl-C" msgstr "Kopijuoti\tCtrl-C" #: ../lib/gui/mainwin.py:192 msgid "Copy selected translation text" msgstr "Nukopijuoti paymt vertimo tekst" #: ../lib/gui/mainwin.py:195 msgid "Paste\tCtrl-V" msgstr "dti\tCtrl-V" #: ../lib/gui/mainwin.py:196 msgid "Paste clipboard text into the search entry" msgstr "Kopijuoti ikarpins tekst paiekos laukel" #: ../lib/gui/mainwin.py:201 msgid "Edit preferences" msgstr "Keisti nustatymus" #: ../lib/gui/mainwin.py:201 msgid "Preferences...\tCtrl-P" msgstr "Nustatymai...\tCtrl-N" #: ../lib/gui/mainwin.py:203 msgid "&Edit" msgstr "&Keisti" #: ../lib/gui/mainwin.py:213 msgid "Increase\tCtrl-=" msgstr "Padidinti\tCtrl-=" #: ../lib/gui/mainwin.py:214 msgid "Increase text size" msgstr "Padidinti tekst" #: ../lib/gui/mainwin.py:215 msgid "Decrease\tCtrl--" msgstr "Sumainti\tCtrl--" #: ../lib/gui/mainwin.py:216 msgid "Decrease text size" msgstr "Sumainti tekst" #: ../lib/gui/mainwin.py:218 msgid "Normal\tCtrl-0" msgstr "prastas\tCtrl-0" #: ../lib/gui/mainwin.py:219 msgid "Set normal text size" msgstr "Nustatyti prast teksto dyd" #: ../lib/gui/mainwin.py:220 msgid "Font Size" msgstr "rifto dydis" #: ../lib/gui/mainwin.py:235 msgid "Font Face" msgstr "riftas" #: ../lib/gui/mainwin.py:250 msgid "Character Encoding" msgstr "Simboli koduot" #: ../lib/gui/mainwin.py:255 msgid "Show/Hide Word List...\tCtrl-H" msgstr "Rodyti/slpti odi sra...\tCtrl-H" #: ../lib/gui/mainwin.py:256 msgid "Show or hide word list" msgstr "Rodyti arba paslpti odi sra" #: ../lib/gui/mainwin.py:259 msgid "&View" msgstr "&Perira" #: ../lib/gui/mainwin.py:300 msgid "&Install Dictionary From File..." msgstr "&diegti odyn i bylos..." #: ../lib/gui/mainwin.py:302 msgid "&Dictionaries" msgstr "o&dynai" #: ../lib/gui/mainwin.py:311 msgid "Manage Dictionaries...\tCtrl-M" msgstr "Tvarkyti odynus...\tCtrl-M" #: ../lib/gui/mainwin.py:312 msgid "Install or remove dictionaries" msgstr "diegti arba paalinti odynus" #: ../lib/gui/mainwin.py:314 msgid "Create Dictionaries..." msgstr "Kurti odynus..." #: ../lib/gui/mainwin.py:315 msgid "Create and edit dictionaries" msgstr "Sukurti ir taisyti odynus" #: ../lib/gui/mainwin.py:322 msgid "Take Words From Clipboard" msgstr "Imti odius i ikarpins" #: ../lib/gui/mainwin.py:323 msgid "Scan the clipboard for text to translate" msgstr "Imti odius i ikarpins" #: ../lib/gui/mainwin.py:331 msgid "Connect to DICT Server..." msgstr "Prisijungti prie DICT serverio..." #: ../lib/gui/mainwin.py:332 msgid "Open connection to DICT server" msgstr "Prisijungti prie DICT serverio" #: ../lib/gui/mainwin.py:337 msgid "Pronounce\tCtrl-E" msgstr "Itarti balsu\tCtrl-E" #: ../lib/gui/mainwin.py:338 msgid "Pronounce word" msgstr "Itarti od balsu" #: ../lib/gui/mainwin.py:341 msgid "Tools" msgstr "rankiai" #: ../lib/gui/mainwin.py:350 msgid "&About\tCtrl-A" msgstr "&Apie\tCtrl-A" #: ../lib/gui/mainwin.py:352 msgid "&Help" msgstr "&Pagalba" #: ../lib/gui/mainwin.py:357 msgid "Word:" msgstr "odis: " #: ../lib/gui/mainwin.py:362 msgid "Enter some text and press \"Look Up\" button or [ENTER] key on your keyboard" msgstr "veskite tekst ir spauskite mygtuk Iekoti arba [ENTER] klavi savo klaviatroje " #: ../lib/gui/mainwin.py:368 msgid "Look Up" msgstr "Iekoti" #: ../lib/gui/mainwin.py:369 msgid "Click this button to look up word in the dictionary" msgstr "Paspauskite mygtuk odio paiekai odyne" #: ../lib/gui/mainwin.py:380 msgid "History Back" msgstr "Atgal" #: ../lib/gui/mainwin.py:389 msgid "History Forward" msgstr "Pirmyn" #: ../lib/gui/mainwin.py:399 msgid "Stop searching" msgstr "Sustabdyti paiek" #: ../lib/gui/mainwin.py:423 msgid "Translation" msgstr "Vertimas" #: ../lib/gui/mainwin.py:531 msgid "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Welcome to OpenDict

    \n" "

    Short usage information:

    \n" "
      \n" "
    • To start using dictionary, select one from Dictionaries\n" " menu.\n" "
    • \n" "
    • To install new dictionary from the Internet, select\n" " Manage Dictionaries\n" " from Tools menu and choose Available tab.
    • \n" "
    • To install new dictionary from file, select Install Dictionary From File...\n" " from Dictionaries menu.\n" "
    • \n" "
    \n" "\n" "\n" msgstr "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Malonaus naudojimosi odyn programa OpenDict

    \n" "

    Trumpa naudojimo instrukcija:

    \n" "
      \n" "
    • Nordami pradti naudotis odynu, pasirinkite tinkam i odynai\n" " meniu.\n" "
    • \n" "
    • Nordami diegti nauj odyn i Interneto, pasirinkite\n" " Tvarkyti odynus\n" " i rankiai meniu, tada pasirinkite Galimi kortel.
    • \n" "
    • Nordami diegti nauj odyn i bylos, pasirinkite diegti odyn i bylos...\n" " i odynai meniu.\n" "
    • \n" "
    \n" "\n" "\n" #: ../lib/gui/mainwin.py:653 msgid "Translation cannot be displayed using selected encoding %s. Please try another encoding from View > Character Encoding menu." msgstr "Pasirinkta koduot nra tinkama iam odynui. Pasirinkite kit koduot i meniu Keisti > Teksto koduot" #: ../lib/gui/mainwin.py:685 msgid "1 word matches" msgstr "Atitikmen skaiius: 1" #: ../lib/gui/mainwin.py:687 msgid "%d words match" msgstr "Atitikmen skaiius: %d" #: ../lib/gui/mainwin.py:734 msgid "No dictionary activated" msgstr "Neaktyvuotas joks odynas" #: ../lib/gui/mainwin.py:735 msgid "No dictionary activated. Please select one from \"Dictionaries\" menu and try again." msgstr "Neaktyvuotas joks odynas. Pasirinkite odyn i odynai meniu ir bandykite dar kart." #: ../lib/gui/mainwin.py:738 msgid "No dictionaries installed" msgstr "Nra diegt odyn" #: ../lib/gui/mainwin.py:739 msgid "There is no dictionaries installed. You can install one by selecting Tools > Manage Dictionaries > Available" msgstr "Nra diegt odyn. diegti galite i meniu pasirinkdami rankiai > Tvarkyti odynus > Galimi" #: ../lib/gui/mainwin.py:752 msgid "Please enter some text and try again" msgstr "veskite tekst ir bandykite dar kart" #: ../lib/gui/mainwin.py:784 msgid "Unable to encode text \"%s\" in %s for \"%s\". That logically means the word definition does not exist in the dictionary." msgstr "Nepavyko ukoduoti teksto %s koduote %s. Tai gali reikti, jog iekomo odio odyne visai nra." #: ../lib/gui/mainwin.py:872 msgid "Connect to DICT server" msgstr "Prisijungti prie DICT serverio" #: ../lib/gui/mainwin.py:899 msgid "Choose a dictionary from \"Dictionaries\" menu" msgstr "Isirinkite odyn i odynai meniu" #: ../lib/gui/mainwin.py:920 msgid "Failed to copy text from the clipboard" msgstr "Nepavyko paimti teksto i ikarpins" #: ../lib/gui/mainwin.py:922 msgid "Clipboard contains no text data" msgstr "Ikarpinje teksto nra" #: ../lib/gui/mainwin.py:946 #: ../lib/gui/mainwin.py:1142 #: ../lib/gui/pluginwin.py:772 msgid "Error" msgstr "Klaida" #: ../lib/gui/mainwin.py:955 msgid "Groups" msgstr "Grups" #: ../lib/gui/mainwin.py:967 msgid "Manage Dictionaries" msgstr "Tvarkyti odynus" #: ../lib/gui/mainwin.py:981 msgid "File Register" msgstr "Byl registras" #: ../lib/gui/mainwin.py:989 msgid "Create Dictionaries" msgstr "Kurti odynus" #: ../lib/gui/mainwin.py:998 msgid "Preferences" msgstr "Nustatymai" #: ../lib/gui/mainwin.py:1088 msgid "Licence Agreement Rejected" msgstr "Licencija atmesta" #: ../lib/gui/mainwin.py:1089 msgid "You cannot use dictionary \"%s\" without accepting licence agreement" msgstr "Js negalite naudotis odynu %s, jei nesutinkate su licencijos slygomis" #: ../lib/gui/mainwin.py:1103 msgid "Dictionary Index" msgstr "odyno indeksas" #: ../lib/gui/mainwin.py:1104 msgid "" "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..." msgstr "" "is odynas naudojamas pirm kart arba buvo pakeistas po paskutinio indeksavimo. Indeksavimas naudojamas odi paiekai odyne pagreitinti. Dabar odynas bus perindeksuotas. Tai gali utrukti kelet sekudi.\n" "\n" "Nordami pratsti, spauskite Gerai..." #: ../lib/gui/mainwin.py:1121 msgid "Index Creation Error" msgstr "Indeksavimo klaida" #: ../lib/gui/mainwin.py:1122 msgid "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" msgstr "Indeksuojant odyn vyko klaida. Tai galjo vykti dl pasirinktos netinkamos iam odynui teksto koduots %s. Pabandykite pasirinkti kit koduot i meniu Perira > Teksto koduot." #: ../lib/gui/mainwin.py:1143 msgid "Unable to load dictionary index table. Got error: %s" msgstr "Nepavyko pakrauti odyno indeks lentels. Gauta klaida: %s" #: ../lib/gui/mainwin.py:1153 msgid "Dictionary \"%s\" loaded" msgstr "keltas odynas %s" #: ../lib/gui/mainwin.py:1205 msgid "Error: not supported dictionary type" msgstr "Klaida: nepalaikomas odyno formatas" #: ../lib/gui/mainwin.py:1310 msgid "" "Select dictionary format. If you can't find\n" "the format of your dictionary, the register\n" "system does not support it yet." msgstr "" "Pasirinkite odyno format. Jei reikiamo\n" "formato srae nra, registr sistema kol\n" "kas jo nepalaiko." #: ../lib/gui/mainwin.py:1315 msgid "Dictionary format" msgstr "odyno formatas" #: ../lib/gui/mainwin.py:1332 msgid "Choose plugin file" msgstr "Pasirinkite priedo byl" #: ../lib/gui/mainwin.py:1348 msgid "About" msgstr "Apie" #: ../lib/gui/mainwin.py:1399 msgid "Show word list" msgstr "Rodyti odi sra" #: ../lib/gui/mainwin.py:1416 msgid "Hide word list" msgstr "Paslpti odi sra" #: ../lib/gui/mainwin.py:1425 msgid "Failed to print" msgstr "Nepavyko atspausdinti" #: ../lib/gui/mainwin.py:1437 msgid "Page preview failed" msgstr "Puslapio perira nepavyko" #: ../lib/gui/miscwin.py:53 msgid "Error: unable to show licence text" msgstr "Klaida: nepavyko parodyti licencijos teksto" #: ../lib/gui/miscwin.py:59 msgid "Do not accept" msgstr "Nesutinku" #: ../lib/gui/miscwin.py:62 msgid "Accept" msgstr "Sutinku" #: ../lib/gui/miscwin.py:76 msgid "Licence Agreement" msgstr "Licencija" #: ../lib/gui/miscwin.py:103 msgid "" "You have directories that containt invalid dictionaries and cannot be loaded. \n" "You can try to remove these directories right now." msgstr "" "Pas jus yra katalog su blogais odynais, kurie negali bti krauti. \n" "Galite pabandyti tuojau pat paalinti tuos katalogus." #: ../lib/gui/miscwin.py:142 #: ../lib/gui/pluginwin.py:644 msgid "Unable to remove" msgstr "Nepavyko paalinti" #: ../lib/gui/miscwin.py:143 msgid "Unable to remove directory \"%s\": %s" msgstr "Nepavyko paalinti katalogo %s: %s" #: ../lib/gui/miscwin.py:151 msgid "Invalid Dictionaries" msgstr "Sugadinti odynai" #: ../lib/gui/pluginwin.py:78 msgid "Installed" msgstr "diegti" #: ../lib/gui/pluginwin.py:82 msgid "Available" msgstr "Galimi" #: ../lib/gui/pluginwin.py:124 msgid "" "Checked dictionaries are available from the menu, unchecked dictionaries \n" "are not available from the menu." msgstr "" "Paymti odynai prieinami i meniu, nepaymti odynai nra prieinami \n" "i meniu." #: ../lib/gui/pluginwin.py:149 msgid "Install From File" msgstr "diegti i bylos..." #: ../lib/gui/pluginwin.py:208 msgid "Update List" msgstr "Atnaujinti sra" #: ../lib/gui/pluginwin.py:215 msgid "Install" msgstr "diegti" #: ../lib/gui/pluginwin.py:227 msgid "Name" msgstr "Pavadinimas" #: ../lib/gui/pluginwin.py:228 msgid "Size" msgstr "Dydis" #: ../lib/gui/pluginwin.py:274 msgid "Information About Dictionary" msgstr "Informacija apie odyn" #: ../lib/gui/pluginwin.py:288 msgid "Name: " msgstr "Pavadinimas:" #: ../lib/gui/pluginwin.py:293 msgid "Version: " msgstr "Versija:" #: ../lib/gui/pluginwin.py:298 msgid "Maintainer: " msgstr "Priirtojas:" #: ../lib/gui/pluginwin.py:515 msgid "List updated" msgstr "Sraas atnaujintas" #: ../lib/gui/pluginwin.py:516 msgid "All your dictionaries are up to date." msgstr "Js turimi odynai yra patys naujausi." #: ../lib/gui/pluginwin.py:523 msgid "Downloading List" msgstr "Parsiuniamas sraas" #: ../lib/gui/pluginwin.py:558 msgid "Unable to download list from %s: %s" msgstr "Nepavyko parsisti odyn srao i %s: %s" #: ../lib/gui/pluginwin.py:566 msgid "Unable to download list" msgstr "Nepavyko parsisti srao" #: ../lib/gui/pluginwin.py:645 msgid "Unable to remove dictionary \"%s\"" msgstr "Nepavyko paalinti odyno %s" #: ../lib/gui/pluginwin.py:686 msgid "Downloading %s..." msgstr "Parsiuniamas %s..." #: ../lib/gui/pluginwin.py:743 msgid "Unable to download" msgstr "Nepavyko parsisti" #: ../lib/gui/pluginwin.py:753 msgid "File is damaged" msgstr "Byla yra sugadinta" #: ../lib/gui/pluginwin.py:754 msgid "Downloaded file is damaged and cannot be installed. Please try again." msgstr "Parsista byla yra sugadinta ir negali bti diegta. Bandykite dar kart." #: ../lib/gui/pluginwin.py:773 msgid "Unable to remove old version of \"%s\". Error occured: \"%s\". New version cannot be installed without removing old one." msgstr "Nepavyko imesti senos %s versijos. vyko klaida: %s. Nauja versija negali bti instaliuota tol, kol nebus imesta sena." #: ../lib/gui/pluginwin.py:798 msgid "Unable to install" msgstr "Nepavyko diegti" #: ../lib/gui/pluginwin.py:799 msgid "Unable to install dictionary \"%s\"." msgstr "Nepavyko diegti odyno %s." #: ../lib/gui/prefswin.py:48 msgid "Default dictionary: " msgstr "Numatytas odynas:" #: ../lib/gui/prefswin.py:69 msgid "Default encoding: " msgstr "Numatyta koduot: " #: ../lib/gui/prefswin.py:80 msgid "Default DICT server: " msgstr "Numatytas DICT serveris:" #: ../lib/gui/prefswin.py:86 msgid "Default DICT server port: " msgstr "Numatytas DICT serverio prievadas:" #: ../lib/gui/prefswin.py:99 msgid "Pronunciation" msgstr "Tarimas" #: ../lib/gui/prefswin.py:107 msgid "System Command: " msgstr "Sistemos komanda: " #: ../lib/gui/prefswin.py:115 msgid "Default" msgstr "Numatyta" #: ../lib/gui/prefswin.py:121 msgid "Pronounce original word" msgstr "Itarti original od" #: ../lib/gui/prefswin.py:123 msgid "Pronounce translation" msgstr "Itarti vertim" #: ../lib/gui/prefswin.py:130 msgid "Save window size on exit" msgstr "Ieinant isaugoti lango dyd" #: ../lib/gui/prefswin.py:134 msgid "Save window position on exit" msgstr "Ieinant isaugoti lango pozicij" #: ../lib/gui/prefswin.py:138 msgid "Save sash position on exit" msgstr "Ieinant isaugoti skyriklio pozicij" #: ../lib/gui/prefswin.py:143 msgid "Take words from the clipboard by default" msgstr "Visada imti odius i ikarpins" #: ../lib/gui/registerwin.py:66 #: ../lib/gui/registerwin.py:105 #: ../lib/gui/registerwin.py:148 msgid "Name: %s" msgstr "Pavadinimas: %s" #: ../lib/gui/registerwin.py:69 #: ../lib/gui/registerwin.py:106 #: ../lib/gui/registerwin.py:149 msgid "Path: %s" msgstr "Kelias: %s" #: ../lib/gui/registerwin.py:72 #: ../lib/gui/registerwin.py:107 #: ../lib/gui/registerwin.py:150 msgid "Format: %s" msgstr "Formatas: %s" #: ../lib/gui/registerwin.py:75 #: ../lib/gui/registerwin.py:108 #: ../lib/gui/registerwin.py:151 msgid "Encoding: %s" msgstr "Koduot: %s" #: ../lib/gui/registerwin.py:82 msgid "Add new..." msgstr "Pridti nauj..." #: ../lib/gui/registerwin.py:86 msgid "Remove selected" msgstr "Paalinti paymt" #: ../lib/gui/registerwin.py:130 #: ../lib/gui/registerwin.py:137 msgid "Error while deleting \"%s\"" msgstr "Klaida paalinant %s" #: ../lib/installer.py:81 msgid "Recognition Error" msgstr "Atpainimo klaida" #: ../lib/installer.py:82 msgid "File %s is not supported by OpenDict" msgstr "Byla %s nra tinkama programai OpenDict" #: ../lib/installer.py:108 #: ../lib/installer.py:110 msgid "Installation failed" msgstr "Nepavyko diegti" #: ../lib/installer.py:122 #: ../lib/installer.py:308 #: ../lib/installer.py:316 msgid "Installation Error" msgstr "Diegimo klaida" #: ../lib/installer.py:124 #: ../lib/installer.py:128 msgid "Error: Installation failed" msgstr "Klaida: nepavyko diegti" #: ../lib/installer.py:132 msgid "Dictionary installed" msgstr "odynas diegtas" #: ../lib/installer.py:133 msgid "Dictionary successfully installed. You can choose it from \"Dictionaries\" menu now." msgstr "odynas skmingai diegtas. Dabar j galite pasirinkti i odynai meniu." #: ../lib/installer.py:143 #: ../lib/installer.py:218 msgid "File %s does not exist" msgstr "Byla %s neegzistuoja" #: ../lib/installer.py:146 #: ../lib/installer.py:222 msgid "%s is not a file" msgstr "%s nra byla" #: ../lib/installer.py:160 msgid "Dictionary \"%s\" is already installed" msgstr "odynas %s jau diegtas" #: ../lib/installer.py:226 msgid "%s is not OpenDict dictionary plugin" msgstr "%s nra OpenDict skiepis" #: ../lib/installer.py:233 msgid "File \"%s\" is not valid ZIP file" msgstr "%s nra teisinga ZIP byla" #: ../lib/installer.py:238 msgid "Dictionary plugin file is corrupted" msgstr "skiepio byla yra sugadinta" #: ../lib/installer.py:244 msgid "Plugin file is empty (%s)" msgstr "skiepio byla tuia (%s)" #: ../lib/installer.py:268 msgid "Selected file is not valid OpenDict plugin" msgstr "Nurodyta byla nra teisingas OpenDict skiepis" #: ../lib/installer.py:295 #: ../lib/installer.py:377 msgid "This dictionary already installed. If you want to upgrade it, please remove old version first." msgstr "is odynas jau diegtas. Nordami atnaujinti, pirma paalinkite senj versij." #: ../lib/installer.py:309 #: ../lib/installer.py:317 msgid "Installation tool for this dictionary failed to start. Please report this problem to developers." msgstr "iam odynui diegimo rankio paleisti nepavyko. Praome apie problem praneti krjams.??" #: ../lib/installer.py:323 msgid "Installation Aborted" msgstr "Diegimas nutrauktas" #: ../lib/installer.py:324 msgid "Dictionary installation has been aborted." msgstr "odyno diegimas nutrauktas." #: ../lib/installer.py:348 #: ../lib/installer.py:400 msgid "Error while removing created directories after plugin installation failure. This may be permission or disk space error." msgstr "Po neskms diegiant skiepius nepavyko paalinti sukurt katalog. Klaida gali bti susijusi su bylos leidimais." #: ../lib/installer.py:352 msgid "Unable to install plugin" msgstr "Nepavyko diegti priedo " #: ../lib/installer.py:369 msgid "Compressed dictionary file is corrupted" msgstr "Suspausta odyno byla yra sugadinta" #: ../lib/installer.py:404 msgid "Unable to install dictionary" msgstr "Nepavyksta diegti odyno" #: ../lib/misc.py:37 msgid "Dictionary error, please report to its author" msgstr "odyno klaida, praome praneti apie tai jo autoriui" #: ../lib/misc.py:38 msgid "Syntax error" msgstr "Sintakss klaida" #: ../lib/misc.py:39 msgid "You must be connected to the internet to use this dictionary" msgstr "Turite bti prisijung prie interneto, kad galtumte naudoti odyn" #: ../lib/misc.py:40 msgid "Time out" msgstr "Baigsi prisijungimo laikas" #: ../lib/misc.py:41 msgid "Bad encoding is set for this dictionary, try another" msgstr "iam odynui nustatyta neteisinga koduot, pasirinkite kit" #: ../lib/misc.py:48 msgid "Unicode (UTF-8)" msgstr "Unikodas (UTF-8)" #: ../lib/misc.py:49 msgid "Western (ISO-8859-1)" msgstr "Vakar (ISO-8859-1)" #: ../lib/misc.py:50 msgid "Central European (ISO-8859-2)" msgstr "Centrins Europos (ISO-8859-2)" #: ../lib/misc.py:51 msgid "Nordic (ISO-8859-10)" msgstr "iaurs (ISO-8859-10)" #: ../lib/misc.py:52 msgid "South European (ISO-8859-3)" msgstr "Piet Europos (ISO-8859-3)" #: ../lib/misc.py:53 msgid "Greek (ISO-8859-7)" msgstr "Graik (ISO-8859-7)" #: ../lib/misc.py:54 msgid "Baltic (ISO-8859-13)" msgstr "Balt (ISO-8859-13)" #: ../lib/misc.py:55 msgid "Cyrillic (KOI8-R)" msgstr "Kirilica (KOI8-R)" #: ../lib/misc.py:56 msgid "Arabic (ISO-8859-6)" msgstr "Arab (ISO-8859-6)" #: ../lib/util.py:235 msgid "Downloading... %d%%" msgstr "Parsiuniama... %d%%" #: ../opendict.py:115 msgid "wxPython Version Error" msgstr "wxPython versijos klaida" #: ../opendict.py:116 msgid "" "wxPython %s is installed on this system.\n" "\n" "OpenDict %s requires wxPython 2.6 to run smoothly.\n" "\n" "You can find wxPython 2.6 at http://www.wxpython.org or you can install it using your system package manager." msgstr "" "ioje sistemoje yra suinstaliuota wxPython %s biblioteka.\n" "\n" "Kad gerai veikt, OpenDict %s reikalauja wxPython 2.6.\n" "\n" "Galite rasti wxPython 2.6 adresu http://www.python.org arba galite suinstaliuoti j naudodami savo sistemos paket tvarkymo program." #~ msgid "" #~ "Debian/Ubuntu port:\n" #~ " Kęstutis BiliĆ…Ā«nas \n" #~ "\n" #~ "MacOS X port:\n" #~ " Linas Valiukas " #~ msgstr "" #~ "Debian/Ubuntu versija:\n" #~ " Kęstutis BiliÅ«nas \n" #~ "\n" #~ "MacOS X versija:\n" #~ " Linas Valiukas " #~ msgid "&License" #~ msgstr "Licencija" #, fuzzy #~ msgid "Fixed" #~ msgstr "&Byla" #, fuzzy #~ msgid "Times" #~ msgstr "Baigėsi prisijungimo laikas" #~ msgid "Edit Dictionaries" #~ msgstr "Taisyti žodynus" opendict-0.6.8/po/opendict.pot0000664000076400007640000005767013204646653016263 0ustar nerijusnerijus# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-04-12 20:34+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../opendict.py:106 msgid "wxPython Version Error" msgstr "" #: ../opendict.py:107 #, python-format msgid "" "wxPython %s is installed on this system.\n" "\n" "OpenDict %s requires wxPython 2.6 to run smoothly.\n" "\n" "You can find wxPython 2.6 at http://www.wxpython.org or you can install it " "using your system package manager." msgstr "" #: ../lib/errortype.py:57 msgid "Success" msgstr "" #: ../lib/errortype.py:58 msgid "Search successfully finished." msgstr "" #: ../lib/errortype.py:65 ../lib/misc.py:36 msgid "Not found" msgstr "" #: ../lib/errortype.py:66 msgid "Word or phrase not found. Try less letters or fewer words." msgstr "" #: ../lib/errortype.py:74 msgid "Internal error" msgstr "" #: ../lib/errortype.py:75 msgid "" "Internal error occured. Please send bug report to the dictionary's of " "current use authors. Thank you." msgstr "" #: ../lib/errortype.py:83 msgid "Not connected" msgstr "" #: ../lib/errortype.py:84 msgid "" "This dictionary uses Internet connection to translate words. Please connect " "to the Internet and try again." msgstr "" #: ../lib/errortype.py:93 ../lib/gui/dictconnwin.py:183 #: ../lib/gui/dictconnwin.py:199 msgid "Connection Error" msgstr "" #: ../lib/errortype.py:94 msgid "Could not connect to host. Check your Internet connection or try later." msgstr "" #: ../lib/errortype.py:102 msgid "Invalid encoding" msgstr "" #: ../lib/errortype.py:103 msgid "" "Selected encoding is not correct for this dictionary. Please select another " "from Edit > Character Encoding menu" msgstr "" #: ../lib/errortype.py:112 msgid "OpenDict Bug" msgstr "" #: ../lib/errortype.py:113 msgid "" "Internal error occured. Please send bug report to OpenDict authors to " "prevent this error in the future. Thank you!" msgstr "" #: ../lib/errortype.py:121 msgid "Unknown Error" msgstr "" #: ../lib/errortype.py:122 msgid "Unknown error occured." msgstr "" #: ../lib/installer.py:61 ../lib/gui/dicteditorwin.py:600 #: ../lib/gui/mainwin.py:1299 msgid "Choose dictionary file" msgstr "" #: ../lib/installer.py:81 msgid "Recognition Error" msgstr "" #: ../lib/installer.py:82 #, python-format msgid "File %s is not supported by OpenDict" msgstr "" #: ../lib/installer.py:108 ../lib/installer.py:110 msgid "Installation failed" msgstr "" #: ../lib/installer.py:122 ../lib/installer.py:308 ../lib/installer.py:316 msgid "Installation Error" msgstr "" #: ../lib/installer.py:124 ../lib/installer.py:128 msgid "Error: Installation failed" msgstr "" #: ../lib/installer.py:132 msgid "Dictionary installed" msgstr "" #: ../lib/installer.py:133 msgid "" "Dictionary successfully installed. You can choose it from \"Dictionaries\" " "menu now." msgstr "" #: ../lib/installer.py:143 ../lib/installer.py:218 #, python-format msgid "File %s does not exist" msgstr "" #: ../lib/installer.py:146 ../lib/installer.py:222 #, python-format msgid "%s is not a file" msgstr "" #: ../lib/installer.py:160 #, python-format msgid "Dictionary \"%s\" is already installed" msgstr "" #: ../lib/installer.py:226 #, python-format msgid "%s is not OpenDict dictionary plugin" msgstr "" #: ../lib/installer.py:233 #, python-format msgid "File \"%s\" is not valid ZIP file" msgstr "" #: ../lib/installer.py:238 msgid "Dictionary plugin file is corrupted" msgstr "" #: ../lib/installer.py:244 #, python-format msgid "Plugin file is empty (%s)" msgstr "" #: ../lib/installer.py:268 msgid "Selected file is not valid OpenDict plugin" msgstr "" #: ../lib/installer.py:295 ../lib/installer.py:377 msgid "" "This dictionary already installed. If you want to upgrade it, please remove " "old version first." msgstr "" #: ../lib/installer.py:309 ../lib/installer.py:317 msgid "" "Installation tool for this dictionary failed to start. Please report this " "problem to developers." msgstr "" #: ../lib/installer.py:323 msgid "Installation Aborted" msgstr "" #: ../lib/installer.py:324 msgid "Dictionary installation has been aborted." msgstr "" #: ../lib/installer.py:348 ../lib/installer.py:400 msgid "" "Error while removing created directories after plugin installation failure. " "This may be permission or disk space error." msgstr "" #: ../lib/installer.py:352 msgid "Unable to install plugin" msgstr "" #: ../lib/installer.py:369 msgid "Compressed dictionary file is corrupted" msgstr "" #: ../lib/installer.py:404 msgid "Unable to install dictionary" msgstr "" #: ../lib/misc.py:37 msgid "Dictionary error, please report to its author" msgstr "" #: ../lib/misc.py:38 msgid "Syntax error" msgstr "" #: ../lib/misc.py:39 msgid "You must be connected to the internet to use this dictionary" msgstr "" #: ../lib/misc.py:40 msgid "Time out" msgstr "" #: ../lib/misc.py:41 msgid "Bad encoding is set for this dictionary, try another" msgstr "" #: ../lib/misc.py:48 msgid "Unicode (UTF-8)" msgstr "" #: ../lib/misc.py:49 msgid "Western (ISO-8859-1)" msgstr "" #: ../lib/misc.py:50 msgid "Central European (ISO-8859-2)" msgstr "" #: ../lib/misc.py:51 msgid "Nordic (ISO-8859-10)" msgstr "" #: ../lib/misc.py:52 msgid "South European (ISO-8859-3)" msgstr "" #: ../lib/misc.py:53 msgid "Greek (ISO-8859-7)" msgstr "" #: ../lib/misc.py:54 msgid "Baltic (ISO-8859-13)" msgstr "" #: ../lib/misc.py:55 msgid "Cyrillic (KOI8-R)" msgstr "" #: ../lib/misc.py:56 msgid "Arabic (ISO-8859-6)" msgstr "" #: ../lib/util.py:219 ../lib/gui/dictconnwin.py:254 #, python-format msgid "Connecting to %s..." msgstr "" #: ../lib/util.py:235 #, python-format msgid "Downloading... %d%%" msgstr "" #: ../lib/util.py:240 ../lib/gui/dictconnwin.py:174 ../lib/gui/mainwin.py:689 msgid "Done" msgstr "" #: ../lib/gui/dictaddwin.py:35 msgid "Add new dictionary" msgstr "" #: ../lib/gui/dictaddwin.py:41 #, python-format msgid "" "The file format of \"%s\" could not be \n" "recognized by its extention. Please select one\n" "from the list:" msgstr "" #: ../lib/gui/dictaddwin.py:47 ../lib/gui/dictaddwin.py:48 #: ../lib/gui/dictaddwin.py:49 ../lib/gui/dictaddwin.py:50 #, python-format msgid "\"%s\" dictionary format" msgstr "" #: ../lib/gui/dictaddwin.py:59 ../lib/gui/dicteditorwin.py:91 #: ../lib/gui/prefswin.py:149 msgid "OK" msgstr "" #: ../lib/gui/dictaddwin.py:62 ../lib/gui/dictconnwin.py:133 #: ../lib/gui/dicteditorwin.py:94 ../lib/gui/dicteditorwin.py:255 #: ../lib/gui/prefswin.py:152 msgid "Cancel" msgstr "" #: ../lib/gui/dictconnwin.py:55 msgid "Server: " msgstr "" #: ../lib/gui/dictconnwin.py:64 msgid "Default Server" msgstr "" #: ../lib/gui/dictconnwin.py:70 msgid "Port: " msgstr "" #: ../lib/gui/dictconnwin.py:73 msgid "Default Port" msgstr "" #: ../lib/gui/dictconnwin.py:83 msgid "Database: " msgstr "" #: ../lib/gui/dictconnwin.py:87 msgid "Search in all databases" msgstr "" #: ../lib/gui/dictconnwin.py:94 msgid "Fetch List" msgstr "" #: ../lib/gui/dictconnwin.py:100 msgid "Character encoding: " msgstr "" #: ../lib/gui/dictconnwin.py:130 msgid "Connect" msgstr "" #: ../lib/gui/dictconnwin.py:178 msgid "Receiving database list..." msgstr "" #: ../lib/gui/dictconnwin.py:184 ../lib/gui/dictconnwin.py:200 msgid "Unable to connect to server" msgstr "" #: ../lib/gui/dictconnwin.py:218 msgid "Connecting..." msgstr "" #: ../lib/gui/dicteditorwin.py:53 msgid "Word: " msgstr "" #: ../lib/gui/dicteditorwin.py:88 msgid "Add translation field" msgstr "" #: ../lib/gui/dicteditorwin.py:111 #, python-format msgid "Translation #%d: " msgstr "" #: ../lib/gui/dicteditorwin.py:245 #, python-format msgid "Dictionary \"%s\" has been changed" msgstr "" #: ../lib/gui/dicteditorwin.py:249 ../lib/gui/dicteditorwin.py:337 msgid "Save" msgstr "" #: ../lib/gui/dicteditorwin.py:252 msgid "Do not save" msgstr "" #: ../lib/gui/dicteditorwin.py:305 msgid "Dictionary editor" msgstr "" #: ../lib/gui/dicteditorwin.py:321 msgid "Add" msgstr "" #: ../lib/gui/dicteditorwin.py:322 msgid "Add word" msgstr "" #: ../lib/gui/dicteditorwin.py:325 msgid "Edit" msgstr "" #: ../lib/gui/dicteditorwin.py:326 msgid "Change translation" msgstr "" #: ../lib/gui/dicteditorwin.py:329 ../lib/gui/miscwin.py:116 #: ../lib/gui/pluginwin.py:156 msgid "Remove" msgstr "" #: ../lib/gui/dicteditorwin.py:330 msgid "Remove selected word" msgstr "" #: ../lib/gui/dicteditorwin.py:333 msgid "Sort" msgstr "" #: ../lib/gui/dicteditorwin.py:334 msgid "Sort word list" msgstr "" #: ../lib/gui/dicteditorwin.py:338 msgid "Save words to file" msgstr "" #: ../lib/gui/dicteditorwin.py:341 msgid "Save As..." msgstr "" #: ../lib/gui/dicteditorwin.py:342 msgid "Save with a different file name" msgstr "" #: ../lib/gui/dicteditorwin.py:351 ../lib/gui/mainwin.py:1377 msgid "Word List" msgstr "" #: ../lib/gui/dicteditorwin.py:370 msgid "New..." msgstr "" #: ../lib/gui/dicteditorwin.py:371 msgid "Start new dictionary" msgstr "" #: ../lib/gui/dicteditorwin.py:374 msgid "Open..." msgstr "" #: ../lib/gui/dicteditorwin.py:375 msgid "Open dictionary file" msgstr "" #: ../lib/gui/dicteditorwin.py:378 ../lib/gui/errorwin.py:84 #: ../lib/gui/miscwin.py:65 ../lib/gui/miscwin.py:124 #: ../lib/gui/pluginwin.py:92 ../lib/gui/registerwin.py:89 msgid "Close" msgstr "" #: ../lib/gui/dicteditorwin.py:379 msgid "Close editor window" msgstr "" #: ../lib/gui/dicteditorwin.py:410 msgid "New Word" msgstr "" #: ../lib/gui/dicteditorwin.py:425 msgid "Edit Word" msgstr "" #: ../lib/gui/dicteditorwin.py:457 msgid "List is empty" msgstr "" #: ../lib/gui/dicteditorwin.py:463 msgid "List sorted" msgstr "" #: ../lib/gui/dicteditorwin.py:486 msgid "Save file" msgstr "" #: ../lib/gui/dicteditorwin.py:507 msgid "Dictionary saved" msgstr "" #: ../lib/gui/dicteditorwin.py:517 msgid "Untitled" msgstr "" #: ../lib/gui/dicteditorwin.py:588 ../lib/gui/dicteditorwin.py:645 msgid "Exit confirmation" msgstr "" #: ../lib/gui/dicteditorwin.py:614 msgid "Open Failed" msgstr "" #: ../lib/gui/dicteditorwin.py:615 #, python-format msgid "Unable to open dictionary (got message: %s)" msgstr "" #: ../lib/gui/dicteditorwin.py:630 msgid "Dictionary loaded" msgstr "" #: ../lib/gui/errorwin.py:72 msgid "An error occured:" msgstr "" #: ../lib/gui/helpwin.py:69 ../lib/gui/helpwin.py:145 #: ../lib/gui/helpwin.py:208 msgid "&Close" msgstr "" #: ../lib/gui/helpwin.py:107 msgid "Written By" msgstr "" #: ../lib/gui/helpwin.py:119 msgid "Translated By" msgstr "" #: ../lib/gui/helpwin.py:124 msgid "" "Ports:\n" "\n" msgstr "" #: ../lib/gui/helpwin.py:129 msgid "Thanks To" msgstr "" #: ../lib/gui/helpwin.py:135 msgid "" "OpenDict project was sponsored by IDILES.\n" "Visit company's website at http://www.idiles.com." msgstr "" #: ../lib/gui/helpwin.py:141 msgid "Sponsors" msgstr "" #: ../lib/gui/helpwin.py:179 ../lib/gui/helpwin.py:192 msgid "OpenDict is a multiplatform dictionary." msgstr "" #: ../lib/gui/helpwin.py:202 msgid "C&redits" msgstr "" #: ../lib/gui/helpwin.py:205 msgid "&Licence" msgstr "" #: ../lib/gui/helpwin.py:234 msgid "Licence" msgstr "" #: ../lib/gui/mainwin.py:92 ../lib/gui/mainwin.py:778 #: ../lib/gui/mainwin.py:816 msgid "Stopped" msgstr "" #: ../lib/gui/mainwin.py:97 ../lib/gui/mainwin.py:783 msgid "Encode Failed" msgstr "" #: ../lib/gui/mainwin.py:98 #, python-format msgid "Unable to encode text \"%s\" in %s for \"%s\"." msgstr "" #: ../lib/gui/mainwin.py:106 ../lib/gui/mainwin.py:761 #: ../lib/gui/mainwin.py:1361 msgid "Searching..." msgstr "" #: ../lib/gui/mainwin.py:159 msgid "Look Up\tCtrl-U" msgstr "" #: ../lib/gui/mainwin.py:160 msgid "Lookup up word in the dictionary" msgstr "" #: ../lib/gui/mainwin.py:165 msgid "&Close Dictionary\tCtrl-W" msgstr "" #: ../lib/gui/mainwin.py:166 msgid "Close opened dicitonary" msgstr "" #: ../lib/gui/mainwin.py:169 msgid "E&xit\tCtrl-Q" msgstr "" #: ../lib/gui/mainwin.py:170 msgid "Exit program" msgstr "" #: ../lib/gui/mainwin.py:172 msgid "&File" msgstr "" #: ../lib/gui/mainwin.py:180 msgid "&Clear Search Entry\tCtrl-L" msgstr "" #: ../lib/gui/mainwin.py:183 msgid "Clear History" msgstr "" #: ../lib/gui/mainwin.py:191 msgid "Copy\tCtrl-C" msgstr "" #: ../lib/gui/mainwin.py:192 msgid "Copy selected translation text" msgstr "" #: ../lib/gui/mainwin.py:195 msgid "Paste\tCtrl-V" msgstr "" #: ../lib/gui/mainwin.py:196 msgid "Paste clipboard text into the search entry" msgstr "" #: ../lib/gui/mainwin.py:201 msgid "Preferences...\tCtrl-P" msgstr "" #: ../lib/gui/mainwin.py:201 msgid "Edit preferences" msgstr "" #: ../lib/gui/mainwin.py:203 msgid "&Edit" msgstr "" #: ../lib/gui/mainwin.py:213 msgid "Increase\tCtrl-=" msgstr "" #: ../lib/gui/mainwin.py:214 msgid "Increase text size" msgstr "" #: ../lib/gui/mainwin.py:215 msgid "Decrease\tCtrl--" msgstr "" #: ../lib/gui/mainwin.py:216 msgid "Decrease text size" msgstr "" #: ../lib/gui/mainwin.py:218 msgid "Normal\tCtrl-0" msgstr "" #: ../lib/gui/mainwin.py:219 msgid "Set normal text size" msgstr "" #: ../lib/gui/mainwin.py:220 msgid "Font Size" msgstr "" #: ../lib/gui/mainwin.py:235 msgid "Font Face" msgstr "" #: ../lib/gui/mainwin.py:250 msgid "Character Encoding" msgstr "" #: ../lib/gui/mainwin.py:255 msgid "Show/Hide Word List...\tCtrl-H" msgstr "" #: ../lib/gui/mainwin.py:256 msgid "Show or hide word list" msgstr "" #: ../lib/gui/mainwin.py:259 msgid "&View" msgstr "" #: ../lib/gui/mainwin.py:300 msgid "&Install Dictionary From File..." msgstr "" #: ../lib/gui/mainwin.py:302 msgid "&Dictionaries" msgstr "" #: ../lib/gui/mainwin.py:311 msgid "Manage Dictionaries...\tCtrl-M" msgstr "" #: ../lib/gui/mainwin.py:312 msgid "Install or remove dictionaries" msgstr "" #: ../lib/gui/mainwin.py:314 msgid "Create Dictionaries..." msgstr "" #: ../lib/gui/mainwin.py:315 msgid "Create and edit dictionaries" msgstr "" #: ../lib/gui/mainwin.py:322 msgid "Take Words From Clipboard" msgstr "" #: ../lib/gui/mainwin.py:323 msgid "Scan the clipboard for text to translate" msgstr "" #: ../lib/gui/mainwin.py:331 msgid "Connect to DICT Server..." msgstr "" #: ../lib/gui/mainwin.py:332 msgid "Open connection to DICT server" msgstr "" #: ../lib/gui/mainwin.py:337 msgid "Pronounce\tCtrl-E" msgstr "" #: ../lib/gui/mainwin.py:338 msgid "Pronounce word" msgstr "" #: ../lib/gui/mainwin.py:341 msgid "Tools" msgstr "" #: ../lib/gui/mainwin.py:350 msgid "&About\tCtrl-A" msgstr "" #: ../lib/gui/mainwin.py:352 msgid "&Help" msgstr "" #: ../lib/gui/mainwin.py:357 msgid "Word:" msgstr "" #: ../lib/gui/mainwin.py:362 msgid "" "Enter some text and press \"Look Up\" button or [ENTER] key on your keyboard" msgstr "" #: ../lib/gui/mainwin.py:368 msgid "Look Up" msgstr "" #: ../lib/gui/mainwin.py:369 msgid "Click this button to look up word in the dictionary" msgstr "" #: ../lib/gui/mainwin.py:380 msgid "History Back" msgstr "" #: ../lib/gui/mainwin.py:389 msgid "History Forward" msgstr "" #: ../lib/gui/mainwin.py:399 msgid "Stop searching" msgstr "" #: ../lib/gui/mainwin.py:423 msgid "Translation" msgstr "" #: ../lib/gui/mainwin.py:531 msgid "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Welcome to OpenDict

    \n" "

    Short usage information:

    \n" "
      \n" "
    • To start using dictionary, select one from Dictionaries\n" " menu.\n" "
    • \n" "
    • To install new dictionary from the Internet, select\n" " Manage Dictionaries\n" " from Tools menu and choose Available tab.\n" "
    • To install new dictionary from file, select Install Dictionary " "From File...\n" " from Dictionaries menu.\n" "
    • \n" "
    \n" "\n" "\n" msgstr "" #: ../lib/gui/mainwin.py:653 #, python-format msgid "" "Translation cannot be displayed using selected encoding %s. Please try " "another encoding from View > Character Encoding menu." msgstr "" #: ../lib/gui/mainwin.py:685 msgid "1 word matches" msgstr "" #: ../lib/gui/mainwin.py:687 #, python-format msgid "%d words match" msgstr "" #: ../lib/gui/mainwin.py:734 msgid "No dictionary activated" msgstr "" #: ../lib/gui/mainwin.py:735 msgid "" "No dictionary activated. Please select one from \"Dictionaries\" menu and " "try again." msgstr "" #: ../lib/gui/mainwin.py:738 msgid "No dictionaries installed" msgstr "" #: ../lib/gui/mainwin.py:739 msgid "" "There is no dictionaries installed. You can install one by selecting Tools > " "Manage Dictionaries > Available" msgstr "" #: ../lib/gui/mainwin.py:752 msgid "Please enter some text and try again" msgstr "" #: ../lib/gui/mainwin.py:784 #, python-format msgid "" "Unable to encode text \"%s\" in %s for \"%s\". That logically means the word " "definition does not exist in the dictionary." msgstr "" #: ../lib/gui/mainwin.py:872 msgid "Connect to DICT server" msgstr "" #: ../lib/gui/mainwin.py:899 msgid "Choose a dictionary from \"Dictionaries\" menu" msgstr "" #: ../lib/gui/mainwin.py:920 msgid "Failed to copy text from the clipboard" msgstr "" #: ../lib/gui/mainwin.py:922 msgid "Clipboard contains no text data" msgstr "" #: ../lib/gui/mainwin.py:946 ../lib/gui/mainwin.py:1142 #: ../lib/gui/pluginwin.py:772 msgid "Error" msgstr "" #: ../lib/gui/mainwin.py:947 #, python-format msgid "Unable to decode text using your locale charset %s" msgstr "" #: ../lib/gui/mainwin.py:955 msgid "Groups" msgstr "" #: ../lib/gui/mainwin.py:967 msgid "Manage Dictionaries" msgstr "" #: ../lib/gui/mainwin.py:981 msgid "File Register" msgstr "" #: ../lib/gui/mainwin.py:989 msgid "Create Dictionaries" msgstr "" #: ../lib/gui/mainwin.py:998 msgid "Preferences" msgstr "" #: ../lib/gui/mainwin.py:1088 msgid "Licence Agreement Rejected" msgstr "" #: ../lib/gui/mainwin.py:1089 #, python-format msgid "You cannot use dictionary \"%s\" without accepting licence agreement" msgstr "" #: ../lib/gui/mainwin.py:1103 msgid "Dictionary Index" msgstr "" #: ../lib/gui/mainwin.py:1104 msgid "" "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..." msgstr "" #: ../lib/gui/mainwin.py:1121 msgid "Index Creation Error" msgstr "" #: ../lib/gui/mainwin.py:1122 #, python-format msgid "" "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" msgstr "" #: ../lib/gui/mainwin.py:1143 #, python-format msgid "Unable to load dictionary index table. Got error: %s" msgstr "" #: ../lib/gui/mainwin.py:1153 #, python-format msgid "Dictionary \"%s\" loaded" msgstr "" #: ../lib/gui/mainwin.py:1205 msgid "Error: not supported dictionary type" msgstr "" #: ../lib/gui/mainwin.py:1310 msgid "" "Select dictionary format. If you can't find\n" "the format of your dictionary, the register\n" "system does not support it yet." msgstr "" #: ../lib/gui/mainwin.py:1315 msgid "Dictionary format" msgstr "" #: ../lib/gui/mainwin.py:1332 msgid "Choose plugin file" msgstr "" #: ../lib/gui/mainwin.py:1348 msgid "About" msgstr "" #: ../lib/gui/mainwin.py:1399 msgid "Show word list" msgstr "" #: ../lib/gui/mainwin.py:1416 msgid "Hide word list" msgstr "" #: ../lib/gui/mainwin.py:1425 msgid "Failed to print" msgstr "" #: ../lib/gui/mainwin.py:1437 msgid "Page preview failed" msgstr "" #: ../lib/gui/miscwin.py:53 msgid "Error: unable to show licence text" msgstr "" #: ../lib/gui/miscwin.py:59 msgid "Do not accept" msgstr "" #: ../lib/gui/miscwin.py:62 msgid "Accept" msgstr "" #: ../lib/gui/miscwin.py:76 msgid "Licence Agreement" msgstr "" #: ../lib/gui/miscwin.py:103 msgid "" "You have directories that containt invalid dictionaries and cannot be " "loaded. \n" "You can try to remove these directories right now." msgstr "" #: ../lib/gui/miscwin.py:142 ../lib/gui/pluginwin.py:644 msgid "Unable to remove" msgstr "" #: ../lib/gui/miscwin.py:143 #, python-format msgid "Unable to remove directory \"%s\": %s" msgstr "" #: ../lib/gui/miscwin.py:151 msgid "Invalid Dictionaries" msgstr "" #: ../lib/gui/pluginwin.py:78 msgid "Installed" msgstr "" #: ../lib/gui/pluginwin.py:82 msgid "Available" msgstr "" #: ../lib/gui/pluginwin.py:124 msgid "" "Checked dictionaries are available from the menu, unchecked dictionaries \n" "are not available from the menu." msgstr "" #: ../lib/gui/pluginwin.py:149 msgid "Install From File" msgstr "" #: ../lib/gui/pluginwin.py:208 msgid "Update List" msgstr "" #: ../lib/gui/pluginwin.py:215 msgid "Install" msgstr "" #: ../lib/gui/pluginwin.py:227 msgid "Name" msgstr "" #: ../lib/gui/pluginwin.py:228 msgid "Size" msgstr "" #: ../lib/gui/pluginwin.py:274 msgid "Information About Dictionary" msgstr "" #: ../lib/gui/pluginwin.py:288 msgid "Name: " msgstr "" #: ../lib/gui/pluginwin.py:293 msgid "Version: " msgstr "" #: ../lib/gui/pluginwin.py:298 msgid "Maintainer: " msgstr "" #: ../lib/gui/pluginwin.py:515 msgid "List updated" msgstr "" #: ../lib/gui/pluginwin.py:516 msgid "All your dictionaries are up to date." msgstr "" #: ../lib/gui/pluginwin.py:523 msgid "Downloading List" msgstr "" #: ../lib/gui/pluginwin.py:558 #, python-format msgid "Unable to download list from %s: %s" msgstr "" #: ../lib/gui/pluginwin.py:566 msgid "Unable to download list" msgstr "" #: ../lib/gui/pluginwin.py:645 #, python-format msgid "Unable to remove dictionary \"%s\"" msgstr "" #: ../lib/gui/pluginwin.py:686 #, python-format msgid "Downloading %s..." msgstr "" #: ../lib/gui/pluginwin.py:743 msgid "Unable to download" msgstr "" #: ../lib/gui/pluginwin.py:753 msgid "File is damaged" msgstr "" #: ../lib/gui/pluginwin.py:754 msgid "Downloaded file is damaged and cannot be installed. Please try again." msgstr "" #: ../lib/gui/pluginwin.py:773 #, python-format msgid "" "Unable to remove old version of \"%s\". Error occured: \"%s\". New " "version cannot be installed without removing old one." msgstr "" #: ../lib/gui/pluginwin.py:798 msgid "Unable to install" msgstr "" #: ../lib/gui/pluginwin.py:799 #, python-format msgid "Unable to install dictionary \"%s\"." msgstr "" #: ../lib/gui/prefswin.py:48 msgid "Default dictionary: " msgstr "" #: ../lib/gui/prefswin.py:69 msgid "Default encoding: " msgstr "" #: ../lib/gui/prefswin.py:80 msgid "Default DICT server: " msgstr "" #: ../lib/gui/prefswin.py:86 msgid "Default DICT server port: " msgstr "" #: ../lib/gui/prefswin.py:99 msgid "Pronunciation" msgstr "" #: ../lib/gui/prefswin.py:107 msgid "System Command: " msgstr "" #: ../lib/gui/prefswin.py:115 msgid "Default" msgstr "" #: ../lib/gui/prefswin.py:121 msgid "Pronounce original word" msgstr "" #: ../lib/gui/prefswin.py:123 msgid "Pronounce translation" msgstr "" #: ../lib/gui/prefswin.py:130 msgid "Save window size on exit" msgstr "" #: ../lib/gui/prefswin.py:134 msgid "Save window position on exit" msgstr "" #: ../lib/gui/prefswin.py:138 msgid "Save sash position on exit" msgstr "" #: ../lib/gui/prefswin.py:143 msgid "Take words from the clipboard by default" msgstr "" #: ../lib/gui/registerwin.py:66 ../lib/gui/registerwin.py:105 #: ../lib/gui/registerwin.py:148 #, python-format msgid "Name: %s" msgstr "" #: ../lib/gui/registerwin.py:69 ../lib/gui/registerwin.py:106 #: ../lib/gui/registerwin.py:149 #, python-format msgid "Path: %s" msgstr "" #: ../lib/gui/registerwin.py:72 ../lib/gui/registerwin.py:107 #: ../lib/gui/registerwin.py:150 #, python-format msgid "Format: %s" msgstr "" #: ../lib/gui/registerwin.py:75 ../lib/gui/registerwin.py:108 #: ../lib/gui/registerwin.py:151 #, python-format msgid "Encoding: %s" msgstr "" #: ../lib/gui/registerwin.py:82 msgid "Add new..." msgstr "" #: ../lib/gui/registerwin.py:86 msgid "Remove selected" msgstr "" #: ../lib/gui/registerwin.py:130 ../lib/gui/registerwin.py:137 #, python-format msgid "Error while deleting \"%s\"" msgstr "" opendict-0.6.8/po/ru.po0000664000076400007640000011526013204646653014706 0ustar nerijusnerijus# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: opendict\n" "POT-Creation-Date: 2007-08-29 11:55+EEST\n" "PO-Revision-Date: 2014-04-09 11:55+0300\n" "Last-Translator: AlexL \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" #: ../lib/errortype.py:57 msgid "Success" msgstr "Успешно" #: ../lib/errortype.py:58 msgid "Search successfully finished." msgstr "Поиск успешно завершен." #: ../lib/errortype.py:65 #: ../lib/misc.py:36 msgid "Not found" msgstr "Не найден" #: ../lib/errortype.py:66 msgid "Word or phrase not found. Try less letters or fewer words." msgstr "Слово или словосочетание не найдено. Попробуйте меньше букв или меньше слов." #: ../lib/errortype.py:74 msgid "Internal error" msgstr "Внутренняя ошибка" #: ../lib/errortype.py:75 msgid "Internal error occured. Please send bug report to the dictionary's of current use authors. Thank you." msgstr "Внутренняя ошибка. Пожалуйста, отправьте отчет об ошибке в словаре текущим авторам. Спасибо." #: ../lib/errortype.py:83 msgid "Not connected" msgstr "Не подключен" #: ../lib/errortype.py:84 msgid "This dictionary uses Internet connection to translate words. Please connect to the Internet and try again." msgstr "Этот словарь используется интернет-соединение для перевода слов. Пожалуйста, подключитесь к Интернету и повторите попытку." #: ../lib/errortype.py:93 #: ../lib/gui/dictconnwin.py:183 #: ../lib/gui/dictconnwin.py:199 msgid "Connection Error" msgstr "Ошибка подключения" #: ../lib/errortype.py:94 msgid "Could not connect to host. Check your Internet connection or try later." msgstr "Не удается подключиться к хосту. Проверьте подключение к Интернету или попробуйте позже." #: ../lib/errortype.py:102 msgid "Invalid encoding" msgstr "Неверная кодировка" #: ../lib/errortype.py:103 msgid "Selected encoding is not correct for this dictionary. Please select another from Edit > Character Encoding menu" msgstr "Выбранная кодировка не является правильной для этого словаря. Пожалуйста, выберите другую из Меню: Правка -> Кодировка" #: ../lib/errortype.py:112 msgid "OpenDict Bug" msgstr "Баг OpenDict" #: ../lib/errortype.py:113 msgid "Internal error occured. Please send bug report to OpenDict authors to prevent this error in the future. Thank you!" msgstr "Внутренняя ошибка. Пожалуйста, отправьте отчет об ошибке авторам OpenDict для предотвращения этой ошибки в будущем. Спасибо!" #: ../lib/errortype.py:121 msgid "Unknown Error" msgstr "Неизвестная ошибка" #: ../lib/errortype.py:122 msgid "Unknown error occured." msgstr "Произошла неизвестная ошибка." #: ../lib/gui/dictaddwin.py:35 msgid "Add new dictionary" msgstr "Добавить новый словарь" #: ../lib/gui/dictaddwin.py:41 msgid "" "The file format of \"%s\" could not be \n" "recognized by its extention. Please select one\n" "from the list:" msgstr "" "Формат файла \"%s\" не может быть \n" "определен по его расширению. Пожалуйста, выберите одно\n" "из списка:" #: ../lib/gui/dictaddwin.py:47 #: ../lib/gui/dictaddwin.py:48 #: ../lib/gui/dictaddwin.py:49 #: ../lib/gui/dictaddwin.py:50 msgid "\"%s\" dictionary format" msgstr "\"%s\" формат словаря" #: ../lib/gui/dictaddwin.py:59 #: ../lib/gui/dicteditorwin.py:91 #: ../lib/gui/prefswin.py:149 msgid "OK" msgstr "ОК" #: ../lib/gui/dictaddwin.py:62 #: ../lib/gui/dictconnwin.py:133 #: ../lib/gui/dicteditorwin.py:94 #: ../lib/gui/dicteditorwin.py:255 #: ../lib/gui/prefswin.py:152 msgid "Cancel" msgstr "Отмена" #: ../lib/gui/dictconnwin.py:55 msgid "Server: " msgstr "Сервер:" #: ../lib/gui/dictconnwin.py:64 msgid "Default Server" msgstr "Сервер по умолчанию:" #: ../lib/gui/dictconnwin.py:70 msgid "Port: " msgstr "Порт:" #: ../lib/gui/dictconnwin.py:73 msgid "Default Port" msgstr "Порт по умолчанию" #: ../lib/gui/dictconnwin.py:83 msgid "Database: " msgstr "База данных:" #: ../lib/gui/dictconnwin.py:87 msgid "Search in all databases" msgstr "Поиск по всем базам данных" #: ../lib/gui/dictconnwin.py:94 msgid "Fetch List" msgstr "Получить список" #: ../lib/gui/dictconnwin.py:100 msgid "Character encoding: " msgstr "Кодировка:" #: ../lib/gui/dictconnwin.py:130 msgid "Connect" msgstr "Соединение" #: ../lib/gui/dictconnwin.py:174 #: ../lib/gui/mainwin.py:689 #: ../lib/util.py:240 msgid "Done" msgstr "Завершено" #: ../lib/gui/dictconnwin.py:178 msgid "Receiving database list..." msgstr "Получение списка баз данных..." #: ../lib/gui/dictconnwin.py:184 #: ../lib/gui/dictconnwin.py:200 msgid "Unable to connect to server" msgstr "Не удается подключиться к серверу" #: ../lib/gui/dictconnwin.py:218 msgid "Connecting..." msgstr "Соединение..." #: ../lib/gui/dictconnwin.py:254 #: ../lib/util.py:219 msgid "Connecting to %s..." msgstr "Соединение с %s..." #: ../lib/gui/dicteditorwin.py:53 msgid "Word: " msgstr "Слово:" #: ../lib/gui/dicteditorwin.py:88 msgid "Add translation field" msgstr "Добавить поле перевода" #: ../lib/gui/dicteditorwin.py:111 msgid "Translation #%d: " msgstr "Перевод #%d: " #: ../lib/gui/dicteditorwin.py:245 msgid "Dictionary \"%s\" has been changed" msgstr "Словарь \"%s\" был изменен" #: ../lib/gui/dicteditorwin.py:249 #: ../lib/gui/dicteditorwin.py:337 msgid "Save" msgstr "Сохранить" #: ../lib/gui/dicteditorwin.py:252 msgid "Do not save" msgstr "Не сохранять" #: ../lib/gui/dicteditorwin.py:305 msgid "Dictionary editor" msgstr "Редактор словарей" #: ../lib/gui/dicteditorwin.py:321 msgid "Add" msgstr "Добавить" #: ../lib/gui/dicteditorwin.py:322 msgid "Add word" msgstr "Добавить слово" #: ../lib/gui/dicteditorwin.py:325 msgid "Edit" msgstr "Правка" #: ../lib/gui/dicteditorwin.py:326 msgid "Change translation" msgstr "Изменить перевод" #: ../lib/gui/dicteditorwin.py:329 #: ../lib/gui/miscwin.py:116 #: ../lib/gui/pluginwin.py:156 msgid "Remove" msgstr "Удалить" #: ../lib/gui/dicteditorwin.py:330 msgid "Remove selected word" msgstr "Удалить выбранное слово" #: ../lib/gui/dicteditorwin.py:333 msgid "Sort" msgstr "Сортировать" #: ../lib/gui/dicteditorwin.py:334 msgid "Sort word list" msgstr "Сортировать список слов" #: ../lib/gui/dicteditorwin.py:338 msgid "Save words to file" msgstr "Сохранить слова в файл" #: ../lib/gui/dicteditorwin.py:341 msgid "Save As..." msgstr "Сохранить как..." #: ../lib/gui/dicteditorwin.py:342 msgid "Save with a different file name" msgstr "Сохранить с другим именем файла" #: ../lib/gui/dicteditorwin.py:351 #: ../lib/gui/mainwin.py:1377 msgid "Word List" msgstr "Список слов" #: ../lib/gui/dicteditorwin.py:370 msgid "New..." msgstr "Новый..." #: ../lib/gui/dicteditorwin.py:371 msgid "Start new dictionary" msgstr "Начать новый словарь" #: ../lib/gui/dicteditorwin.py:374 msgid "Open..." msgstr "Открыть..." #: ../lib/gui/dicteditorwin.py:375 msgid "Open dictionary file" msgstr "Открыть файл со словарем" #: ../lib/gui/dicteditorwin.py:378 #: ../lib/gui/errorwin.py:84 #: ../lib/gui/miscwin.py:65 #: ../lib/gui/miscwin.py:124 #: ../lib/gui/pluginwin.py:92 #: ../lib/gui/registerwin.py:89 msgid "Close" msgstr "Закрыть" #: ../lib/gui/dicteditorwin.py:379 msgid "Close editor window" msgstr "Закрыть окно редактора" #: ../lib/gui/dicteditorwin.py:410 msgid "New Word" msgstr "Новое слово" #: ../lib/gui/dicteditorwin.py:425 msgid "Edit Word" msgstr "Редактировать слово" #: ../lib/gui/dicteditorwin.py:457 msgid "List is empty" msgstr "Список пуст" #: ../lib/gui/dicteditorwin.py:463 msgid "List sorted" msgstr "Список отсортирован" #: ../lib/gui/dicteditorwin.py:486 msgid "Save file" msgstr "Сохранить файл" #: ../lib/gui/dicteditorwin.py:507 msgid "Dictionary saved" msgstr "Словарь сохранен" #: ../lib/gui/dicteditorwin.py:517 msgid "Untitled" msgstr "БезИмени" #: ../lib/gui/dicteditorwin.py:588 #: ../lib/gui/dicteditorwin.py:645 msgid "Exit confirmation" msgstr "Подтверждение выхода" #: ../lib/gui/dicteditorwin.py:600 #: ../lib/gui/mainwin.py:1299 #: ../lib/installer.py:61 msgid "Choose dictionary file" msgstr "Выберите файл со словарем" #: ../lib/gui/dicteditorwin.py:614 msgid "Open Failed" msgstr "Не удалось открыть" #: ../lib/gui/dicteditorwin.py:615 msgid "Unable to open dictionary (got message: %s)" msgstr "Не удалось открыть словарь (причина: %s)" #: ../lib/gui/dicteditorwin.py:630 msgid "Dictionary loaded" msgstr "Словарь загружен" #: ../lib/gui/errorwin.py:72 msgid "An error occured:" msgstr "Произошла ошибка:" #: ../lib/gui/helpwin.py:69 #: ../lib/gui/helpwin.py:146 #: ../lib/gui/helpwin.py:209 msgid "&Close" msgstr "Закрыть" #: ../lib/gui/helpwin.py:107 msgid "Written By" msgstr "Написано" #: ../lib/gui/helpwin.py:119 msgid "Translated By" msgstr "Переведено" #: ../lib/gui/helpwin.py:124 msgid "" "Ports:\n" "\n" msgstr "" "Порты:\n" "\n" #: ../lib/gui/helpwin.py:129 msgid "Thanks To" msgstr "Спасибо" #: ../lib/gui/helpwin.py:135 msgid "" "OpenDict project is sponsored by IDILES.\n" "Visit company's website at http://www.idiles.com.\n" "\n" "Report problems by email address support@idiles.com." msgstr "" "OpenDict проект был спонсирован IDILES.\n" "Посетите сайт компании http://www.idiles.com.\n" "\n" "Отправляйте проблемы по адресу support@idiles.com." #: ../lib/gui/helpwin.py:142 msgid "Sponsors" msgstr "Спонсоры" #: ../lib/gui/helpwin.py:180 #: ../lib/gui/helpwin.py:193 msgid "OpenDict is a multiplatform dictionary." msgstr "OpenDict является мультиплатформенным словарем." #: ../lib/gui/helpwin.py:203 msgid "C&redits" msgstr "Кредиты" #: ../lib/gui/helpwin.py:206 msgid "&Licence" msgstr "Лицензия" #: ../lib/gui/helpwin.py:235 msgid "Licence" msgstr "Лицензия" #: ../lib/gui/mainwin.py:92 #: ../lib/gui/mainwin.py:778 #: ../lib/gui/mainwin.py:816 msgid "Stopped" msgstr "Остановлено" #: ../lib/gui/mainwin.py:97 #: ../lib/gui/mainwin.py:783 msgid "Encode Failed" msgstr "Кодирование не удалось" #: ../lib/gui/mainwin.py:98 msgid "Unable to encode text \"%s\" in %s for \"%s\"." msgstr "Не удалось кодировать текст \"%s\" в %s для \"%s\"." #: ../lib/gui/mainwin.py:106 #: ../lib/gui/mainwin.py:761 #: ../lib/gui/mainwin.py:1361 msgid "Searching..." msgstr "Поиск..." #: ../lib/gui/mainwin.py:159 msgid "Look Up\tCtrl-U" msgstr "Посмотреть\tCtrl-U" #: ../lib/gui/mainwin.py:160 msgid "Lookup up word in the dictionary" msgstr "Посмотреть слово в словаре" #: ../lib/gui/mainwin.py:165 msgid "&Close Dictionary\tCtrl-W" msgstr "&Закрыть словарь\tCtrl-W" #: ../lib/gui/mainwin.py:166 msgid "Close opened dicitonary" msgstr "Закрыть открытый словарь" #: ../lib/gui/mainwin.py:169 msgid "E&xit\tCtrl-Q" msgstr "В&ыход\tCtrl-Q" #: ../lib/gui/mainwin.py:170 msgid "Exit program" msgstr "Выйти из программы" #: ../lib/gui/mainwin.py:172 msgid "&File" msgstr "&Файл" #: ../lib/gui/mainwin.py:180 msgid "&Clear Search Entry\tCtrl-L" msgstr "&Очистить содержимое поиска\tCtrl-L" #: ../lib/gui/mainwin.py:183 msgid "Clear History" msgstr "Очистить историю" #: ../lib/gui/mainwin.py:191 msgid "Copy\tCtrl-C" msgstr "Копировать\tCtrl-C" #: ../lib/gui/mainwin.py:192 msgid "Copy selected translation text" msgstr "Копировать выделенный переведенный текст" #: ../lib/gui/mainwin.py:195 msgid "Paste\tCtrl-V" msgstr "Вставить\tCtrl-V" #: ../lib/gui/mainwin.py:196 msgid "Paste clipboard text into the search entry" msgstr "Вставить текст из буфера обмена в содержимое поиска" #: ../lib/gui/mainwin.py:201 msgid "Edit preferences" msgstr "Изменить настройки" #: ../lib/gui/mainwin.py:201 msgid "Preferences...\tCtrl-P" msgstr "Настройки...\tCtrl-P" #: ../lib/gui/mainwin.py:203 msgid "&Edit" msgstr "&Правка" #: ../lib/gui/mainwin.py:213 msgid "Increase\tCtrl-=" msgstr "Увеличить\tCtrl-=" #: ../lib/gui/mainwin.py:214 msgid "Increase text size" msgstr "Увеличить размер текста" #: ../lib/gui/mainwin.py:215 msgid "Decrease\tCtrl--" msgstr "Уменьшить\tCtrl--" #: ../lib/gui/mainwin.py:216 msgid "Decrease text size" msgstr "Уменьшить размер текста" #: ../lib/gui/mainwin.py:218 msgid "Normal\tCtrl-0" msgstr "Нормальный\tCtrl-0" #: ../lib/gui/mainwin.py:219 msgid "Set normal text size" msgstr "Установить нормальный размер текста" #: ../lib/gui/mainwin.py:220 msgid "Font Size" msgstr "Размер шрифта" #: ../lib/gui/mainwin.py:235 msgid "Font Face" msgstr "Гарнитура" #: ../lib/gui/mainwin.py:250 msgid "Character Encoding" msgstr "Кодировка" #: ../lib/gui/mainwin.py:255 msgid "Show/Hide Word List...\tCtrl-H" msgstr "Показать/Скрыть список слов...\tCtrl-H" #: ../lib/gui/mainwin.py:256 msgid "Show or hide word list" msgstr "Показать или скрыть список слов" #: ../lib/gui/mainwin.py:259 msgid "&View" msgstr "П&росмотр" #: ../lib/gui/mainwin.py:300 msgid "&Install Dictionary From File..." msgstr "&Установить словарь из файла..." #: ../lib/gui/mainwin.py:302 msgid "&Dictionaries" msgstr "&Словари" #: ../lib/gui/mainwin.py:311 msgid "Manage Dictionaries...\tCtrl-M" msgstr "Управлять словарями...\tCtrl-M" #: ../lib/gui/mainwin.py:312 msgid "Install or remove dictionaries" msgstr "Установить или удалить словари" #: ../lib/gui/mainwin.py:314 msgid "Create Dictionaries..." msgstr "Создать словари..." #: ../lib/gui/mainwin.py:315 msgid "Create and edit dictionaries" msgstr "Создать и редактировать словари" #: ../lib/gui/mainwin.py:322 msgid "Take Words From Clipboard" msgstr "Взять слова из буфера обмена" #: ../lib/gui/mainwin.py:323 msgid "Scan the clipboard for text to translate" msgstr "Сканировать буфер обмена для текста, который надо перевести" #: ../lib/gui/mainwin.py:331 msgid "Connect to DICT Server..." msgstr "Соединение с DICT сервером..." #: ../lib/gui/mainwin.py:332 msgid "Open connection to DICT server" msgstr "Открыть соединение с сервером DICT" #: ../lib/gui/mainwin.py:337 msgid "Pronounce\tCtrl-E" msgstr "Произнести\tCtrl-E" #: ../lib/gui/mainwin.py:338 msgid "Pronounce word" msgstr "Произнести слово" #: ../lib/gui/mainwin.py:341 msgid "Tools" msgstr "Инструменты" #: ../lib/gui/mainwin.py:350 msgid "&About\tCtrl-A" msgstr "&О программе\tCtrl-A" #: ../lib/gui/mainwin.py:352 msgid "&Help" msgstr "&Помощь" #: ../lib/gui/mainwin.py:357 msgid "Word:" msgstr "Слово:" #: ../lib/gui/mainwin.py:362 msgid "Enter some text and press \"Look Up\" button or [ENTER] key on your keyboard" msgstr "Введите текст и нажмите \"Смотреть\" или кнопку [ENTER] на клавиатуре" #: ../lib/gui/mainwin.py:368 msgid "Look Up" msgstr "Смотреть" #: ../lib/gui/mainwin.py:369 msgid "Click this button to look up word in the dictionary" msgstr "Нажмите эту кнопку, чтобы найти слово в словаре" #: ../lib/gui/mainwin.py:380 msgid "History Back" msgstr "История назад" #: ../lib/gui/mainwin.py:389 msgid "History Forward" msgstr "История вперед" #: ../lib/gui/mainwin.py:399 msgid "Stop searching" msgstr "Остановить поиск" #: ../lib/gui/mainwin.py:423 msgid "Translation" msgstr "Перевод" #: ../lib/gui/mainwin.py:531 msgid "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Welcome to OpenDict

    \n" "

    Short usage information:

    \n" "
      \n" "
    • To start using dictionary, select one from Dictionaries\n" " menu.\n" "
    • \n" "
    • To install new dictionary from the Internet, select\n" " Manage Dictionaries\n" " from Tools menu and choose Available tab.
    • \n" "
    • To install new dictionary from file, select Install Dictionary From File...\n" " from Dictionaries menu.\n" "
    • \n" "
    \n" "\n" "\n" msgstr "" "\n" "\n" "\n" "\n" "\n" "\n" "

    Добро пожаловать в OpenDict

    \n" "

    Краткая информация об использовании:

    \n" "
      \n" "
    • Чтобы начать пользоваться словарем, выберите один из Словари\n" " в меню.\n" "
    • \n" "
    • Чтобы установить новый словарь из интернета, выберите\n" " Управлять словарями\n" " из Инструменты в меню и выберите Доступный во вкладке.
    • \n" "
    • Чтобы установить новый словарь из файла, выберите Установить словарь из файла...\n" " из Словари в меню.\n" "
    • \n" "
    \n" "\n" "\n" #: ../lib/gui/mainwin.py:653 msgid "Translation cannot be displayed using selected encoding %s. Please try another encoding from View > Character Encoding menu." msgstr "Перевод не может быть отображен с помощью выбранной кодировки %s. Пожалуйста, попробуйте другую кодировку из меню Вид -> Кодировка." #: ../lib/gui/mainwin.py:685 msgid "1 word matches" msgstr "Одно слово совпадает" #: ../lib/gui/mainwin.py:687 msgid "%d words match" msgstr "%d слов совпадает" #: ../lib/gui/mainwin.py:734 msgid "No dictionary activated" msgstr "Нет активированного словаря" #: ../lib/gui/mainwin.py:735 msgid "No dictionary activated. Please select one from \"Dictionaries\" menu and try again." msgstr "Нет активированного словаря. Пожалуйста, выберите один из \"Словари\" из меню или попытайтесь снова" #: ../lib/gui/mainwin.py:738 msgid "No dictionaries installed" msgstr "Нет установленных словарей" #: ../lib/gui/mainwin.py:739 msgid "There is no dictionaries installed. You can install one by selecting Tools > Manage Dictionaries > Available" msgstr "Нет установленных словарей. Вы можете установить один, выбрав Инструменты -> Управлять словарями ->Доступный" #: ../lib/gui/mainwin.py:752 msgid "Please enter some text and try again" msgstr "Пожалуйста, введите текст и попробуйте еще раз" #: ../lib/gui/mainwin.py:784 msgid "Unable to encode text \"%s\" in %s for \"%s\". That logically means the word definition does not exist in the dictionary." msgstr "Не удалось кодировать текст \"%s\" в %s для \"%s\". Это логически означает, что определение слова не существует в словаре." #: ../lib/gui/mainwin.py:872 msgid "Connect to DICT server" msgstr "Соединение с сервером DICT" #: ../lib/gui/mainwin.py:899 msgid "Choose a dictionary from \"Dictionaries\" menu" msgstr "Выберите словарь из \"Словари\" из меню" #: ../lib/gui/mainwin.py:920 msgid "Failed to copy text from the clipboard" msgstr "Не удалось скопировать текст из буфера обмена" #: ../lib/gui/mainwin.py:922 msgid "Clipboard contains no text data" msgstr "Буфер обмена не содержит текстовых данных" #: ../lib/gui/mainwin.py:946 #: ../lib/gui/mainwin.py:1142 #: ../lib/gui/pluginwin.py:772 msgid "Error" msgstr "Ошибка" #: ../lib/gui/mainwin.py:955 msgid "Groups" msgstr "Группы" #: ../lib/gui/mainwin.py:967 msgid "Manage Dictionaries" msgstr "Управлять словарями" #: ../lib/gui/mainwin.py:981 msgid "File Register" msgstr "Регистрировать файл" #: ../lib/gui/mainwin.py:989 msgid "Create Dictionaries" msgstr "Создать словари" #: ../lib/gui/mainwin.py:998 msgid "Preferences" msgstr "Настройки" #: ../lib/gui/mainwin.py:1088 msgid "Licence Agreement Rejected" msgstr "Лицензионное соглашение отклонено" #: ../lib/gui/mainwin.py:1089 msgid "You cannot use dictionary \"%s\" without accepting licence agreement" msgstr "Вы не можете использовать словарь \"%s\" без принятия лицензионного соглашения" #: ../lib/gui/mainwin.py:1103 msgid "Dictionary Index" msgstr "Индекс словаря" #: ../lib/gui/mainwin.py:1104 msgid "" "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..." msgstr "" "Это первый раз, когда вы использовать этот словарь или он был изменен на диске с момента последнего индексирования. Индексация используется, чтобы сделать поиск более эффективным. Словарь будет проиндексирован сейчас. Это может занять несколько секунд.\n" "\n" "Нажмите ОК для продолжения..." #: ../lib/gui/mainwin.py:1121 msgid "Index Creation Error" msgstr "Ошибка создания индекса" #: ../lib/gui/mainwin.py:1122 msgid "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" msgstr "Произошла ошибка во время индексации файла. Это может быть потому, что в настоящее время выбрана кодировка %s, не являющаяся правильной для этого словаря. Попробуйте выбрать другую кодировку из меню Вид -> Кодировка" #: ../lib/gui/mainwin.py:1143 msgid "Unable to load dictionary index table. Got error: %s" msgstr "Не удается загрузить таблицу словаря индекса. Есть ошибка: %s" #: ../lib/gui/mainwin.py:1153 msgid "Dictionary \"%s\" loaded" msgstr "Словарь \"%s\" загружен" #: ../lib/gui/mainwin.py:1205 msgid "Error: not supported dictionary type" msgstr "Ошибка: не поддерживаемый тип словаря" #: ../lib/gui/mainwin.py:1310 msgid "" "Select dictionary format. If you can't find\n" "the format of your dictionary, the register\n" "system does not support it yet." msgstr "" "Выберите формат словаря. Если вы не можете найти\n" "формат вашего словаря, то\n" "система еще не поддерживает его." #: ../lib/gui/mainwin.py:1315 msgid "Dictionary format" msgstr "Формат словаря" #: ../lib/gui/mainwin.py:1332 msgid "Choose plugin file" msgstr "Выберите файл плагина" #: ../lib/gui/mainwin.py:1348 msgid "About" msgstr "О программе" #: ../lib/gui/mainwin.py:1399 msgid "Show word list" msgstr "Показать список слов" #: ../lib/gui/mainwin.py:1416 msgid "Hide word list" msgstr "Скрыть список слов" #: ../lib/gui/mainwin.py:1425 msgid "Failed to print" msgstr "Не удалось распечатать" #: ../lib/gui/mainwin.py:1437 msgid "Page preview failed" msgstr "Предварительный просмотр страницы не удался" #: ../lib/gui/miscwin.py:53 msgid "Error: unable to show licence text" msgstr "Ошибка: не удалось показать текст лицензии" #: ../lib/gui/miscwin.py:59 msgid "Do not accept" msgstr "Не принимать" #: ../lib/gui/miscwin.py:62 msgid "Accept" msgstr "Принять" #: ../lib/gui/miscwin.py:76 msgid "Licence Agreement" msgstr "Лицензионное соглашение" #: ../lib/gui/miscwin.py:103 msgid "" "You have directories that containt invalid dictionaries and cannot be loaded. \n" "You can try to remove these directories right now." msgstr "" "У вас есть каталоги, которые содержат недопустимые словари и не могут быть загружены. \n" "Вы можете попробовать удалить эти каталоги прямо сейчас." #: ../lib/gui/miscwin.py:142 #: ../lib/gui/pluginwin.py:644 msgid "Unable to remove" msgstr "Не удается удалить" #: ../lib/gui/miscwin.py:143 msgid "Unable to remove directory \"%s\": %s" msgstr "Не удается удалить директорию \"%s\": %s" #: ../lib/gui/miscwin.py:151 msgid "Invalid Dictionaries" msgstr "Недопустимые словари" #: ../lib/gui/pluginwin.py:78 msgid "Installed" msgstr "Установленный" #: ../lib/gui/pluginwin.py:82 msgid "Available" msgstr "Доступный" #: ../lib/gui/pluginwin.py:124 msgid "" "Checked dictionaries are available from the menu, unchecked dictionaries \n" "are not available from the menu." msgstr "" "Выбранные словари доступны из меню, невыбранные словари \n" "не доступны из меню." #: ../lib/gui/pluginwin.py:149 msgid "Install From File" msgstr "Установить из файла" #: ../lib/gui/pluginwin.py:208 msgid "Update List" msgstr "Обновить список" #: ../lib/gui/pluginwin.py:215 msgid "Install" msgstr "Установить" #: ../lib/gui/pluginwin.py:227 msgid "Name" msgstr "Имя" #: ../lib/gui/pluginwin.py:228 msgid "Size" msgstr "Размер" #: ../lib/gui/pluginwin.py:274 msgid "Information About Dictionary" msgstr "Информация о словаре" #: ../lib/gui/pluginwin.py:288 msgid "Name: " msgstr "Имя:" #: ../lib/gui/pluginwin.py:293 msgid "Version: " msgstr "Версия:" #: ../lib/gui/pluginwin.py:298 msgid "Maintainer: " msgstr "Кто собрал:" #: ../lib/gui/pluginwin.py:515 msgid "List updated" msgstr "Список обновлен" #: ../lib/gui/pluginwin.py:516 msgid "All your dictionaries are up to date." msgstr "Все ваши словари в актуальном состоянии." #: ../lib/gui/pluginwin.py:523 msgid "Downloading List" msgstr "Загружается список" #: ../lib/gui/pluginwin.py:558 msgid "Unable to download list from %s: %s" msgstr "Не удается загрузить список из %s: %s" #: ../lib/gui/pluginwin.py:566 msgid "Unable to download list" msgstr "Не удается загрузить список" #: ../lib/gui/pluginwin.py:645 msgid "Unable to remove dictionary \"%s\"" msgstr "Не удается удалить словарь \"%s\"" #: ../lib/gui/pluginwin.py:686 msgid "Downloading %s..." msgstr "Загружается %s..." #: ../lib/gui/pluginwin.py:743 msgid "Unable to download" msgstr "Не удается загрузить" #: ../lib/gui/pluginwin.py:753 msgid "File is damaged" msgstr "Файл поврежден" #: ../lib/gui/pluginwin.py:754 msgid "Downloaded file is damaged and cannot be installed. Please try again." msgstr "Загруженный файл поврежден и не может быть установлен. Пожалуйста, попробуйте еще раз." #: ../lib/gui/pluginwin.py:773 msgid "Unable to remove old version of \"%s\". Error occured: \"%s\". New version cannot be installed without removing old one." msgstr "Не удалось удалить старую версию из \"%s\". Произошла ошибка: \"%s\". Новая версия не может быть установлена ​​без удаления старой." #: ../lib/gui/pluginwin.py:798 msgid "Unable to install" msgstr "Не удается установить" #: ../lib/gui/pluginwin.py:799 msgid "Unable to install dictionary \"%s\"." msgstr "Не удается установить словарь \"%s\"." #: ../lib/gui/prefswin.py:48 msgid "Default dictionary: " msgstr "Словарь по умолчанию:" #: ../lib/gui/prefswin.py:69 msgid "Default encoding: " msgstr "Кодировка по умолчанию:" #: ../lib/gui/prefswin.py:80 msgid "Default DICT server: " msgstr "Сервер DICT по умолчанию:" #: ../lib/gui/prefswin.py:86 msgid "Default DICT server port: " msgstr "Порт сервера DICT по умолчанию:" #: ../lib/gui/prefswin.py:99 msgid "Pronunciation" msgstr "Произношение" #: ../lib/gui/prefswin.py:107 msgid "System Command: " msgstr "Системная команда:" #: ../lib/gui/prefswin.py:115 msgid "Default" msgstr "По умолчанию" #: ../lib/gui/prefswin.py:121 msgid "Pronounce original word" msgstr "Произнести оригинальное слово" #: ../lib/gui/prefswin.py:123 msgid "Pronounce translation" msgstr "Произнести перевод" #: ../lib/gui/prefswin.py:130 msgid "Save window size on exit" msgstr "Сохранять размер окна при выходе" #: ../lib/gui/prefswin.py:134 msgid "Save window position on exit" msgstr "Сохранять позицию окна при выходе" #: ../lib/gui/prefswin.py:138 msgid "Save sash position on exit" msgstr "Сохранять позицию створок при выходе" #: ../lib/gui/prefswin.py:143 msgid "Take words from the clipboard by default" msgstr "Брать слова из буфера обмена по умолчанию" #: ../lib/gui/registerwin.py:66 #: ../lib/gui/registerwin.py:105 #: ../lib/gui/registerwin.py:148 msgid "Name: %s" msgstr "Имя: %s" #: ../lib/gui/registerwin.py:69 #: ../lib/gui/registerwin.py:106 #: ../lib/gui/registerwin.py:149 msgid "Path: %s" msgstr "Путь: %s" #: ../lib/gui/registerwin.py:72 #: ../lib/gui/registerwin.py:107 #: ../lib/gui/registerwin.py:150 msgid "Format: %s" msgstr "Формат: %s" #: ../lib/gui/registerwin.py:75 #: ../lib/gui/registerwin.py:108 #: ../lib/gui/registerwin.py:151 msgid "Encoding: %s" msgstr "Кодировка: %s" #: ../lib/gui/registerwin.py:82 msgid "Add new..." msgstr "Добавить новый..." #: ../lib/gui/registerwin.py:86 msgid "Remove selected" msgstr "Удалить выбранное" #: ../lib/gui/registerwin.py:130 #: ../lib/gui/registerwin.py:137 msgid "Error while deleting \"%s\"" msgstr "Ошибка при удалении \"%s\"" #: ../lib/installer.py:81 msgid "Recognition Error" msgstr "Известная ошибка" #: ../lib/installer.py:82 msgid "File %s is not supported by OpenDict" msgstr "Файл %s не поддерживается OpenDict" #: ../lib/installer.py:108 #: ../lib/installer.py:110 msgid "Installation failed" msgstr "Установка не удалась" #: ../lib/installer.py:122 #: ../lib/installer.py:308 #: ../lib/installer.py:316 msgid "Installation Error" msgstr "Ошибка при установке" #: ../lib/installer.py:124 #: ../lib/installer.py:128 msgid "Error: Installation failed" msgstr "Ошибка: Установка не удалась" #: ../lib/installer.py:132 msgid "Dictionary installed" msgstr "Словарь установлен" #: ../lib/installer.py:133 msgid "Dictionary successfully installed. You can choose it from \"Dictionaries\" menu now." msgstr "Словарь успешно установлен. Теперь Вы можете выбрать его из \"Словари\" из меню." #: ../lib/installer.py:143 #: ../lib/installer.py:218 msgid "File %s does not exist" msgstr "Файл %s не существует" #: ../lib/installer.py:146 #: ../lib/installer.py:222 msgid "%s is not a file" msgstr "%s не является файлом" #: ../lib/installer.py:160 msgid "Dictionary \"%s\" is already installed" msgstr "Словарь \"%s\" уже установлен" #: ../lib/installer.py:226 msgid "%s is not OpenDict dictionary plugin" msgstr "%s не является плагином словаря OpenDict" #: ../lib/installer.py:233 msgid "File \"%s\" is not valid ZIP file" msgstr "Файл \"%s\" не является корректным файлом ZIP" #: ../lib/installer.py:238 msgid "Dictionary plugin file is corrupted" msgstr "Поврежден файл плагина для словаря" #: ../lib/installer.py:244 msgid "Plugin file is empty (%s)" msgstr "Файл плагина пуст (%s)" #: ../lib/installer.py:268 msgid "Selected file is not valid OpenDict plugin" msgstr "Выбранный файл не является допустимым плагином OpenDict" #: ../lib/installer.py:295 #: ../lib/installer.py:377 msgid "This dictionary already installed. If you want to upgrade it, please remove old version first." msgstr "Этот словарь уже установлены. Если вы хотите обновить его, то, пожалуйста, удалите сначала старую версию." #: ../lib/installer.py:309 #: ../lib/installer.py:317 msgid "Installation tool for this dictionary failed to start. Please report this problem to developers." msgstr "Инсталляционный инструмент для этого словаря не удалось запустить. Пожалуйста, сообщите об этой проблеме разработчикам." #: ../lib/installer.py:323 msgid "Installation Aborted" msgstr "Установка прервана" #: ../lib/installer.py:324 msgid "Dictionary installation has been aborted." msgstr "Установка словаря была прервана." #: ../lib/installer.py:348 #: ../lib/installer.py:400 msgid "Error while removing created directories after plugin installation failure. This may be permission or disk space error." msgstr "Ошибка при удалении созданных каталогов после установки плагина. Это может быть связано с правами или ошибки на диске." #: ../lib/installer.py:352 msgid "Unable to install plugin" msgstr "Не удается установить плагин" #: ../lib/installer.py:369 msgid "Compressed dictionary file is corrupted" msgstr "Сжатый файл словаря поврежден" #: ../lib/installer.py:404 msgid "Unable to install dictionary" msgstr "Не удается установить словарь" #: ../lib/misc.py:37 msgid "Dictionary error, please report to its author" msgstr "Ошибка словаря, пожалуйста, сообщите об этом автору" #: ../lib/misc.py:38 msgid "Syntax error" msgstr "Синтаксическая ошибка" #: ../lib/misc.py:39 msgid "You must be connected to the internet to use this dictionary" msgstr "Вы должны быть подключены к Интернету, чтобы использовать этот словарь" #: ../lib/misc.py:40 msgid "Time out" msgstr "Тайм-аут" #: ../lib/misc.py:41 msgid "Bad encoding is set for this dictionary, try another" msgstr "Плохая кодировка для этого словаря, попробуйте другую" #: ../lib/misc.py:48 msgid "Unicode (UTF-8)" msgstr "Юникод (UTF-8)" #: ../lib/misc.py:49 msgid "Western (ISO-8859-1)" msgstr "Западная (ISO-8859-1)" #: ../lib/misc.py:50 msgid "Central European (ISO-8859-2)" msgstr "Центральная Европа (ISO-8859-2)" #: ../lib/misc.py:51 msgid "Nordic (ISO-8859-10)" msgstr "Скандинавская (ISO-8859-10)" #: ../lib/misc.py:52 msgid "South European (ISO-8859-3)" msgstr "Южная Европа (ISO-8859-3)" #: ../lib/misc.py:53 msgid "Greek (ISO-8859-7)" msgstr "Греческая (ISO-8859-7)" #: ../lib/misc.py:54 msgid "Baltic (ISO-8859-13)" msgstr "Балтийская (ISO-8859-13)" #: ../lib/misc.py:55 msgid "Cyrillic (KOI8-R)" msgstr "Кириллица (KOI8-R)" #: ../lib/misc.py:56 msgid "Arabic (ISO-8859-6)" msgstr "Арабская (ISO-8859-6)" #: ../lib/util.py:235 msgid "Downloading... %d%%" msgstr "Загружается... %d%%" #: ../opendict.py:115 msgid "wxPython Version Error" msgstr "Ошибка версии wxPython" #: ../opendict.py:116 msgid "" "wxPython %s is installed on this system.\n" "\n" "OpenDict %s requires wxPython 2.6 to run smoothly.\n" "\n" "You can find wxPython 2.6 at http://www.wxpython.org or you can install it using your system package manager." msgstr "" "wxPython %s установлен в системе.\n" "\n" "OpenDict %s требует wxPython 2.6 для плавного запуска.\n" "\n" "Вы можете найти wxPython 2.6 на http://www.wxpython.org или вы можете установить его с помощью менеджера пакетов вашей системы." opendict-0.6.8/scripts/0000775000076400007640000000000013204646653014764 5ustar nerijusnerijusopendict-0.6.8/scripts/count_code.py0000664000076400007640000000204413204646653017460 0ustar nerijusnerijus#!/usr/bin/env python # Count OpenDict Code Lines # Copyright (c) Martynas Jocius # Licensed under the GNU GPL. import sys import glob def count(file): fd = open(file) all = 0 code = 0 for line in fd.readlines(): all += 1 if line.strip() == "": continue if line.find("#") > -1: if line[0] == "#": continue elif line[0:line.index("#")].strip() == "": continue code += 1 print "%s:" % file print " Number of lines: ", all print " Number of code lines:", code return (all, code) if __name__ == "__main__": if len(sys.argv) == 1: print "Usage: %s [file1] [file2] ..." % sys.argv[0] sys.exit(1) lines = 0 code = 0 for arg in sys.argv[1:]: for file in glob.glob(arg): new = count(file) lines += new[0] code += new[1] print "\nTotal number of lines: %d" % lines print "Total number of code lines: %d" % code opendict-0.6.8/scripts/install-odp.sh0000775000076400007640000000172213204646653017553 0ustar nerijusnerijus#!/bin/bash # OpenDict Plugin installation helper script # Copyright (c) 2005 Martynas Jocius # # With this script one can install OpenDict plugins without using # OpenDict itself. This may be handy for installing plugins from # scripts or other automatic method. PLUGINDIR=/home/`id -un`/.opendict/plugins if [ ! $1 ] then echo "OpenDict plugin installation helper" echo "Copyright (c) 2005 Martynas Jocius " echo echo "Usage: $0 [--global]" echo echo " --global Install plugin globally to /usr/share/opendict" exit 1 fi if [ ! -e $1 ] then echo "Error: File '$1' does not exist" exit 1 fi if [[ $2 = "--global" ]] then if [[ ! `id -u` = '0' ]] then echo "Error: You must be root (system administrator)" \ "to install globally" exit 1 fi PLUGINDIR=/usr/share/opendict/plugins fi mkdir -p $PLUGINDIR/$1 unzip -d $PLUGINDIR/$1 $1 echo "Done." opendict-0.6.8/scripts/make-addons-list.py0000775000076400007640000001775113204646653020510 0ustar nerijusnerijus#!/usr/bin/env python import sys import os import zipfile import md5 import xml.dom.minidom # # Add-ons description file generator for OpenDict # Copyright (c) 2005 Martynas Jocius # # Fast code, dirty code # def parsePluginConfig(xmlData): """Parse plugin configuration""" doc = xml.dom.minidom.parseString(xmlData) name = None version = None authors = [] description = None pluginElement = doc.getElementsByTagName('plugin')[0] pluginType = pluginElement.getAttribute('type') if pluginType != 'dictionary': raise Exception, "Plugin is not dictionary plugin" # Get name for nameElement in doc.getElementsByTagName('name'): for node in nameElement.childNodes: if node.nodeType == node.TEXT_NODE: name = node.data # Get version for versionElement in doc.getElementsByTagName('version'): for node in versionElement.childNodes: if node.nodeType == node.TEXT_NODE: version = node.data # Get authors for authorElement in doc.getElementsByTagName('author'): authorName = authorElement.getAttribute('name') authorEMail = authorElement.getAttribute('email') authors.append({'name': authorName, 'email': authorEMail}) # Get description for descElement in doc.getElementsByTagName('description'): for node in descElement.childNodes: if node.nodeType == node.TEXT_NODE: description = node.data result = {} result['name'] = name result['version'] = version result['authors'] = authors result['description'] = description return result def parsePlainConfig(xmlData): """Parse plain dict configuration""" doc = xml.dom.minidom.parseString(xmlData) name = None version = None authors = [] description = None registers = doc.getElementsByTagName('plain-dictionary') if len(registers) == 0: raise "Invalid configuration" registerElement = registers[0] for nameElement in registerElement.getElementsByTagName('name'): for node in nameElement.childNodes: name = node.data for versionElement in registerElement.getElementsByTagName('version'): for node in versionElement.childNodes: version = node.data.strip() for authorElement in registerElement.getElementsByTagName('author'): authors.append({'name': authorElement.getAttribute('name'), 'email': authorElement.getAttribute('email')}) for descElement in \ registerElement.getElementsByTagName('description'): for node in descElement.childNodes: description = (description or '') + node.data.strip() result = {} result['name'] = name result['version'] = version result['authors'] = authors result['description'] = description return result def generateElement(**args): """Generate add-on XML DOM elemente""" doc = xml.dom.minidom.Document() addonElement = doc.createElement('add-on') addonElement.setAttribute('type', args.get('type')) # Name element nameElement = doc.createElement('name') addonElement.appendChild(nameElement) nameElement.appendChild(doc.createTextNode(args.get('name'))) # Version element versionElement = doc.createElement('version') addonElement.appendChild(versionElement) versionElement.appendChild(doc.createTextNode(args.get('version'))) # Authors element authorsElement = doc.createElement('authors') addonElement.appendChild(authorsElement) for author in (args.get('authors') or []): authorElement = doc.createElement('author') authorsElement.appendChild(authorElement) authorElement.setAttribute('name', author.get('name')) authorElement.setAttribute('email', author.get('email')) # Description element descElement = doc.createElement('description') addonElement.appendChild(descElement) descEscaped = "%s" % args.get('description', '') descElement.appendChild(doc.createTextNode(descEscaped)) # MD5 element md5Element = doc.createElement('md5') addonElement.appendChild(md5Element) md5Element.appendChild(doc.createTextNode(args.get('md5sum'))) # URL element urlElement = doc.createElement('url') addonElement.appendChild(urlElement) urlElement.appendChild(doc.createTextNode(args.get('url'))) # Size element sizeElement = doc.createElement('size') addonElement.appendChild(sizeElement) sizeElement.appendChild(doc.createTextNode(str(args.get('size')))) return addonElement def listFiles(start, followLinks, myDepth, maxDepth): """Return file list""" files = [] try: dirList = os.listdir(start) except: if os.path.isdir(start): print 'ERROR: Cannot list directory %s' % start return files for item in dirList: path = os.path.join(start, item) if os.path.isdir(path) and (followLinks or \ (not followLinks and not islink(path))): files.extend(listFiles(path, followLinks, myDepth + 1, maxDepth)) else: files.append(path) return files def makeDocument(addons): """Connect add-on elements to one XML document""" doc = xml.dom.minidom.Document() addonsElement = doc.createElement('opendict-add-ons') doc.appendChild(addonsElement) for addon in addons: addonsElement.appendChild(addon) return doc def main(): """Main procedure""" if len(sys.argv) < 3: print "Usage: %s " % sys.argv[0] print "(Example: '%s . http://xxx.yyy.net/dicts')" % sys.argv[0] sys.exit(1) d = sys.argv[1] baseURL = sys.argv[2] xmlElements = [] for filePath in listFiles(d, True, 0, None): try: zipFile = zipfile.ZipFile(filePath, 'r') except Exception, e: print "ERROR: %s: %s" % (filePath, e) continue # Test CRC if zipFile.testzip(): raise Exception, _("Dictionary plugin file is corrupted") # Check if empty try: topDirectory = zipFile.namelist()[0] except Exception, e: raise Exception, _("Plugin file is empty (%s)" % e) # Check for validity for fileInZip in zipFile.namelist(): dirName = os.path.dirname(fileInZip) fileName = os.path.basename(fileInZip) topDir = zipFile.namelist()[0] plainConfigPath = os.path.join(topDir, 'conf', 'config.xml') pluginConfigPath = os.path.join(topDir, 'plugin.xml') info = {} if plainConfigPath in zipFile.namelist(): info.update(parsePlainConfig(zipFile.read(plainConfigPath))) info['type'] = 'plain-dictionary' elif pluginConfigPath in zipFile.namelist(): info.update(parsePluginConfig(zipFile.read(pluginConfigPath))) info['type'] = 'plugin-dictionary' sz = os.stat(filePath)[6] / 1000 fd = open(filePath) m = md5.new(fd.read()) fd.close() checksum = m.hexdigest() location = baseURL + '/' + filePath xmlElements.append(generateElement(type=info.get('type'), name=info.get('name'), version=info.get('version'), authors=info.get('authors'), description=info.get('description'), url=location, md5sum=checksum, size=sz)) print "* %s" % filePath doc = makeDocument(xmlElements) fd = open('opendict-add-ons.xml', 'w') fd.write(doc.toxml()) fd.close() if __name__ == "__main__": main() opendict-0.6.8/scripts/make_hash.py0000664000076400007640000000101413204646653017252 0ustar nerijusnerijus#!/usr/bin/env python # MakeHash # Utility for dictionary hash table making # mjoc, 2003 import sys if len(sys.argv) < 3: print "Usage: %s " % sys.argv[0] sys.exit(1) dict = open(sys.argv[1], "r") hash = open(sys.argv[2], "w") line = dict.readline() l = line[0].lower() n = 0 hash.write(l+" "+repr(n)+"\n") n += len(line) for line in dict.readlines(): if line[0].lower() != l: l = line[0] hash.write(l+" "+repr(n)+"\n") n += len(line) dict.close() hash.close() opendict-0.6.8/scripts/make_hash2.py0000664000076400007640000000112713204646653017341 0ustar nerijusnerijus#!/usr/bin/env python # MakeHash # Utility for dictionary hash table making # mjoc, 2003 import sys if len(sys.argv) < 3: print "Usage: %s " % sys.argv[0] sys.exit(1) fdDict = open(sys.argv[1]) fdHash = open(sys.argv[2], "w") print "Indexing..." hash = {} line = fdDict.readline() l = line[0:2].lower() n = 0 hash[l] = n n += len(line) for line in fdDict.readlines(): l = line[0:2].lower() if not hash.has_key(l): hash[l] = n n += len(line) for l, p in hash.items(): fdHash.write("%s %s\n" % (l, p)) fdDict.close() fdHash.close() opendict-0.6.8/scripts/msgfmt.py0000664000076400007640000001257613204646653016646 0ustar nerijusnerijus#! /usr/bin/env python # Written by Martin v. Lwis """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po Options: -o file --output-file=file Specify the output file to write to. If omitted, output will go to a file named filename.mo (based off the input file name). -h --help Print this message and exit. -V --version Display version information and exit. """ import sys import os import getopt import struct import array __version__ = "1.1" MESSAGES = {} def usage(code, msg=''): print >> sys.stderr, __doc__ if msg: print >> sys.stderr, msg sys.exit(code) def add(id, str, fuzzy): "Add a non-fuzzy translation to the dictionary." global MESSAGES if not fuzzy and str: MESSAGES[id] = str def generate(): "Return the generated output." global MESSAGES keys = MESSAGES.keys() # the keys are sorted in the .mo file keys.sort() offsets = [] ids = strs = '' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) ids += id + '\0' strs += MESSAGES[id] + '\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. # translated string. keystart = 7*4+16*len(keys) # and the values start after the keys valuestart = keystart + len(ids) koffsets = [] voffsets = [] # The string table first has the list of keys, then the list of values. # Each entry has first the size of the string, then the file offset. for o1, l1, o2, l2 in offsets: koffsets += [l1, o1+keystart] voffsets += [l2, o2+valuestart] offsets = koffsets + voffsets output = struct.pack("iiiiiii", 0x950412de, # Magic 0, # Version len(keys), # # of entries 7*4, # start of key index 7*4+len(keys)*8, # start of value index 0, 0) # size and offset of hash table output += array.array("i", offsets).tostring() output += ids output += strs return output def make(filename, outfile): ID = 1 STR = 2 # Compute .mo name from .po name and arguments if filename.endswith('.po'): infile = filename else: infile = filename + '.po' if outfile is None: outfile = os.path.splitext(infile)[0] + '.mo' try: lines = open(infile).readlines() except IOError, msg: print >> sys.stderr, msg sys.exit(1) section = None fuzzy = 0 # Parse the catalog lno = 0 for l in lines: lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: add(msgid, msgstr, fuzzy) section = None fuzzy = 0 # Record a fuzzy mark if l[:2] == '#,' and l.find('fuzzy'): fuzzy = 1 # Skip comments if l[0] == '#': continue # Now we are in a msgid section, output previous section if l.startswith('msgid'): if section == STR: add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR l = l[6:] # Skip empty lines l = l.strip() if not l: continue # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: msgid += l elif section == STR: msgstr += l else: print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ 'before:' print >> sys.stderr, l sys.exit(1) # Add last entry if section == STR: add(msgid, msgstr, fuzzy) # Compute output output = generate() try: open(outfile,"wb").write(output) except IOError,msg: print >> sys.stderr, msg def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'hVo:', ['help', 'version', 'output-file=']) except getopt.error, msg: usage(1, msg) outfile = None # parse options for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-V', '--version'): print >> sys.stderr, "msgfmt.py", __version__ sys.exit(0) elif opt in ('-o', '--output-file'): outfile = arg # do it if not args: print >> sys.stderr, 'No input file given' print >> sys.stderr, "Try `msgfmt --help' for more information." return for filename in args: make(filename, outfile) if __name__ == '__main__': main() opendict-0.6.8/scripts/opendict-festival-pulseaudio.sh0000775000076400007640000000145013204646653023113 0ustar nerijusnerijus#!/bin/bash if [ -f "/usr/bin/festival" ] then if [ ! -f "$HOME/.festivalrc" ] then touch $HOME/.festivalrc fi A=`cat $HOME/.festivalrc|grep Parameter|grep Audio_Command|grep paplay` if [ "$A" = "" ] then B=`cat $HOME/.festivalrc|grep Parameter|grep Audio_Method|grep Audio_Command` if [ "$B" = "" ] then C=`cat $HOME/.festivalrc|grep Parameter|grep Audio_Required_Format|grep snd` if [ "$C" = "" ] then echo '(Parameter.set '\''Audio_Command "paplay $FILE")' >> $HOME/.festivalrc echo '(Parameter.set '\''Audio_Method '\''Audio_Command)' >> $HOME/.festivalrc echo '(Parameter.set '\''Audio_Required_Format '\''snd)' >> $HOME/.festivalrc fi fi fi fi exec /usr/share/opendict/opendict.py opendict-0.6.8/scripts/release.sh0000775000076400007640000000130113204646653016736 0ustar nerijusnerijus#!/bin/sh # # Easy releasy script. Use before releasing software. # NAME=$1 INDIR=$2 OUTDIR=$3 if [[ $NAME == "" ]] || [[ $INDIR == "" ]]; then echo "Usage: $0 " exit 1; fi #if [[ $UID != "0" ]]; then # echo "You should be root (or modify this script to avoid root :)" # exit 1; #fi cd $INDIR && make clean rm -rf "$OUTDIR/$NAME*" cp -r "$INDIR" "$OUTDIR/$NAME" cd $OUTDIR rm -rf $NAME.zip rm -rf $NAME.tar.gz for f in `find "$NAME" -name ".git"`; do echo Removing "$f" && rm -rf "$f"; done; zip -r "$NAME.zip" "$NAME" tar -cf "$NAME.tar" "$NAME" gzip "$NAME.tar" echo echo "Release files created. Do not forget to create SVN TAG when tested." opendict-0.6.8/scripts/slowo2mova.py0000664000076400007640000000103613204646653017446 0ustar nerijusnerijus#!/usr/bin/env python # slowo2mova # Copyright (c) 2003 Martynas Jocius import sys def slowo2mova(sfName, mfName): fdSlowo = open(sfName) fdMova = open(mfName, "w") for line in fdSlowo.readlines(): fdMova.write(line.split("=")[0].strip()+" "+line.split("=")[1].strip()+"\n") fdSlowo.close() fdMova.close() if __name__ == "__main__": if len(sys.argv) < 3: print "Usage %s " % sys.argv[0] sys.exit(1) slowo2mova(sys.argv[1], sys.argv[2]) opendict-0.6.8/scripts/unzip.py0000664000076400007640000000104013204646653016476 0ustar nerijusnerijus#!/usr/bin/env python # learn how to use zipfile module import sys, zipfile, os, os.path def unzip_file_into_dir(file, dir): os.mkdir(dir, 0777) zfobj = zipfile.ZipFile(file) for name in zfobj.namelist(): if name.endswith('/'): os.mkdir(os.path.join(dir, name)) else: outfile = open(os.path.join(dir, name), 'wb') outfile.write(zfobj.read(name)) outfile.close() def main(): unzip_file_into_dir(open(sys.argv[1]), sys.argv[2]) if __name__ == '__main__': main() opendict-0.6.8/scripts/w2u.py0000664000076400007640000000125513204646653016056 0ustar nerijusnerijus#!/usr/bin/env python # w2u # Convert windows text file to unix text file # (by changing line end symbol) # Martynas Jocius import sys import glob def w2u(args): files = [] for arg in args: files.extend(glob.glob(arg)) for fname in files: print "Working on %s..." % fname old = open(fname) data = "" for line in old.readlines(): data += line.rstrip() + "\n" new = open(fname, "w") new.write(data) old.close() new.close() if __name__ == "__main__": if len(sys.argv) < 2: print "Usage: %s [file2] [file3] ..." % sys.argv[0] sys.exit(1) w2u(sys.argv[1:]) opendict-0.6.8/scripts/zip.py0000664000076400007640000000077013204646653016144 0ustar nerijusnerijusfrom zipfile import ZipFile from glob import glob import sys import os def compress(z, dir): zip = ZipFile(z, "w") files = glob(os.path.join(dir, "*")) for file in files: zip.write(file) zip.close() if __name__ == "__main__": if len(sys.argv) < 3: print "Usage: %s " % sys.argv[0] sys.exit(1) print "Packing '%s' to '%s'..." % (sys.argv[2], sys.argv[1]), compress(sys.argv[1], sys.argv[2]) print "done" opendict-0.6.8/win32/0000775000076400007640000000000013204646653014237 5ustar nerijusnerijusopendict-0.6.8/win32/compile.bat0000775000076400007640000000067413204646653016371 0ustar nerijusnerijusrem Copy compile.bat and setup.py to root directory and run compile.bat C:\Python27\python.exe setup.py py2exe --packages encodings rem Use this to get controls with the Windows XP appearance rem C:\Python27\python.exe setup.manifest.py py2exe --packages encodings copy copying.html dist rem echo don't forget to copy msvcr71.dll from wxPython/distrib/msw/ to dist rem echo before making a release rem copy C:\Python27\msvcr71.dll dist opendict-0.6.8/win32/install_script.iss0000664000076400007640000001364413204646653020021 0ustar nerijusnerijus; Script generated by the My Inno Setup Extensions Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! [Setup] AppName=OpenDict AppVerName=OpenDict 0.5.6 AppPublisher=Martynas Jocius ;AppPublisherURL=http://opendict.sourceforge.net ;AppSupportURL=http://opendict.sourceforge.net ;AppUpdatesURL=http://opendict.sourceforge.net DefaultDirName={pf}\OpenDict DisableDirPage=no DefaultGroupName=OpenDict AllowNoIcons=yes LicenseFile=C:\Program Files\OpenDict-dev\OpenDict-source\copying.txt ; MessagesFile=compiler:lithuanian.isl [Tasks] ; NOTE: The following entry contains English phrases ("Create a desktop icon" and "Additional icons"). You are free to translate them into another language if required. Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional icons:" ; NOTE: The following entry contains English phrases ("Create a Quick Launch icon" and "Additional icons"). You are free to translate them into another language if required. Name: "quicklaunchicon"; Description: "Create a &Quick Launch icon"; GroupDescription: "Additional icons:"; Flags: unchecked [Files] Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\opendict.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\_socket.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\_ssl.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\pyexpat.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\_socket.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\_sre.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\_winreg.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\htmlc.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\python23.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\wxc.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\wxmsw24h.dll"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\win32\dist\opendict\zlib.pyd"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\copying.txt"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\OpenDict_LT_instrukcija.txt"; DestDir: "{app}"; Flags: isreadme Source: "C:\Program Files\OpenDict-dev\OpenDict-source\po\lt\opendict.mo"; DestDir: "{app}\locale\lt\"; Flags: ignoreversion ;Source: "C:\Program Files\OpenDict-dev\OpenDict-source\todo.txt"; DestDir: "{app}"; Flags: ignoreversion ;Source: "C:\Program Files\OpenDict-dev\OpenDict-source\doc\Design.txt"; DestDir: "{app}\doc\"; Flags: ignoreversion ;Source: "C:\Program Files\OpenDict-dev\OpenDict-source\doc\Manual.html"; DestDir: "{app}\doc\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\clear.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\hide.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\logo.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\icon.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\icon.png"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\search.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\right.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\left.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\plugin.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\register.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\group.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion Source: "C:\Program Files\OpenDict-dev\OpenDict-source\pixmaps\stop.xpm"; DestDir: "{app}\pixmaps\"; Flags: ignoreversion ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] Name: "{group}\OpenDict"; Filename: "{app}\opendict.exe" Name: "{userdesktop}\OpenDict"; Filename: "{app}\opendict.exe"; Tasks: desktopicon Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\OpenDict"; Filename: "{app}\opendict.exe"; Tasks: quicklaunchicon ; [Messages] ; MessagesFile=compiler:lithuanian.isl [Run] ; NOTE: The following entry contains an English phrase ("Launch"). You are free to translate it into another language if required. Filename: "{app}\opendict.exe"; Description: "Launch OpenDict"; Flags: shellexec postinstall skipifsilent [Registry] Root: HKCU; Subkey: "Software\OpenDict"; Flags: uninsdeletekeyifempty Root: HKCU; Subkey: "Software\OpenDict"; Flags: uninsdeletekey Root: HKCU; Subkey: "Software\OpenDict\Settings"; ValueType: string; ValueName: "Path"; ValueData: "{app}" ;Root: HKLM; Subkey: "Software\OpenDict"; Flags: uninsdeletekeyifempty ;Root: HKLM; Subkey: "Software\OpenDict"; Flags: uninsdeletekey ;Root: HKLM; Subkey: "Software\OpenDict\Settings"; ValueType: string; ValueName: "Path"; ValueData: "{app}" opendict-0.6.8/win32/make.py0000664000076400007640000000166513204646653015536 0ustar nerijusnerijus# Make Win32 executable for OpenDict import os import sys #sys.path = [os.path.join(os.curdir, "lib")] + sys.path sys.path = ["C:\\Program files\\OpenDict-dev\Opendict-source\lib"] + sys.path odlist = "wx.Python.html,shutil,zipfile,string," list = "encodings,codecs,xml,ConfigParser,"\ "Cookie,copy,ftplib,glob,gopherlib,gzip,htmllib,HTMLParser,httplib,"\ "locale,re,sgmllib,socket,stat,StringIO,threading,thread,"\ "urllib,urllib2,urlparse,uu,warnings,webbrowser" command = "C:\\python24\\python.exe setup.py py2exe -w " \ "--icon ..\\pixmaps\\icon.ico -i %s " \ "--packages encodings --force-imports encodings" % (odlist+list) #command = "C:\\python22\\python.exe setup.py py2exe --icon ..\\pixmaps\\icon.ico" print "Command: '%s'\n" % command out = os.popen(command) print "\"dist\" directory will be created." print "Compiling, will take a minute...\n", out.read() raw_input("...") opendict-0.6.8/win32/opendict.ico0000664000076400007640000015447613204646653016561 0ustar nerijusnerijus hV   F00 %`` D(  @ ,zqqq  !B,O7UѪz +F/U/p4r=]Ʒj4G/_%qK1{3w=] #AOn2g#' ,H$n.2{=_/\r"#Q|c+-.D"&.j'(0 ` 1( +a2`Ybc!)Y%Y1n#Bxs~akm7 +S#^0r1o1n"Bx{Zce, z ,Ld%k-y/v0r1o"Bx{9o +Ei'e&l-y/u0q"BxzBIL e*?m"$!| W*,|-x/t"CxzJRT >Z!!-Cn')*,|.x!EyzJRT Lk Nw#7$&()*,{!FyzJRT Nlk ;^"&()+~ HzzJRU Pl 6Rx&()JzzJRU Qm[ %'(K{zJRU Sm\"#%'M{zJRU Un[!"$&O|zJRUWn/DJms!"$P|zJRUYor Rr 3Ih !@[JRU YoW~1@Inz|JRU!Yoc+?HgruJRU!Yop&>HjuxJRU"Yo=FcorJRU" YoBLanpgrvMVY #& DE9@  +Jd)\Cy,y.w/t0r1oGFNQhsu 7 )Bf&'"r $?+{-z.w/t0qGFNQ~/47$- '<h"#%$$"&y*,|-y.v/sHFNQ~169$"i !"# *C !r))+,|-y/vJFNQ~169%(+> "Eld&'))+~,{-xKFNQ~169%(,><_$%&())+~,{MFNQ~179&(-> 0?d"&'()*+}NFNQ~179&(.?U f&'()*PFNQ~179'(/? $#&'()RFNQ~17:'(0?`Bg#%&'(SFNQ~17:((0@_Gl!"#%&'UFOQ~17:((1@^Ot ""#%&WFOQ~17:)(2@e A\ ""$%XFOQ~17:)(3@ . :Wp!""$ZFOQ~17:*(4Ax Xy 9O&u!""IuIRT~17:+(4Ai7K=GLny{~17:+)4Av.+4A f~17S]_t_jnBJM"&)+/: l/6MWYs[eh@GJ).1 h=#*,kvxur~shsvU^a@GJ).1 e:v057MUXGOQ8>A'+-a7e^3 ?(0` %=k4 %6 &*+:+-B%lKl,25 #)<#f9=Qs,36,012S\]>} &7"`8===Qs,36mx{t  #2 Z7=====Qs,36k  .Uy5=======Qs,36?EG]^hjF b +Oq4=========Qs,36^hi~Y (Ih2=9<========Qs-36-P %C`0==; #1 "13=======Ps-36PYZ9G#=X.==== 8Q,z<====![0========Ps-36x$),[*3J*t<=====+x'l=========Ps-36x$),[.B(o;======3 Mn==========Ps-36x$),\ "_=======9 $0E<==========Ps-36x$),\ "_=======3I %9===========Pr-36x$),] "_======80============Pr-36x$),] "_======/*s===========Pr-46x$),^ "_=======2 #27N7=========Pr-46x$),^ "_========<"^  %f========Pr-46x$),_ "_==========5/B(p=======Pr-46x$),_ "_===========#b6=======Pr-46x$),` "_=========="^#a========Pr-46x$),` "_========= Y~&j=========Pr-46x%),a "_========Tw(o==========Pr-46x%),a "_=======Op)s===========Pr-46x%)-b "_======Lm+w============Pr-46x%)-b "_=====5 $6MTw)q3<=======Pr-46x%)-c "_====="^ 9======Pr-46x%)-c "_======;1'kNn0E9P======9A]/57x%)-d "_============9/5====:%g2D)5;^gix%)-d "_=================;'m4H&3;ELNcnptx%)-e "`===============<*s7L$2:;ACYbdvx%)-e "`=============<,y:R#2:7>?RZ\yx%)-f "`============.?X!1:7>@S[]}x%)-f "`==========0C`0:29',DKLny}S\`>EI Y( ;U/@$*A&+. yO$m.3649<%)+ vK!erH???(`  @37 . -/ & ,/6/!!GNO8>?( +/F>< 4+29*..}6v)/A:[,i!K 6,39*..}6m(/<7[-j1n1n!K 6,39*..}6d&/9 4| [.k1n1n1n1n!K 6,39*..}gXacO [ $/5 1u Z.k1n1n1n1n1n1n!K 6,39*..}\$'([7"R #03 /m!Y.l1n1n1n1n1n1n1n1n!K 6,39*..}ny{akmMUVI!/1 /h!Z/n1o1n1n1n1n1n1n1n1n1n!K 6,39*..}]gh@ 01 .b!\.q0r0p1p1o1n1n1n1n1n1n1n1n!K 6,39*..}]gh7/1 -] \.t/t/s0r0r0p1p1o1n1n1n1n1n1n1n!K 6,39*..}]gh / /1 ,X ]-w.w/v/u/t0s0r0q0p1p1n1n1n1n1n1n1n!K 6,39*..}PXZXab>DE & .2 *Q\,y-z-y.x.w/v/u/t0s0r0q0p1o1n1n1n1n1n1n!K 6,39*..}dop䄒@ .2 )M[+|,|,|-{-z-y.w.w/v/u0t0s0r0q0p1o1n1n1n1n1n!K 6,39*..}w -3 'HY)~*+~+}-}-|-z-z-y.w.w/v/u/t/s0r0q0p1o1n1n1n1n!K 6,39*..}p{}n +3%CV())**'s'p,|-{-z-z-x.w.v/u/u0t0r0r0q1p1o1n1n1n!K 6,39*..}o{}DKL$& e *4$?T&))))))| 3 M,|,{-z-y.x.w.v/u/u0t0r0r0p1p1o1n1n!K 6,39*..}q}t=CD \)4#=Q%'(())))1V #>'n-{-z-y.x.w.v/u/t/s0r0r0p1p1o1n!K 6,39*..}q|z|.35 QR '4#;N#&&''(())I 'n-|-{-z-y.x.w/v/u/t0s0r0q0p1p1n!K 6,39*..}q|zlxzjJ %4"9Jw %&&&&''((`!b+~,},|-{-z-y.x.w/v/u/t0s0r0q0p1o!K 6,39*..}q|z|k@# 4"7Gp#$$%&&&'''"s O*++~,|-|-{-z-y.w.w/v/u/t/s0r0q0p!K 6,39*..}q|z|k8!!4#8Ci~"###$$%&&&'%'9c)**++},|-|-z-z-y.w.v/v/t/t/s0r0q!L 6,39*..}q|z|l/!4$8 @b{""#"###$$&&&& *F $>())**+~,},|,{-z-y-x.w.v/u/t/t/r0r L 6,39*..}q|z|l"3%8 <[x !!""""###$$&&Co %z))))**+~,},|,{-z-y.x.w.v/u/t/t/r M 6,39*..}q|z|m"3&9 9Tu !!""####$$%] !p()))))**+~,},|,{-z-y.x.w.v/u/t/sM 6,39*..}q|z|m[&'9 6Or !!""""##$s ^'(()))))**+~,},|,{-z-y.x.w/v/u/tN 6,39*..}q|z|nw%6 Ii !!!""""# Gv&''(())))***+~,|,|,{-y-y.x.v/v/uN 6,39*..}q|z|nw&6Vz !!""""!#8 0N&&'''(())))**++~,|,|,{-y-y.w.v/vO 6,39*..}q|z|ow&6Vz !!"""<^,$&&&'''(())))**++},|,|,z-y-y.w.vO 6,39*..}q|z|ow&7W{ !!"W  ~$&&&&''((())))**+~,},|,{-z-y-x.wP 7,39*..}q|z|pw&7W{ !!m$$$&&&&''(()))))**+~,},|,{-z-y.xP 7,39*..}q|z|qw'7X{ X##$$%&&&&''(()))))**+~,},|,{-z-yQ 7,39*..}q|z|qx'7X{ X 7W ##$$%&&&&''(())))***+~,},|,{-zQ 7,39*..}q|z|rx'7 Y| /H a##$$%&&&&''(())))**++~,|,|,{R 7,39*..}q|z|rx(7 Y|%7 ,F#$$%&&&'''(())))**++~,|,|S 7,49*..}q|z|sx(8 Z| Z  T#$$%&&&'''(())))**+~+},|S 7,49*..}q|z|sx(8 [|  .F"7x$$&&&&''((())))**+~,}S 7,49*..}q|z|tx)8 [} eIt#$&&&&''(()))))**+~T 7,49*..}q|z|tx)8 \}  9W(n%&&&&''(()))))**U 7,49*..}q|z|ux)8 \} !n o%&&&&''(())))**U 7,49*..}q|z|ux*8 ]} !! Di!$%&&&&''(())))*V 7,49*..}q|z|vx*8 ]} !! #7#$$%&&&'''(())))V 7,49*..}q|z|vx*8 ^} }Lw##$$%&&&'''(()))V 7,49*..}q|z|wx+8 _~|  ,E###$$&&&&''(()))W 7,49*..}q|z|xx+9 `~{  3O!""##$$$&&&&''(())X 7,49*..}q|z|xx+9 `~y 8U!""""##$$%&&&&''(()X 8,49*..}q|z|yx+9 `w =\ !!""""##$$%&&&&''((Y 8,4:*..}q|z|yx,9 at Bb !!"""""##$$%&&&&''(Y 8,4:*..}q|z|zy,9 br Fi !!"""""##$$%&&&'''Z 8,4:*..}q|z|zy,9 bpLp !!"""""##$$%&&&''[ !8,4:*..}q|z|{y-: clRw !!""""###$$&&&&'[ !8,4:*..}q|z|{y-: diW} !!""""##$$$&&&&\ !8,4:*..}q|z||y.: df] !!""""##$$%&&&\ !8,4:*..}q|z||y.: e \y !!!""""##$$%&&] !8,5:*..}q|z|}y.: fj '9 Ca_z !!"""""##$$%&] "8,5:*..}q|z|~y/: f!-,AGif !!"""""##$$%^ "8,5:*..}q|z|~y/: g ;X !!"""""##$$_ "8,5:*..}q|z|y/; g b CZ$1 } !!""""###$_ #8,5:*..}q|z|y0; hx Y{ ;R( "2 !!""""###P#8,5:*./}q|z|y0; in Qr 4I!e !!""""n 6W#8'838:=CD}q|z|y0; i !!!"v ;^$9 %9 /928::?@}q|z|y0; i !~Ae%9 %9.918:49:RZ[q}juwgrtq|z|y0; iHn&: &9.907:49:IPQ_ikfprlwylwyq|z|z0; iOv(<&9-9/7:49:@FGU^`almny{mxzq|z|z0; iW*>':-:-6:49:8=>KSU]fhp{}ny{q|z|z0; i^,?(:,:,6:49:267ELMYcdp|~p|~q|z|z0; if0C(:,:)5:49:/34CJKXabq|r~q|z|z0; in3H):,:'5:49:-22FMNXabp|~skvxq|z|z0; iw7M*;,:%4:49:,01IQRXbcq}uoz|q|z|z0; iDFT]_nz|}lxzq|z||0; i Qi-<.;3;18:'*+49:LTVmy{xvz||0; i Xr.<.<2;/79&**)-.EMNkwylwy{|}0; i a{0>/<3;-79%)) $%>EFjuwkwy|}0; i j3@0<3;+69$((;BCjuwtz|~0; j r6C1=3<)58#''=CDitvnz|nz|0; j y8F1=3<&47#&'BIJlwyitv0< j ?`jlkwylwy}oz|p|~}itv|sQY^+05   ]2 0<1=)0"#/45Xabny|kvxq}sblnzakmthsujuwr~r~Xbf17<   Y/ p%()QY[kvxyuyp|~{grt|[dfwyYbdzxYbdyny{itx^im9?D   V,! ]giOWY}lxzx}fqseprhsuwW`bo{}juwZcevalm^gir~_il]gl?FK#  }S(O %),FNQblno{}eoqXachsuR[\fprZce\fggrtR[]kvxtZcfV_cFMR $)  zO%* !$'CJKLTVYbcS[]R[\nz|ZcfMUYGOT%*.  wL!c&*-BIMEMQ,16  sIA pE;mB? ????7??opendict-0.6.8/win32/setup.manifest.py0000664000076400007640000000321713204646653017561 0ustar nerijusnerijus# Copy compile.bat and setup.py to root directory and run compile.bat from distutils.core import setup import py2exe import sys import glob # The manifest will be inserted as resource into opendict.exe. This # gives the controls the Windows XP appearance (if run on XP ;-) # # Another option would be to store if in a file named # opendict.exe.manifest, and probably copy it with the data_files # option. # manifest_template = ''' %(prog)s Program ''' RT_MANIFEST = 24 ################################################################ # arguments for the setup() call opendict = dict( script = "opendict.py", other_resources = [(RT_MANIFEST, 1, manifest_template % dict(prog="OpenDict"))], ) options = {"py2exe": {"compressed": 1, "optimize": 2}} setup( name="OpenDict", version="0.6.8", options = options, zipfile = None, package_dir = {"": "lib"}, windows = [opendict], data_files=[("pixmaps", glob.glob("pixmaps/\\*.png"))], ) opendict-0.6.8/win32/setup.py0000664000076400007640000000071313204646653015752 0ustar nerijusnerijus# Copy compile.bat and setup.py to root directory and run compile.bat from distutils.core import setup import py2exe import sys import glob setup( name="opendict", version="0.6.8", zipfile=None, package_dir = {"": "lib"}, windows = [{ "script":"opendict.py", "icon_resources": [(1, "win32/opendict.ico")] }], data_files=[("pixmaps", glob.glob("pixmaps/\\*.png"))], )